feat: add RowActions component for enhanced row-level actions in data grids
- Introduced RowActions component to manage row-level actions with tooltips and dropdown menus. - Created types for row actions and page actions to standardize action properties. - Implemented utility function to map action intents to Mantine theme colors. - Updated CoreAppShell component to support optional slots for better flexibility. - Added enterprise module structure with context hooks for managing module state and actions. - Implemented draft management for forms to enhance user experience during data entry. - Established context providers for detail, form, and index pages to streamline data handling. - Updated dependencies to ensure compatibility with the latest versions.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
export { setupI18n, type SupportedLanguage } from './setup';
|
||||
export { changeLanguage, applyTenantOverrides } from './manager';
|
||||
export { registerModuleNamespace, isNamespaceRegistered } from './registry';
|
||||
export { useTranslation, Trans } from 'react-i18next';
|
||||
export { default as i18n } from 'i18next';
|
||||
|
||||
@@ -5,8 +5,10 @@
|
||||
"success": "Success",
|
||||
"error": "Error",
|
||||
"settings": "Settings",
|
||||
"loading": "Loading...",
|
||||
"loading": "Loading",
|
||||
"delete": "Delete",
|
||||
"edit": "Edit"
|
||||
"edit": "Edit",
|
||||
"duplicate": "Duplicate",
|
||||
"view": "View"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,8 +5,10 @@
|
||||
"success": "Sukses",
|
||||
"error": "Galat",
|
||||
"settings": "Pengaturan",
|
||||
"loading": "Memuat...",
|
||||
"loading": "Memuat",
|
||||
"delete": "Hapus",
|
||||
"edit": "Ubah"
|
||||
"edit": "Ubah",
|
||||
"duplicate": "Duplikat",
|
||||
"view": "Lihat"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
import i18n from 'i18next';
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Module Namespace Registry
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Tracks which namespaces have already been registered to prevent
|
||||
* double-registration and detect accidental namespace collisions.
|
||||
*/
|
||||
const registeredNamespaces = new Set<string>();
|
||||
|
||||
/**
|
||||
* Resources shape expected by registerModuleNamespace.
|
||||
* Keys are language codes, values are flat or nested translation objects.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const resources = {
|
||||
* en: { title: 'Full Page', fields: { name: 'Name' } },
|
||||
* id: { title: 'Halaman Penuh', fields: { name: 'Nama' } },
|
||||
* };
|
||||
* ```
|
||||
*/
|
||||
export type ModuleNamespaceResources = Record<string, Record<string, unknown>>;
|
||||
|
||||
/**
|
||||
* Registers a module's translation namespace into the global i18n instance.
|
||||
*
|
||||
* **Must be called at module scope** (outside any React component) to ensure
|
||||
* resources are available before the first render. The function is idempotent —
|
||||
* calling it multiple times with the same namespace is a safe no-op.
|
||||
*
|
||||
* @param namespace - Unique namespace identifier (should match the JSON filename, e.g. 'full-page').
|
||||
* @param resources - An object keyed by language code containing the translation dictionaries.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* import fullPageEn from '../locales/en/full-page.json';
|
||||
* import fullPageId from '../locales/id/full-page.json';
|
||||
*
|
||||
* // ✅ Called at module scope — safe, idempotent, outside React render
|
||||
* registerModuleNamespace('full-page', {
|
||||
* en: fullPageEn,
|
||||
* id: fullPageId,
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function registerModuleNamespace(namespace: string, resources: ModuleNamespaceResources): void {
|
||||
if (registeredNamespaces.has(namespace)) {
|
||||
return; // Already registered — no-op
|
||||
}
|
||||
|
||||
registeredNamespaces.add(namespace);
|
||||
|
||||
for (const [lng, bundle] of Object.entries(resources)) {
|
||||
// deep: true → merges with any existing keys under this namespace
|
||||
// overwrite: false → does NOT replace keys that already exist (e.g. tenant overrides)
|
||||
i18n.addResourceBundle(lng, namespace, bundle, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a namespace has been registered.
|
||||
* Useful for debugging or conditional loading logic.
|
||||
*/
|
||||
export function isNamespaceRegistered(namespace: string): boolean {
|
||||
return registeredNamespaces.has(namespace);
|
||||
}
|
||||
Reference in New Issue
Block a user