oranguru/src/Gridler/components/adaptors/GlidlerFormAdaptor.tsx
2025-10-21 14:10:59 +02:00

173 lines
5.1 KiB
TypeScript

import {
IconEdit,
IconExclamationMark,
IconRefresh,
IconSquarePlus,
IconTrashX,
} from '@tabler/icons-react';
import { useCallback, useEffect } from 'react';
import type { MantineBetterMenuInstanceItem } from '../../../MantineBetterMenu';
import type { FormRequestType } from '../../utils/types';
import type { GridlerColumn } from '../Column';
import { type GridlerProps, type GridlerState, useGridlerStore } from '../GridlerStore';
export function GlidlerFormAdaptor(props: {
descriptionField?: ((data: Record<string, unknown>) => string) | string;
getMenuItems?: GridlerProps['getMenuItems'];
onReload?: () => void;
onRequestForm: (
request: FormRequestType,
data: Array<Record<string, unknown>> | Record<string, unknown>
) => void;
showDescriptionInMenu?: boolean;
}) {
const [getState, mounted, setState, reload] = useGridlerStore((s) => [
s.getState,
s.mounted,
s.setState,
s.reload,
]);
const getMenuItems = useCallback(
(
id: string,
storeState: GridlerState,
row?: Record<string, unknown>,
col?: GridlerColumn,
defaultItems?: Array<unknown>
) => {
//console.log('GlidlerFormInterface getMenuItems', id);
if (id === 'header-menu') {
return defaultItems || [];
}
const items = [] as Array<MantineBetterMenuInstanceItem>;
if (defaultItems && id === 'cell') {
items.push(...(defaultItems as Array<MantineBetterMenuInstanceItem>));
}
const rows = getState('_gridSelection')?.rows.toArray() ?? [];
const manyRows = rows.length > 1;
if (!row) {
const firstRow = rows[0];
if (firstRow !== undefined) {
row = storeState.getRowBuffer(firstRow);
}
}
const desc =
typeof props.descriptionField === 'string'
? row?.[props.descriptionField]
: typeof props.descriptionField === 'function' && row
? props.descriptionField(row)
: undefined;
if (id === 'other') {
items.push({
c: 'blue',
label: 'Add',
onClick: () => {
props.onRequestForm('insert', row as Record<string, unknown>);
},
});
}
if ((id === 'cell' && row) || (id === 'menu' && row)) {
items.push({
c: 'teal',
label: 'Add',
leftSection: <IconSquarePlus color="teal" size={16} />,
onClick: () => {
props.onRequestForm('insert', row as Record<string, unknown>);
},
});
if (!manyRows) {
items.push({
c: 'green',
label: `Modify${desc && props.showDescriptionInMenu ? ` (${desc})` : ''}`,
leftSection: <IconEdit color="green" size={16} />,
onClick: () => {
props.onRequestForm('change', row as Record<string, unknown>);
},
});
items.push({
c: 'red',
label: `Remove${desc && props.showDescriptionInMenu ? ` (${desc})` : ''}`,
leftSection: <IconTrashX color="maroon" size={16} />,
onClick: () => {
props.onRequestForm('delete', row as Record<string, unknown>);
},
});
} else {
items.push({
c: 'green',
label: `Modify All Selected (${rows.length})`,
leftSection: <IconEdit color="green" size={16} />,
onClick: () => {
props.onRequestForm(
'change',
rows.map((r) => storeState.getRowBuffer(r)) as Array<Record<string, unknown>>
);
},
});
items.push({
c: 'red',
label: `Remove All Selected (${rows.length})`,
leftSection: <IconTrashX color="maroon" size={16} />,
onClick: () => {
props.onRequestForm(
'delete',
rows.map((r) => storeState.getRowBuffer(r)) as Array<Record<string, unknown>>
);
},
});
}
items.push({
isDivider: true,
});
} else if ((id === 'cell' && !row) || (id === 'menu' && !row)) {
items.push({
c: 'red',
label: `Nothing Selected`,
leftSection: <IconExclamationMark color="yellow" size={16} />,
});
}
items.push({
c: 'orange',
label: 'Refresh',
leftSection: <IconRefresh color="orange" size={16} />,
onClick: () => {
reload?.();
},
});
const result = props.getMenuItems
? props.getMenuItems(id, storeState, row, col, items)
: items;
//console.log('GlidlerFormInterface getMenuItems', id, items);
if (!items || items.length === 0) {
return defaultItems || [];
}
return result;
},
[props.onRequestForm, getState]
);
useEffect(() => {
if (mounted && typeof setState === 'function') {
//console.log('GlidlerFormInterface setState getMenuItems1', mounted);
if (getState('getMenuItems') !== getMenuItems) {
setState('getMenuItems', getMenuItems);
}
}
return () => {};
}, [props.getMenuItems, mounted]);
return <></>;
}