From 1812f7c585d37c297396a8395290d3339b8bdcff Mon Sep 17 00:00:00 2001 From: Firman Ramdhani <33869609+firmanramdhani@users.noreply.github.com> Date: Thu, 23 Jul 2026 18:29:40 +0700 Subject: [PATCH] refactor: update icons and improve action visibility in row and bulk action menus --- .../pages/full-page.page.detail copy.tsx | 131 ------------------ .../components/actions-tools/row-actions.tsx | 16 +-- .../data-table/components/bulk-actions.tsx | 42 +++--- .../data-table/components/row-actions.tsx | 22 +-- .../components/data-table/index.tsx | 4 +- .../providers/detail-page.provider.tsx | 10 +- 6 files changed, 51 insertions(+), 174 deletions(-) delete mode 100644 apps/web/src/apps/modules/example/full-page/presentation/pages/full-page.page.detail copy.tsx 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 deleted file mode 100644 index c29969d..0000000 --- a/apps/web/src/apps/modules/example/full-page/presentation/pages/full-page.page.detail copy.tsx +++ /dev/null @@ -1,131 +0,0 @@ -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 - - - - - - - - - - - - - - - - {/* --- 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/packages/ui/src/components/actions-tools/row-actions.tsx b/packages/ui/src/components/actions-tools/row-actions.tsx index 62a3c3f..1978dbe 100644 --- a/packages/ui/src/components/actions-tools/row-actions.tsx +++ b/packages/ui/src/components/actions-tools/row-actions.tsx @@ -1,5 +1,5 @@ import { Fragment, memo } from 'react'; -import { Group, ActionIcon, Tooltip, Menu, Divider, Box, Button } from '@mantine/core'; +import { Group, ActionIcon, Tooltip, Menu, Divider, Box, Button, MantineSpacing } from '@mantine/core'; import { RowActionProps } from './types'; import { getIntentColor } from './utils'; import { MoreVertical } from 'lucide-react'; @@ -9,6 +9,8 @@ export interface RowActionsProps { actions: RowActionProps[]; showLabels?: boolean; responsiveView?: boolean; + gapActionDesktop?: MantineSpacing; + gapActionMobile?: MantineSpacing; } /** @@ -17,11 +19,9 @@ export interface RowActionsProps { * * @performance Wrapped in React.memo to guarantee zero overhead inside large lists/grids. */ -export const RowActions = memo(function RowActions({ - actions = [], - showLabels = false, - responsiveView = true, -}: RowActionsProps) { +export const RowActions = memo(function RowActions(props: RowActionsProps) { + const { actions = [], showLabels = false, responsiveView = true, gapActionDesktop = 0, gapActionMobile = 0 } = props; + /** * Helper function to render a standalone item. */ @@ -114,14 +114,14 @@ export const RowActions = memo(function RowActions({ return ( {/* --- DESKTOP VIEW (hidden on mobile devices) --- */} - + {renderFlatActions()} {/* --- MOBILE VIEW (hidden on desktop devices) --- */} {responsiveView && ( - + diff --git a/packages/ui/src/foundations/enterprise-module/components/data-table/components/bulk-actions.tsx b/packages/ui/src/foundations/enterprise-module/components/data-table/components/bulk-actions.tsx index 4d61a12..6619d33 100644 --- a/packages/ui/src/foundations/enterprise-module/components/data-table/components/bulk-actions.tsx +++ b/packages/ui/src/foundations/enterprise-module/components/data-table/components/bulk-actions.tsx @@ -4,7 +4,7 @@ import { useEnterpriseModuleTranslationContext, useEnterpriseModuleConfigContext, } from '../../../hooks/use-module.context'; -import { Trash2, CheckCircle, XCircle, PauseCircle, RotateCcw, X, Check } from 'lucide-react'; +import { Trash, Unlock, Lock, PauseCircle, RotateCcw, X, Check } from 'lucide-react'; import { PageActions, PageActionProps } from '../../../../../components'; // --------------------------------------------------------------------------- @@ -29,7 +29,7 @@ export interface BulkActionMenuProps { * privilege checks, and the status of selected rows — mirroring the * row-level action logic in `RowActionMenu`. * - * All actions have `showLabel: false` so they render as icon-only + * All actions have `showLabel: t so they render as icon-only * `ActionIcon` buttons via the `PageActions` component. * * @performance @@ -74,9 +74,9 @@ export function BulkActionMenu({ defaultActions.push({ key: ModuleAction.DEACTIVATE, label: t('common:actions.deactivate'), - icon: , + icon: , variant: 'default', - showLabel: false, + showLabel: true, onClick: handleClick(ModuleAction.DEACTIVATE), }); } @@ -85,9 +85,9 @@ export function BulkActionMenu({ defaultActions.push({ key: ModuleAction.ACTIVATE, label: t('common:actions.activate'), - icon: , + icon: , variant: 'default', - showLabel: false, + showLabel: true, onClick: handleClick(ModuleAction.ACTIVATE), }); } @@ -99,9 +99,9 @@ export function BulkActionMenu({ defaultActions.push({ key: ModuleAction.HOLD, label: t('common:actions.hold'), - icon: , + icon: , variant: 'default', - showLabel: false, + showLabel: true, onClick: handleClick(ModuleAction.HOLD), }); } @@ -110,9 +110,9 @@ export function BulkActionMenu({ defaultActions.push({ key: ModuleAction.ROLLBACK, label: t('common:actions.rollback'), - icon: , + icon: , variant: 'default', - showLabel: false, + showLabel: true, onClick: handleClick(ModuleAction.ROLLBACK), }); } @@ -121,9 +121,9 @@ export function BulkActionMenu({ defaultActions.push({ key: ModuleAction.CANCEL, label: t('common:actions.cancel'), - icon: , + icon: , variant: 'default', - showLabel: false, + showLabel: true, onClick: handleClick(ModuleAction.CANCEL), }); } @@ -132,9 +132,9 @@ export function BulkActionMenu({ defaultActions.push({ key: ModuleAction.CONFIRM, label: t('common:actions.confirm'), - icon: , + icon: , variant: 'default', - showLabel: false, + showLabel: true, onClick: handleClick(ModuleAction.CONFIRM), }); } @@ -145,10 +145,10 @@ export function BulkActionMenu({ defaultActions.push({ key: ModuleAction.DELETE, label: t('common:actions.delete'), - icon: , + icon: , variant: 'outline', intent: 'destructive', - showLabel: false, + showLabel: true, onClick: handleClick(ModuleAction.DELETE), }); } @@ -158,5 +158,13 @@ export function BulkActionMenu({ if (actions.length === 0) return null; - return ; + return ( + { + return { size: 'xs' }; + }} + /> + ); } diff --git a/packages/ui/src/foundations/enterprise-module/components/data-table/components/row-actions.tsx b/packages/ui/src/foundations/enterprise-module/components/data-table/components/row-actions.tsx index 0731048..16d9a13 100644 --- a/packages/ui/src/foundations/enterprise-module/components/data-table/components/row-actions.tsx +++ b/packages/ui/src/foundations/enterprise-module/components/data-table/components/row-actions.tsx @@ -1,5 +1,5 @@ import { useMemo } from 'react'; -import { Eye, Trash2, CheckCircle, XCircle, Edit2, Copy, PauseCircle, RotateCcw, X, Check } from 'lucide-react'; +import { FileSearchCorner, Trash, Unlock, Lock, SquarePen, Copy, PauseCircle, RotateCcw, X, Check } from 'lucide-react'; import { ModuleAction, ModuleActionType } from '../../../entities/entity'; import { useEnterpriseModuleTranslationContext, @@ -47,7 +47,7 @@ export function RowActionMenu({ data, onActionClick, statusKey = 'status', custo key: 'VIEW', label: t('common:actions.detail'), tooltip: t('common:actions.detail'), - icon: , + icon: , onClick: () => onActionClick('VIEW' as any, data), }); @@ -56,7 +56,7 @@ export function RowActionMenu({ data, onActionClick, statusKey = 'status', custo key: ModuleAction.EDIT, label: t('common:actions.edit'), tooltip: t('common:actions.edit'), - icon: , + icon: , onClick: () => onActionClick(ModuleAction.EDIT, data), }); } @@ -66,7 +66,7 @@ export function RowActionMenu({ data, onActionClick, statusKey = 'status', custo key: ModuleAction.DUPLICATE, label: t('common:actions.duplicate'), tooltip: t('common:actions.duplicate'), - icon: , + icon: , onClick: () => onActionClick(ModuleAction.DUPLICATE, data), }); } @@ -77,7 +77,7 @@ export function RowActionMenu({ data, onActionClick, statusKey = 'status', custo key: ModuleAction.DEACTIVATE, label: t('common:actions.deactivate'), tooltip: t('common:actions.deactivate'), - icon: , + icon: , onClick: () => onActionClick(ModuleAction.DEACTIVATE, data), }); } @@ -86,7 +86,7 @@ export function RowActionMenu({ data, onActionClick, statusKey = 'status', custo key: ModuleAction.ACTIVATE, label: t('common:actions.activate'), tooltip: t('common:actions.activate'), - icon: , + icon: , onClick: () => onActionClick(ModuleAction.ACTIVATE, data), }); } @@ -98,7 +98,7 @@ export function RowActionMenu({ data, onActionClick, statusKey = 'status', custo key: ModuleAction.HOLD, label: t('common:actions.hold'), tooltip: t('common:actions.hold'), - icon: , + icon: , onClick: () => onActionClick(ModuleAction.HOLD, data), }); } @@ -107,7 +107,7 @@ export function RowActionMenu({ data, onActionClick, statusKey = 'status', custo key: ModuleAction.ROLLBACK, label: t('common:actions.rollback'), tooltip: t('common:actions.rollback'), - icon: , + icon: , onClick: () => onActionClick(ModuleAction.ROLLBACK, data), }); } @@ -116,7 +116,7 @@ export function RowActionMenu({ data, onActionClick, statusKey = 'status', custo key: ModuleAction.CANCEL, label: t('common:actions.cancel'), tooltip: t('common:actions.cancel'), - icon: , + icon: , onClick: () => onActionClick(ModuleAction.CANCEL, data), }); } @@ -125,7 +125,7 @@ export function RowActionMenu({ data, onActionClick, statusKey = 'status', custo key: ModuleAction.CONFIRM, label: t('common:actions.confirm'), tooltip: t('common:actions.confirm'), - icon: , + icon: , onClick: () => onActionClick(ModuleAction.CONFIRM, data), }); } @@ -136,7 +136,7 @@ export function RowActionMenu({ data, onActionClick, statusKey = 'status', custo key: ModuleAction.DELETE, label: t('common:actions.delete'), tooltip: t('common:actions.delete'), - icon: , + icon: , intent: 'destructive', onClick: () => onActionClick(ModuleAction.DELETE, data), }); diff --git a/packages/ui/src/foundations/enterprise-module/components/data-table/index.tsx b/packages/ui/src/foundations/enterprise-module/components/data-table/index.tsx index a8bc8f0..fb609c0 100644 --- a/packages/ui/src/foundations/enterprise-module/components/data-table/index.tsx +++ b/packages/ui/src/foundations/enterprise-module/components/data-table/index.tsx @@ -824,7 +824,7 @@ export function EnterpriseDataTable(props: EnterpriseDataT { key: 'filter', icon: ( - + ), @@ -881,7 +881,7 @@ export function EnterpriseDataTable(props: EnterpriseDataT statusBar={statusBar} domLayout={domLayout} overlayLoadingTemplate={`${loadingMessage}`} - overlayNoRowsTemplate={`${noRowsMessage}`} + overlayNoRowsTemplate={`${noRowsMessage}`} {...restAgGridProps} /> diff --git a/packages/ui/src/foundations/enterprise-module/providers/detail-page.provider.tsx b/packages/ui/src/foundations/enterprise-module/providers/detail-page.provider.tsx index 84d91a2..3aee758 100644 --- a/packages/ui/src/foundations/enterprise-module/providers/detail-page.provider.tsx +++ b/packages/ui/src/foundations/enterprise-module/providers/detail-page.provider.tsx @@ -1,7 +1,7 @@ import { useCallback, useEffect, useMemo, useState } from 'react'; import { useParams } from 'react-router-dom'; import { BaseEntity } from '@repo/core-api/data-services'; -import { Check, CheckCircle, Copy, Edit2, PauseCircle, Plus, RotateCcw, Trash2, X, XCircle } from 'lucide-react'; +import { Check, Unlock, Copy, SquarePen, PauseCircle, Plus, RotateCcw, Trash, X, Lock } from 'lucide-react'; import { DetailPageContext } from '../hooks/use-detail-page.context'; import { EnterpriseDetailPageConfig, ModuleAction, ModuleActionType, ActionModalState } from '../entities/entity'; @@ -421,7 +421,7 @@ export function EnterpriseDetailPageProvider( ALLOW_DELETE && { key: ModuleAction.DELETE, label: t('common:actions.delete'), - icon: , + icon: , intent: 'destructive', variant: 'subtle', onClick: (key: ModuleActionType) => handleActionClick(key), @@ -432,7 +432,7 @@ export function EnterpriseDetailPageProvider( isDataActive && { key: ModuleAction.DEACTIVATE, label: t('common:actions.deactivate'), - icon: , + icon: , intent: 'default', variant: 'subtle', onClick: (key: ModuleActionType) => handleActionClick(key), @@ -443,7 +443,7 @@ export function EnterpriseDetailPageProvider( key: ModuleAction.ACTIVATE, label: t('common:actions.activate'), tooltipLabel: t('common:actions.activate'), - icon: , + icon: , intent: 'default', variant: 'subtle', onClick: (key: ModuleActionType) => handleActionClick(key), @@ -460,7 +460,7 @@ export function EnterpriseDetailPageProvider( ALLOW_EDIT && { key: ModuleAction.EDIT, label: t('common:actions.edit'), - icon: , + icon: , intent: 'default', variant: 'subtle', onClick: (key: ModuleActionType) => handleActionClick(key),