feat: enhance enterprise module with new actions and UI improvements
- Added support for rollback and hold actions in the enterprise module. - Updated tooltip labels for action buttons to improve user experience. - Refactored PageActions component to use tooltipLabel instead of shortcutLabel. - Introduced height prop for system pages (Coming Soon, Forbidden, Maintenance, Not Found) for better layout control. - Improved ModulePageHeader to accept custom button properties and enhanced title handling. - Cleaned up default privileges by removing unused actions (ALLOW_DUPLICATE, ALLOW_SAVE). - Implemented detail page provider with comprehensive action handling for CRUD operations. - Created a new full-page detail component for better data presentation.
This commit is contained in:
@@ -7,7 +7,6 @@ import {
|
||||
Text,
|
||||
Group,
|
||||
Button,
|
||||
Divider,
|
||||
TextInput,
|
||||
Pagination,
|
||||
Select,
|
||||
@@ -16,7 +15,7 @@ import {
|
||||
import { PageActions } from '@repo/ui/components';
|
||||
import { useEnterpriseModuleTranslationContext, useEnterpriseModuleNavigationContext } from '@repo/ui/foundations';
|
||||
import { FullPageEntity } from '../../domain/entities';
|
||||
import { Edit2, Eye, Copy, Trash2, Search, Filter, Plus, CheckCircle2, Ban } from 'lucide-react';
|
||||
import { Edit2, Eye, Copy, Trash2, Search, Filter, CheckCircle2, Ban } from 'lucide-react';
|
||||
|
||||
// TODO: Replace this mock data with real API data loaded from DataService via useEnterpriseModuleDataServiceContext
|
||||
const MOCK_DATA: FullPageEntity[] = Array.from({ length: 50 }).map((_, i) => ({
|
||||
@@ -29,8 +28,7 @@ const MOCK_DATA: FullPageEntity[] = Array.from({ length: 50 }).map((_, i) => ({
|
||||
|
||||
export function DataTable() {
|
||||
const { t } = useEnterpriseModuleTranslationContext();
|
||||
const { navigateToDetail, navigateToEdit, navigateToDuplicate, navigateToCreate } =
|
||||
useEnterpriseModuleNavigationContext();
|
||||
const { navigateToDetail, navigateToEdit, navigateToDuplicate } = useEnterpriseModuleNavigationContext();
|
||||
|
||||
const [page, setPage] = useState(1);
|
||||
const [pageSize, setPageSize] = useState(10);
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
{
|
||||
"title": "Full Page",
|
||||
"detail_page_title": "Detail Full Page",
|
||||
"create_page_title": "New Full Page",
|
||||
"duplicate_page_title": "Duplicate Full Page",
|
||||
"description": "An example module of a <1>full page layout</1> for detailed forms.",
|
||||
"fields": {
|
||||
"status": "Status",
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
{
|
||||
"title": "Halaman Penuh",
|
||||
"description": "Contoh modul <1>tata letak halaman penuh</1> untuk formulir detail.",
|
||||
"detail_page_title": "Detail Halaman Penuh",
|
||||
"create_page_title": "Buat Halaman Penuh Baru",
|
||||
"duplicate_page_title": "Duplikat Halaman Penuh",
|
||||
"description": "Contoh penerapan <1>tata letak halaman penuh</1> untuk formulir detail.",
|
||||
"fields": {
|
||||
"status": "Status",
|
||||
"name": "Nama",
|
||||
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
import { Paper, SimpleGrid, Box, Text, Group, Badge, Divider, Breadcrumbs, Anchor, Flex, Title, ActionIcon, Button } from '@repo/ui/components';
|
||||
import { useEnterpriseModuleTranslationContext } from '@repo/ui/foundations';
|
||||
import { ChevronRight, CheckCircle2, Trash2, Edit2, Play } from 'lucide-react';
|
||||
|
||||
export default function FullPagePageDetail() {
|
||||
const { t } = useEnterpriseModuleTranslationContext();
|
||||
|
||||
return (
|
||||
<Box pb="xl">
|
||||
{/* --- INLINED PAGE HEADER --- */}
|
||||
<Box mb="xl" mt="xs">
|
||||
<Breadcrumbs
|
||||
mb="md"
|
||||
separator={<ChevronRight size={12} strokeWidth={3} style={{ color: 'var(--mantine-color-gray-5)' }} />}
|
||||
>
|
||||
<Anchor href="#" c="dimmed" size="xs" fw={500} style={{ transition: 'color 0.2s ease', letterSpacing: '0.2px' }}>
|
||||
Acme Corp
|
||||
</Anchor>
|
||||
<Anchor href="#" c="dimmed" size="xs" fw={500} style={{ transition: 'color 0.2s ease', letterSpacing: '0.2px' }}>
|
||||
Infrastructure
|
||||
</Anchor>
|
||||
<Anchor href="#" c="dimmed" size="xs" fw={500} style={{ transition: 'color 0.2s ease', letterSpacing: '0.2px' }}>
|
||||
Database Clusters
|
||||
</Anchor>
|
||||
<Text size="xs" fw={600} style={{ color: 'light-dark(var(--mantine-color-gray-8), var(--mantine-color-dark-0))', letterSpacing: '0.2px' }}>
|
||||
prod-db-01
|
||||
</Text>
|
||||
</Breadcrumbs>
|
||||
|
||||
<Group justify="space-between" align="center" wrap="nowrap">
|
||||
<Flex gap="md" align="center">
|
||||
<Box>
|
||||
<Group gap="xs" align="center" mb={4}>
|
||||
<Title
|
||||
order={2}
|
||||
fw={600}
|
||||
style={{
|
||||
color: 'light-dark(var(--mantine-color-gray-9), var(--mantine-color-dark-0))',
|
||||
letterSpacing: '-0.3px',
|
||||
}}
|
||||
>
|
||||
prod-db-01
|
||||
</Title>
|
||||
<Badge
|
||||
variant="light"
|
||||
color="teal"
|
||||
size="sm"
|
||||
radius="sm"
|
||||
fw={600}
|
||||
leftSection={<CheckCircle2 size={10} strokeWidth={3} />}
|
||||
style={{ textTransform: 'capitalize' }}
|
||||
>
|
||||
Running
|
||||
</Badge>
|
||||
</Group>
|
||||
|
||||
<Text size="sm" c="dimmed" fw={400}>
|
||||
PostgreSQL v15.4 · <Text span fw={500} c="var(--mantine-color-text)">us-east-1</Text> · Created Oct 12, 2023
|
||||
</Text>
|
||||
</Box>
|
||||
</Flex>
|
||||
|
||||
<Group gap="sm">
|
||||
<ActionIcon variant="light" color="red" size="lg" radius="md" aria-label="Delete">
|
||||
<Trash2 size={18} strokeWidth={2} />
|
||||
</ActionIcon>
|
||||
<Button
|
||||
variant="default"
|
||||
radius="md"
|
||||
leftSection={<Edit2 size={16} strokeWidth={2} style={{ color: 'var(--mantine-color-dimmed)' }} />}
|
||||
>
|
||||
Edit
|
||||
</Button>
|
||||
<Button
|
||||
variant="filled"
|
||||
color="indigo"
|
||||
radius="md"
|
||||
leftSection={<Play size={16} strokeWidth={2.5} />}
|
||||
style={{ boxShadow: '0 4px 14px 0 rgba(76, 110, 245, 0.39)' }}
|
||||
>
|
||||
Restart
|
||||
</Button>
|
||||
</Group>
|
||||
</Group>
|
||||
|
||||
<Divider mt={28} mb={0} color="light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-6))" />
|
||||
</Box>
|
||||
{/* --- END INLINED PAGE HEADER --- */}
|
||||
|
||||
<Paper withBorder shadow="sm" radius="md" p="xl">
|
||||
<Text size="lg" fw={600} mb="xs" style={{ color: 'light-dark(var(--mantine-color-gray-9), var(--mantine-color-dark-0))', letterSpacing: '-0.3px' }}>
|
||||
General Information
|
||||
</Text>
|
||||
<Text size="sm" c="dimmed" mb="xl">
|
||||
View the complete details and configuration for this entity.
|
||||
</Text>
|
||||
|
||||
<Divider mb="xl" color="light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-6))" />
|
||||
|
||||
<SimpleGrid cols={{ base: 1, sm: 2 }} spacing="xl" verticalSpacing="xl">
|
||||
<Box>
|
||||
<Text size="xs" tt="uppercase" fw={700} c="dimmed" mb={4} style={{ letterSpacing: '0.5px' }}>
|
||||
{t('fields.code')}
|
||||
</Text>
|
||||
<Text size="sm" fw={500}>WID-001</Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text size="xs" tt="uppercase" fw={700} c="dimmed" mb={4} style={{ letterSpacing: '0.5px' }}>
|
||||
{t('fields.name')}
|
||||
</Text>
|
||||
<Text size="sm" fw={500}>Dashboard Widget</Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text size="xs" tt="uppercase" fw={700} c="dimmed" mb={4} style={{ letterSpacing: '0.5px' }}>
|
||||
{t('fields.status')}
|
||||
</Text>
|
||||
<Badge variant="light" color="teal" size="sm" radius="sm" fw={600}>
|
||||
ACTIVE
|
||||
</Badge>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text size="xs" tt="uppercase" fw={700} c="dimmed" mb={4} style={{ letterSpacing: '0.5px' }}>
|
||||
{t('fields.description')}
|
||||
</Text>
|
||||
<Text size="sm" fw={500}>Main dashboard widget</Text>
|
||||
</Box>
|
||||
</SimpleGrid>
|
||||
</Paper>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
+11
-123
@@ -1,131 +1,19 @@
|
||||
import { Paper, SimpleGrid, Box, Text, Group, Badge, Divider, Breadcrumbs, Anchor, Flex, Title, ActionIcon, Button } from '@repo/ui/components';
|
||||
import { useEnterpriseModuleTranslationContext } from '@repo/ui/foundations';
|
||||
import { ChevronRight, CheckCircle2, Trash2, Edit2, Play } from 'lucide-react';
|
||||
import { EnterpriseDetailPageProvider, useEnterpriseModuleTranslationContext } from '@repo/ui/foundations';
|
||||
import { FullPageModuleConfig } from '../../domain/constants';
|
||||
|
||||
export default function FullPagePageDetail() {
|
||||
const { t } = useEnterpriseModuleTranslationContext();
|
||||
|
||||
return (
|
||||
<Box pb="xl">
|
||||
{/* --- INLINED PAGE HEADER --- */}
|
||||
<Box mb="xl" mt="xs">
|
||||
<Breadcrumbs
|
||||
mb="md"
|
||||
separator={<ChevronRight size={12} strokeWidth={3} style={{ color: 'var(--mantine-color-gray-5)' }} />}
|
||||
>
|
||||
<Anchor href="#" c="dimmed" size="xs" fw={500} style={{ transition: 'color 0.2s ease', letterSpacing: '0.2px' }}>
|
||||
Acme Corp
|
||||
</Anchor>
|
||||
<Anchor href="#" c="dimmed" size="xs" fw={500} style={{ transition: 'color 0.2s ease', letterSpacing: '0.2px' }}>
|
||||
Infrastructure
|
||||
</Anchor>
|
||||
<Anchor href="#" c="dimmed" size="xs" fw={500} style={{ transition: 'color 0.2s ease', letterSpacing: '0.2px' }}>
|
||||
Database Clusters
|
||||
</Anchor>
|
||||
<Text size="xs" fw={600} style={{ color: 'light-dark(var(--mantine-color-gray-8), var(--mantine-color-dark-0))', letterSpacing: '0.2px' }}>
|
||||
prod-db-01
|
||||
</Text>
|
||||
</Breadcrumbs>
|
||||
<EnterpriseDetailPageProvider
|
||||
pageHeaderProps={{
|
||||
title: t('detail_page_title'),
|
||||
|
||||
<Group justify="space-between" align="center" wrap="nowrap">
|
||||
<Flex gap="md" align="center">
|
||||
<Box>
|
||||
<Group gap="xs" align="center" mb={4}>
|
||||
<Title
|
||||
order={2}
|
||||
fw={600}
|
||||
style={{
|
||||
color: 'light-dark(var(--mantine-color-gray-9), var(--mantine-color-dark-0))',
|
||||
letterSpacing: '-0.3px',
|
||||
}}
|
||||
>
|
||||
prod-db-01
|
||||
</Title>
|
||||
<Badge
|
||||
variant="light"
|
||||
color="teal"
|
||||
size="sm"
|
||||
radius="sm"
|
||||
fw={600}
|
||||
leftSection={<CheckCircle2 size={10} strokeWidth={3} />}
|
||||
style={{ textTransform: 'capitalize' }}
|
||||
>
|
||||
Running
|
||||
</Badge>
|
||||
</Group>
|
||||
|
||||
<Text size="sm" c="dimmed" fw={400}>
|
||||
PostgreSQL v15.4 · <Text span fw={500} c="var(--mantine-color-text)">us-east-1</Text> · Created Oct 12, 2023
|
||||
</Text>
|
||||
</Box>
|
||||
</Flex>
|
||||
|
||||
<Group gap="sm">
|
||||
<ActionIcon variant="light" color="red" size="lg" radius="md" aria-label="Delete">
|
||||
<Trash2 size={18} strokeWidth={2} />
|
||||
</ActionIcon>
|
||||
<Button
|
||||
variant="default"
|
||||
radius="md"
|
||||
leftSection={<Edit2 size={16} strokeWidth={2} style={{ color: 'var(--mantine-color-dimmed)' }} />}
|
||||
>
|
||||
Edit
|
||||
</Button>
|
||||
<Button
|
||||
variant="filled"
|
||||
color="indigo"
|
||||
radius="md"
|
||||
leftSection={<Play size={16} strokeWidth={2.5} />}
|
||||
style={{ boxShadow: '0 4px 14px 0 rgba(76, 110, 245, 0.39)' }}
|
||||
>
|
||||
Restart
|
||||
</Button>
|
||||
</Group>
|
||||
</Group>
|
||||
|
||||
<Divider mt={28} mb={0} color="light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-6))" />
|
||||
</Box>
|
||||
{/* --- END INLINED PAGE HEADER --- */}
|
||||
|
||||
<Paper withBorder shadow="sm" radius="md" p="xl">
|
||||
<Text size="lg" fw={600} mb="xs" style={{ color: 'light-dark(var(--mantine-color-gray-9), var(--mantine-color-dark-0))', letterSpacing: '-0.3px' }}>
|
||||
General Information
|
||||
</Text>
|
||||
<Text size="sm" c="dimmed" mb="xl">
|
||||
View the complete details and configuration for this entity.
|
||||
</Text>
|
||||
|
||||
<Divider mb="xl" color="light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-6))" />
|
||||
|
||||
<SimpleGrid cols={{ base: 1, sm: 2 }} spacing="xl" verticalSpacing="xl">
|
||||
<Box>
|
||||
<Text size="xs" tt="uppercase" fw={700} c="dimmed" mb={4} style={{ letterSpacing: '0.5px' }}>
|
||||
{t('fields.code')}
|
||||
</Text>
|
||||
<Text size="sm" fw={500}>WID-001</Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text size="xs" tt="uppercase" fw={700} c="dimmed" mb={4} style={{ letterSpacing: '0.5px' }}>
|
||||
{t('fields.name')}
|
||||
</Text>
|
||||
<Text size="sm" fw={500}>Dashboard Widget</Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text size="xs" tt="uppercase" fw={700} c="dimmed" mb={4} style={{ letterSpacing: '0.5px' }}>
|
||||
{t('fields.status')}
|
||||
</Text>
|
||||
<Badge variant="light" color="teal" size="sm" radius="sm" fw={600}>
|
||||
ACTIVE
|
||||
</Badge>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text size="xs" tt="uppercase" fw={700} c="dimmed" mb={4} style={{ letterSpacing: '0.5px' }}>
|
||||
{t('fields.description')}
|
||||
</Text>
|
||||
<Text size="sm" fw={500}>Main dashboard widget</Text>
|
||||
</Box>
|
||||
</SimpleGrid>
|
||||
</Paper>
|
||||
</Box>
|
||||
breadcrumbs: [
|
||||
{ label: t('nav:example-module'), type: 'text' },
|
||||
{ label: t('nav:example-full-page'), type: 'link', href: `${FullPageModuleConfig.webUrl}/index` },
|
||||
],
|
||||
}}
|
||||
></EnterpriseDetailPageProvider>
|
||||
);
|
||||
}
|
||||
|
||||
+1
-2
@@ -2,7 +2,6 @@ import { EnterpriseIndexPageProvider, useEnterpriseModuleTranslationContext } fr
|
||||
import { Trans } from '@repo/core-i18n';
|
||||
import { Badge, Text } from '@repo/ui/components';
|
||||
import { Activity, LayoutDashboard } from 'lucide-react';
|
||||
import { FullPageModuleConfig } from '../../domain/constants';
|
||||
import { DataTable } from '../components/data-table';
|
||||
|
||||
export default function FullPagePageIndex() {
|
||||
@@ -37,7 +36,7 @@ export default function FullPagePageIndex() {
|
||||
icon: LayoutDashboard,
|
||||
breadcrumbs: [
|
||||
{ label: t('nav:example-module'), type: 'text' },
|
||||
{ label: t('nav:example-full-page'), type: 'link', href: `${FullPageModuleConfig.webUrl}/index` },
|
||||
{ label: t('nav:example-full-page'), type: 'text' },
|
||||
],
|
||||
}}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user