feat: add StatusBadge component and integrate action confirmation modal
- Introduced StatusBadge component for displaying various status indicators with customizable colors and icons. - Updated ModulePageHeader to conditionally render badges based on props. - Implemented ActionConfirmationModal for handling lifecycle actions (delete, activate, etc.) with support for forms and custom body rendering. - Enhanced EnterpriseDetailPageProvider to manage action confirmation modal state and execution of actions. - Added new modal configurations for various actions in EnterpriseDetailPageConfig. - Updated theme provider to include ModalsProvider and Notifications for better user feedback.
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
import { ReactNode } from 'react';
|
||||
import type { UseFormReturn } from 'react-hook-form';
|
||||
import type { ZodType } from 'zod';
|
||||
import type { BaseEntity, BaseRemoteDataServices } from '@repo/core-api/data-services';
|
||||
import type { ModulePageHeaderProps } from '../components/module-page-header';
|
||||
import { PageActionsProps } from '../../../components';
|
||||
@@ -219,9 +221,84 @@ export interface EnterpriseFormPageConfig<E extends BaseEntity = BaseEntity> ext
|
||||
presetDuplicate?: (data: E) => Promise<Partial<E>>;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Action Confirmation Modal Configuration
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Configuration for the confirmation modal shown before executing a lifecycle action.
|
||||
*
|
||||
* Supports three modes:
|
||||
* 1. **Simple confirmation** — no `renderBody`, just a confirm/cancel dialog.
|
||||
* 2. **Static body** — `renderBody` returns static JSX (text, checkboxes, etc.).
|
||||
* 3. **Form body** — `renderBody` receives an RHF `UseFormReturn` instance.
|
||||
* The implementer renders `Field*` components bound to the form.
|
||||
* Form data is validated via `schema` before submission and sent as `meta`.
|
||||
*
|
||||
* @template TMeta The shape of the form data (defaults to Record<string, unknown>).
|
||||
*/
|
||||
export interface ActionModalConfig<TMeta extends Record<string, unknown> = Record<string, unknown>> {
|
||||
/** Modal title override. Defaults to action-specific translation (e.g., "Delete Item?") */
|
||||
title?: string;
|
||||
/**
|
||||
* Custom modal body renderer.
|
||||
*
|
||||
* When provided WITHOUT `schema`/`defaultValues`, receives `undefined` — render static content.
|
||||
* When provided WITH `schema`/`defaultValues`, receives a fully-typed `UseFormReturn<TMeta>`
|
||||
* instance. Use `Field*` components from `@repo/ui/form` bound to this form.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* // Static body (no form)
|
||||
* renderBody: () => <Text>Are you sure you want to delete this item?</Text>
|
||||
*
|
||||
* // Form body
|
||||
* renderBody: (form) => (
|
||||
* <FieldTextarea name="reason" control={form.control} label="Reason" />
|
||||
* )
|
||||
* ```
|
||||
*/
|
||||
renderBody?: (form?: UseFormReturn<TMeta>) => ReactNode;
|
||||
/** Zod schema for validating the form body. When omitted, no validation is applied */
|
||||
schema?: ZodType<TMeta>;
|
||||
/** Default values for the form. Required when schema is provided */
|
||||
defaultValues?: TMeta;
|
||||
/** Confirm button label override. Defaults to action translation */
|
||||
confirmLabel?: string;
|
||||
/** Cancel button label override. Defaults to t('common:actions.cancel') */
|
||||
cancelLabel?: string;
|
||||
/** Size of the modal. @default 'md' */
|
||||
size?: string | number;
|
||||
/** Custom success message or a function to generate it after action completes successfully */
|
||||
successMessage?: string | ((data?: any) => string);
|
||||
/** Custom error message or a function to extract it from the network error */
|
||||
errorMessage?: string | ((error: any) => string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal state for the action confirmation modal managed by the detail page provider.
|
||||
* @internal
|
||||
*/
|
||||
export interface ActionModalState<E extends BaseEntity = BaseEntity> {
|
||||
opened: boolean;
|
||||
action: ModuleActionType | null;
|
||||
data: E | null;
|
||||
config?: ActionModalConfig<any>;
|
||||
}
|
||||
|
||||
export interface EnterpriseDetailPageConfig<E extends BaseEntity = BaseEntity> extends BasePageConfig {
|
||||
editMode?: 'FULL' | 'PARTIAL';
|
||||
customPageActions?: (data: E, actions: PageActionsProps['actions']) => PageActionsProps['actions'];
|
||||
onDetailLoaded?: (data: E) => void;
|
||||
|
||||
showHighlightData?: boolean;
|
||||
showHighlightDataOnBreadcrumbs?: boolean;
|
||||
highlightDataKey?: string;
|
||||
|
||||
/** Key to reference status data in the entity, used to render the status badge automatically. @default 'status' */
|
||||
statusKey?: string;
|
||||
/** Custom callback to provide dynamic status badge properties */
|
||||
getCustomStatusConfig?: (status: string) => Partial<import('@mantine/core').BadgeProps>;
|
||||
|
||||
onClickCreate?: () => void;
|
||||
onClickDuplicate?: (data: E) => void;
|
||||
@@ -238,9 +315,14 @@ export interface EnterpriseDetailPageConfig<E extends BaseEntity = BaseEntity> e
|
||||
onClickRollback?: (data: E) => void;
|
||||
onClickHold?: (data: E) => void;
|
||||
|
||||
showHighlightData?: boolean;
|
||||
showHighlightDataOnBreadcrumbs?: boolean;
|
||||
highlightDataKey?: string;
|
||||
// Action Modal Configurations
|
||||
deleteModalConfig?: ActionModalConfig;
|
||||
activateModalConfig?: ActionModalConfig;
|
||||
deactivateModalConfig?: ActionModalConfig;
|
||||
confirmModalConfig?: ActionModalConfig;
|
||||
cancelModalConfig?: ActionModalConfig;
|
||||
rollbackModalConfig?: ActionModalConfig;
|
||||
holdModalConfig?: ActionModalConfig;
|
||||
}
|
||||
|
||||
export interface PrivilegeEntity {
|
||||
|
||||
Reference in New Issue
Block a user