mod-arch-shared
Version:
Shared UI components and utilities for modular architecture micro-frontend projects
99 lines • 4.7 kB
JavaScript
import * as React from 'react';
import { useBrowserStorage } from 'mod-arch-core';
import { CHECKBOX_FIELD_ID, EXPAND_FIELD_ID, KEBAB_FIELD_ID } from './const';
// Fields that are never manageable by users (UI chrome columns)
const NON_MANAGEABLE_FIELDS = [CHECKBOX_FIELD_ID, KEBAB_FIELD_ID, EXPAND_FIELD_ID];
export const useManageColumns = ({ allColumns, storageKey, defaultVisibleColumnIds, maxVisibleColumns, }) => {
// Get manageable columns (those that can be shown/hidden)
const manageableColumns = React.useMemo(() => allColumns.filter((col) => !NON_MANAGEABLE_FIELDS.includes(col.field)), [allColumns]);
// Calculate default visible fields if not provided
const effectivedefaultVisibleColumnIds = React.useMemo(() => {
if (defaultVisibleColumnIds) {
const normalizedDefaults = defaultVisibleColumnIds.filter((id) => manageableColumns.some((col) => col.field === id));
const defaultCount = maxVisibleColumns ?? 2;
return normalizedDefaults.slice(0, defaultCount);
}
// Default: show first maxVisibleColumns columns, or first 2 if not specified
const manageableFields = manageableColumns.map((col) => col.field);
const defaultCount = maxVisibleColumns ?? 2;
return manageableFields.slice(0, defaultCount);
}, [defaultVisibleColumnIds, manageableColumns, maxVisibleColumns]);
// Persist visible column IDs to localStorage
const [storedVisibleIds, setStoredVisibleIds] = useBrowserStorage(storageKey, effectivedefaultVisibleColumnIds, true);
// Build the managed columns list for the modal
// Preserves order from storage, adds any new columns at the end
const managedColumns = React.useMemo(() => {
const orderedIds = [...storedVisibleIds];
const allManageableIds = manageableColumns.map((col) => col.field);
// Add columns that are not in storage (new columns)
allManageableIds.forEach((id) => {
if (!orderedIds.includes(id)) {
orderedIds.push(id);
}
});
return orderedIds
.filter((id) => allManageableIds.includes(id)) // Remove deleted columns
.map((id) => {
const col = manageableColumns.find((c) => c.field === id);
if (!col) {
return null;
}
return {
id: col.field,
label: col.label,
isVisible: storedVisibleIds.includes(col.field),
};
})
.filter((col) => col !== null);
}, [manageableColumns, storedVisibleIds]);
// Build the final visible columns for the table
const visibleColumns = React.useMemo(() => {
const result = [];
// First, add columns that come before manageable columns (like checkbox)
allColumns.forEach((col) => {
if (col.field === CHECKBOX_FIELD_ID || col.field === EXPAND_FIELD_ID) {
result.push(col);
}
});
// Add visible manageable columns in their stored order
const visibleManageableIds = storedVisibleIds.filter((id) => manageableColumns.some((col) => col.field === id));
visibleManageableIds.forEach((id) => {
const col = manageableColumns.find((c) => c.field === id);
if (col) {
result.push(col);
}
});
// Add kebab column at the end if present
const kebabCol = allColumns.find((col) => col.field === KEBAB_FIELD_ID);
if (kebabCol) {
result.push(kebabCol);
}
return result;
}, [allColumns, storedVisibleIds, manageableColumns]);
const setVisibleColumnIds = React.useCallback((columnIds) => {
const uniqueManageableIds = Array.from(new Set(columnIds)).filter((id) => manageableColumns.some((col) => col.field === id));
const normalizedIds = maxVisibleColumns !== undefined
? uniqueManageableIds.slice(0, maxVisibleColumns)
: uniqueManageableIds;
setStoredVisibleIds(normalizedIds);
}, [setStoredVisibleIds, manageableColumns, maxVisibleColumns]);
// Modal state management
const [isModalOpen, setIsModalOpen] = React.useState(false);
const openModal = React.useCallback(() => {
setIsModalOpen(true);
}, []);
const closeModal = React.useCallback(() => {
setIsModalOpen(false);
}, []);
return {
visibleColumns,
managedColumns,
setVisibleColumnIds,
visibleColumnIds: storedVisibleIds,
defaultVisibleColumnIds,
isModalOpen,
openModal,
closeModal,
};
};
//# sourceMappingURL=useManageColumns.js.map