From 7ce4ced7d627fe4bbc4b54c0e212e08d4ea065e1 Mon Sep 17 00:00:00 2001
From: Firman Ramdhani <33869609+firmanramdhani@users.noreply.github.com>
Date: Wed, 15 Jul 2026 15:28:58 +0700
Subject: [PATCH] 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.
---
apps/web/index.html | 2 +-
.../presentation/components/data-table.tsx | 6 +-
.../presentation/locales/en/full-page.json | 3 +
.../presentation/locales/id/full-page.json | 5 +-
.../pages/full-page.page.detail copy.tsx | 131 +++++
.../pages/full-page.page.detail.tsx | 134 +----
.../pages/full-page.page.index.tsx | 3 +-
packages/core-api/src/data-services/types.ts | 1 +
packages/core-i18n/src/locales/en/common.json | 2 +
packages/core-i18n/src/locales/id/common.json | 2 +
.../components/actions-tools/page-actions.tsx | 19 +-
.../ui/src/components/actions-tools/types.ts | 5 +-
.../components/system-pages/coming-soon.tsx | 9 +-
.../src/components/system-pages/forbidden.tsx | 10 +-
.../components/system-pages/maintenance.tsx | 9 +-
.../src/components/system-pages/not-found.tsx | 10 +-
.../components/module-page-header.tsx | 51 +-
.../constant/default-privilege.ts | 2 -
.../enterprise-module/entities/entity.ts | 33 +-
.../hooks/use-detail-page.context.ts | 2 +
.../foundations/enterprise-module/index.ts | 1 +
.../providers/detail-page.provider.tsx | 483 +++++++++++++++++-
.../providers/index-page.provider.tsx | 3 +-
.../providers/module.provider.tsx | 23 +-
24 files changed, 741 insertions(+), 208 deletions(-)
create mode 100644 apps/web/src/apps/modules/example/full-page/presentation/pages/full-page.page.detail copy.tsx
diff --git a/apps/web/index.html b/apps/web/index.html
index 9d591cc..eed3f7d 100644
--- a/apps/web/index.html
+++ b/apps/web/index.html
@@ -5,7 +5,7 @@
-
Vite + React
+ Applications
diff --git a/apps/web/src/apps/modules/example/full-page/presentation/components/data-table.tsx b/apps/web/src/apps/modules/example/full-page/presentation/components/data-table.tsx
index 4076718..4f88c99 100644
--- a/apps/web/src/apps/modules/example/full-page/presentation/components/data-table.tsx
+++ b/apps/web/src/apps/modules/example/full-page/presentation/components/data-table.tsx
@@ -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);
diff --git a/apps/web/src/apps/modules/example/full-page/presentation/locales/en/full-page.json b/apps/web/src/apps/modules/example/full-page/presentation/locales/en/full-page.json
index 159078d..b61f453 100644
--- a/apps/web/src/apps/modules/example/full-page/presentation/locales/en/full-page.json
+++ b/apps/web/src/apps/modules/example/full-page/presentation/locales/en/full-page.json
@@ -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 layout1> for detailed forms.",
"fields": {
"status": "Status",
diff --git a/apps/web/src/apps/modules/example/full-page/presentation/locales/id/full-page.json b/apps/web/src/apps/modules/example/full-page/presentation/locales/id/full-page.json
index 7912506..e9345d3 100644
--- a/apps/web/src/apps/modules/example/full-page/presentation/locales/id/full-page.json
+++ b/apps/web/src/apps/modules/example/full-page/presentation/locales/id/full-page.json
@@ -1,6 +1,9 @@
{
"title": "Halaman Penuh",
- "description": "Contoh modul <1>tata letak halaman penuh1> 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 penuh1> untuk formulir detail.",
"fields": {
"status": "Status",
"name": "Nama",
diff --git a/apps/web/src/apps/modules/example/full-page/presentation/pages/full-page.page.detail copy.tsx b/apps/web/src/apps/modules/example/full-page/presentation/pages/full-page.page.detail copy.tsx
new file mode 100644
index 0000000..c29969d
--- /dev/null
+++ b/apps/web/src/apps/modules/example/full-page/presentation/pages/full-page.page.detail copy.tsx
@@ -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 (
+
+ {/* --- INLINED PAGE HEADER --- */}
+
+ }
+ >
+
+ Acme Corp
+
+
+ Infrastructure
+
+
+ Database Clusters
+
+
+ prod-db-01
+
+
+
+
+
+
+
+
+ prod-db-01
+
+ }
+ style={{ textTransform: 'capitalize' }}
+ >
+ Running
+
+
+
+
+ PostgreSQL v15.4 · us-east-1 · Created Oct 12, 2023
+
+
+
+
+
+
+
+
+ }
+ >
+ Edit
+
+ }
+ style={{ boxShadow: '0 4px 14px 0 rgba(76, 110, 245, 0.39)' }}
+ >
+ Restart
+
+
+
+
+
+
+ {/* --- END INLINED PAGE HEADER --- */}
+
+
+
+ General Information
+
+
+ View the complete details and configuration for this entity.
+
+
+
+
+
+
+
+ {t('fields.code')}
+
+ WID-001
+
+
+
+ {t('fields.name')}
+
+ Dashboard Widget
+
+
+
+ {t('fields.status')}
+
+
+ ACTIVE
+
+
+
+
+ {t('fields.description')}
+
+ Main dashboard widget
+
+
+
+
+ );
+}
diff --git a/apps/web/src/apps/modules/example/full-page/presentation/pages/full-page.page.detail.tsx b/apps/web/src/apps/modules/example/full-page/presentation/pages/full-page.page.detail.tsx
index c29969d..f1b1bc9 100644
--- a/apps/web/src/apps/modules/example/full-page/presentation/pages/full-page.page.detail.tsx
+++ b/apps/web/src/apps/modules/example/full-page/presentation/pages/full-page.page.detail.tsx
@@ -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 (
-
- {/* --- INLINED PAGE HEADER --- */}
-
- }
- >
-
- Acme Corp
-
-
- Infrastructure
-
-
- Database Clusters
-
-
- prod-db-01
-
-
+
-
-
-
-
- prod-db-01
-
- }
- style={{ textTransform: 'capitalize' }}
- >
- Running
-
-
-
-
- PostgreSQL v15.4 · us-east-1 · Created Oct 12, 2023
-
-
-
-
-
-
-
-
- }
- >
- Edit
-
- }
- style={{ boxShadow: '0 4px 14px 0 rgba(76, 110, 245, 0.39)' }}
- >
- Restart
-
-
-
-
-
-
- {/* --- END INLINED PAGE HEADER --- */}
-
-
-
- General Information
-
-
- View the complete details and configuration for this entity.
-
-
-
-
-
-
-
- {t('fields.code')}
-
- WID-001
-
-
-
- {t('fields.name')}
-
- Dashboard Widget
-
-
-
- {t('fields.status')}
-
-
- ACTIVE
-
-
-
-
- {t('fields.description')}
-
- Main dashboard widget
-
-
-
-
+ breadcrumbs: [
+ { label: t('nav:example-module'), type: 'text' },
+ { label: t('nav:example-full-page'), type: 'link', href: `${FullPageModuleConfig.webUrl}/index` },
+ ],
+ }}
+ >
);
}
diff --git a/apps/web/src/apps/modules/example/full-page/presentation/pages/full-page.page.index.tsx b/apps/web/src/apps/modules/example/full-page/presentation/pages/full-page.page.index.tsx
index 43fca04..a757fa8 100644
--- a/apps/web/src/apps/modules/example/full-page/presentation/pages/full-page.page.index.tsx
+++ b/apps/web/src/apps/modules/example/full-page/presentation/pages/full-page.page.index.tsx
@@ -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' },
],
}}
>
diff --git a/packages/core-api/src/data-services/types.ts b/packages/core-api/src/data-services/types.ts
index 9febaea..9742701 100644
--- a/packages/core-api/src/data-services/types.ts
+++ b/packages/core-api/src/data-services/types.ts
@@ -10,6 +10,7 @@ import type { IDataTransformer } from './base-data.transformer';
*/
export interface BaseEntity {
id?: string;
+ [key: string]: any;
}
// ─── API URL Map ────────────────────────────────────────────────
diff --git a/packages/core-i18n/src/locales/en/common.json b/packages/core-i18n/src/locales/en/common.json
index 366eea6..c61e03c 100644
--- a/packages/core-i18n/src/locales/en/common.json
+++ b/packages/core-i18n/src/locales/en/common.json
@@ -52,6 +52,8 @@
"activate": "Activate",
"deactivate": "Deactivate",
"duplicate": "Duplicate",
+ "rollback": "Rollback",
+ "hold": "Hold",
"back": "Back",
"reload": "Reload"
},
diff --git a/packages/core-i18n/src/locales/id/common.json b/packages/core-i18n/src/locales/id/common.json
index 6b8fe60..b8642e4 100644
--- a/packages/core-i18n/src/locales/id/common.json
+++ b/packages/core-i18n/src/locales/id/common.json
@@ -52,6 +52,8 @@
"activate": "Aktifkan",
"deactivate": "Nonaktifkan",
"duplicate": "Duplikat",
+ "rollback": "Rollback",
+ "hold": "Hold",
"back": "Kembali",
"reload": "Muat Ulang"
},
diff --git a/packages/ui/src/components/actions-tools/page-actions.tsx b/packages/ui/src/components/actions-tools/page-actions.tsx
index 0fa2d34..f573388 100644
--- a/packages/ui/src/components/actions-tools/page-actions.tsx
+++ b/packages/ui/src/components/actions-tools/page-actions.tsx
@@ -60,13 +60,8 @@ export const PageActions = memo(function PageActions({ actions = [], customButto