Grid selection
This commit is contained in:
parent
6350b513ca
commit
4186219c50
@ -1,3 +1,10 @@
|
|||||||
|
import {
|
||||||
|
IconEdit,
|
||||||
|
IconExclamationMark,
|
||||||
|
IconRefresh,
|
||||||
|
IconSquarePlus,
|
||||||
|
IconTrashX,
|
||||||
|
} from '@tabler/icons-react';
|
||||||
import { useCallback, useEffect } from 'react';
|
import { useCallback, useEffect } from 'react';
|
||||||
|
|
||||||
import type { MantineBetterMenuInstanceItem } from '../../MantineBetterMenu';
|
import type { MantineBetterMenuInstanceItem } from '../../MantineBetterMenu';
|
||||||
@ -7,9 +14,14 @@ import type { GridlerColumn } from './Column';
|
|||||||
import { type GridlerProps, type GridlerState, useGridlerStore } from './Store';
|
import { type GridlerProps, type GridlerState, useGridlerStore } from './Store';
|
||||||
|
|
||||||
export function GlidlerFormInterface(props: {
|
export function GlidlerFormInterface(props: {
|
||||||
|
descriptionField?: ((data: Record<string, unknown>) => string) | string;
|
||||||
getMenuItems?: GridlerProps['getMenuItems'];
|
getMenuItems?: GridlerProps['getMenuItems'];
|
||||||
onReload?: () => void;
|
onReload?: () => void;
|
||||||
onRequestForm: (request: FormRequestType, data: Record<string, unknown>) => void;
|
onRequestForm: (
|
||||||
|
request: FormRequestType,
|
||||||
|
data: Array<Record<string, unknown>> | Record<string, unknown>
|
||||||
|
) => void;
|
||||||
|
showDescriptionInMenu?: boolean;
|
||||||
}) {
|
}) {
|
||||||
const [getState, mounted, setState, reload] = useGridlerStore((s) => [
|
const [getState, mounted, setState, reload] = useGridlerStore((s) => [
|
||||||
s.getState,
|
s.getState,
|
||||||
@ -22,7 +34,7 @@ export function GlidlerFormInterface(props: {
|
|||||||
(
|
(
|
||||||
id: string,
|
id: string,
|
||||||
storeState: GridlerState,
|
storeState: GridlerState,
|
||||||
row?: unknown,
|
row?: Record<string, unknown>,
|
||||||
col?: GridlerColumn,
|
col?: GridlerColumn,
|
||||||
defaultItems?: Array<unknown>
|
defaultItems?: Array<unknown>
|
||||||
) => {
|
) => {
|
||||||
@ -33,13 +45,26 @@ export function GlidlerFormInterface(props: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const items = [] as Array<MantineBetterMenuInstanceItem>;
|
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) {
|
if (!row) {
|
||||||
const firstRow = getState('_gridSelection')?.rows?.first();
|
const firstRow = rows[0];
|
||||||
if (firstRow !== undefined) {
|
if (firstRow !== undefined) {
|
||||||
row = storeState.getRowBuffer(firstRow);
|
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') {
|
if (id === 'other') {
|
||||||
items.push({
|
items.push({
|
||||||
c: 'blue',
|
c: 'blue',
|
||||||
@ -51,35 +76,70 @@ export function GlidlerFormInterface(props: {
|
|||||||
}
|
}
|
||||||
if ((id === 'cell' && row) || (id === 'menu' && row)) {
|
if ((id === 'cell' && row) || (id === 'menu' && row)) {
|
||||||
items.push({
|
items.push({
|
||||||
c: 'blue',
|
c: 'teal',
|
||||||
label: 'Add',
|
label: 'Add',
|
||||||
|
leftSection: <IconSquarePlus color="teal" size={16} />,
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
props.onRequestForm('insert', row as Record<string, unknown>);
|
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({
|
items.push({
|
||||||
c: 'green',
|
isDivider: true,
|
||||||
label: 'Change',
|
|
||||||
onClick: () => {
|
|
||||||
props.onRequestForm('change', row as Record<string, unknown>);
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
} else if ((id === 'cell' && !row) || (id === 'menu' && !row)) {
|
||||||
items.push({
|
items.push({
|
||||||
c: 'red',
|
c: 'red',
|
||||||
label: 'Delete',
|
label: `Nothing Selected`,
|
||||||
onClick: () => {
|
leftSection: <IconExclamationMark color="yellow" size={16} />,
|
||||||
props.onRequestForm('delete', row as Record<string, unknown>);
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
items.push({
|
|
||||||
isDivider: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
items.push({
|
items.push({
|
||||||
c: 'orange',
|
c: 'orange',
|
||||||
label: 'Refresh',
|
label: 'Refresh',
|
||||||
|
leftSection: <IconRefresh color="orange" size={16} />,
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
reload?.();
|
reload?.();
|
||||||
},
|
},
|
||||||
|
|||||||
@ -32,6 +32,7 @@ import { ColumnFilterSet, type GridlerColumn, type GridlerColumns } from './Colu
|
|||||||
import { SortDownSprite } from './sprites/SortDown';
|
import { SortDownSprite } from './sprites/SortDown';
|
||||||
import { SortUpSprite } from './sprites/SortUp';
|
import { SortUpSprite } from './sprites/SortUp';
|
||||||
import { SpriteImage } from './sprites/SpriteImage';
|
import { SpriteImage } from './sprites/SpriteImage';
|
||||||
|
import { IconGrid4x4 } from '@tabler/icons-react';
|
||||||
|
|
||||||
export type FilterOption = {
|
export type FilterOption = {
|
||||||
datatype?: 'array' | 'boolean' | 'date' | 'function' | 'number' | 'object' | 'string';
|
datatype?: 'array' | 'boolean' | 'date' | 'function' | 'number' | 'object' | 'string';
|
||||||
@ -418,14 +419,65 @@ const { Provider, useStore: useGridlerStore } = createSyncStore<GridlerStoreStat
|
|||||||
: coldef
|
: coldef
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
label: `Column ${coldef?.title ?? coldef?.id} Row ${row}`,
|
items: [
|
||||||
|
{
|
||||||
|
label: 'Sort Ascending',
|
||||||
|
leftSection: <SpriteImage sprite={SortUpSprite} />,
|
||||||
|
onClick: () => {
|
||||||
|
s.setStateFN('colSort', (c) => {
|
||||||
|
const cols = [...(c ?? [])];
|
||||||
|
const idx = cols.findIndex((search) => search.id === coldef.id);
|
||||||
|
const dir = 'asc';
|
||||||
|
if (idx < 0) {
|
||||||
|
const newSort: SortOption = {
|
||||||
|
direction: dir,
|
||||||
|
id: coldef.id,
|
||||||
|
order: cols?.length,
|
||||||
|
};
|
||||||
|
cols.push(newSort);
|
||||||
|
} else if (idx >= 0) {
|
||||||
|
cols[idx].direction = dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cols;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Sort Descending',
|
||||||
|
leftSection: <SpriteImage sprite={SortDownSprite} />,
|
||||||
|
onClick: () => {
|
||||||
|
s.setStateFN('colSort', (c) => {
|
||||||
|
const cols = [...(c ?? [])];
|
||||||
|
const idx = cols.findIndex((search) => search.id === coldef.id);
|
||||||
|
const dir = 'desc';
|
||||||
|
if (idx < 0) {
|
||||||
|
const newSort: SortOption = {
|
||||||
|
direction: dir,
|
||||||
|
id: coldef.id,
|
||||||
|
order: cols?.length,
|
||||||
|
};
|
||||||
|
cols.push(newSort);
|
||||||
|
} else if (idx >= 0) {
|
||||||
|
cols[idx].direction = dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cols;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: `Filter ${coldef?.title ?? coldef?.id}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
renderer: <ColumnFilterSet column={coldef} storeState={get()} />,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
label: `Column Settings for ${coldef?.title ?? coldef?.id}`,
|
||||||
|
leftSection: <IconGrid4x4 size={16} />,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
: [
|
: [];
|
||||||
{
|
|
||||||
label: `No Column ${area}`,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
s.hideMenu?.(area);
|
s.hideMenu?.(area);
|
||||||
|
|
||||||
s.showMenu?.(area, {
|
s.showMenu?.(area, {
|
||||||
|
|||||||
@ -94,6 +94,7 @@ export const GridlerGoAPIExampleEventlog = () => {
|
|||||||
>
|
>
|
||||||
<Gridler.APIAdaptorGoLangv2 authtoken={apiKey} url={`${apiUrl}/public/process`} />
|
<Gridler.APIAdaptorGoLangv2 authtoken={apiKey} url={`${apiUrl}/public/process`} />
|
||||||
<Gridler.GlidlerFormInterface
|
<Gridler.GlidlerFormInterface
|
||||||
|
descriptionField={'process'}
|
||||||
onRequestForm={(request, data) => {
|
onRequestForm={(request, data) => {
|
||||||
console.log('Form requested', request, data);
|
console.log('Form requested', request, data);
|
||||||
}}
|
}}
|
||||||
|
|||||||
@ -1,14 +1,15 @@
|
|||||||
import { Menu, Portal } from '@mantine/core';
|
import { Menu, Portal } from '@mantine/core';
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
|
|
||||||
import { type MantineBetterMenuInstanceItem, useMantineBetterMenus } from './Store';
|
import { type MantineBetterMenuInstanceItem, useMantineBetterMenus } from './Store';
|
||||||
|
|
||||||
export function MenuRenderer() {
|
export function MenuRenderer() {
|
||||||
const { menus, providerID, setInstanceState } = useMantineBetterMenus((s) => ({
|
const { menus, providerID, setInstanceState, width } = useMantineBetterMenus((s) => ({
|
||||||
menus: s.menus,
|
menus: s.menus,
|
||||||
providerID: s.providerID,
|
providerID: s.providerID,
|
||||||
setInstanceState: s.setInstanceState,
|
setInstanceState: s.setInstanceState,
|
||||||
setState: s.setState
|
setState: s.setState,
|
||||||
|
width: s.width,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -18,7 +19,7 @@ export function MenuRenderer() {
|
|||||||
return (
|
return (
|
||||||
<Menu
|
<Menu
|
||||||
shadow="md"
|
shadow="md"
|
||||||
width={200}
|
width={width ?? '300'}
|
||||||
{...m.menuProps}
|
{...m.menuProps}
|
||||||
key={`bmm_menu_${providerID}_${menuIndex}`}
|
key={`bmm_menu_${providerID}_${menuIndex}`}
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
@ -68,8 +69,47 @@ const MenuItemRenderer = ({ children, label, ...props }: MantineBetterMenuInstan
|
|||||||
return <Menu.Divider />;
|
return <Menu.Divider />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (props.items && props.items.length > 0) {
|
||||||
|
return (
|
||||||
|
<Menu.Sub>
|
||||||
|
<Menu.Sub.Target>
|
||||||
|
<Menu.Sub.Item
|
||||||
|
{...props}
|
||||||
|
disabled={loading}
|
||||||
|
onClick={(e) => {
|
||||||
|
props.onClick?.(e);
|
||||||
|
if (props.onClickAsync) {
|
||||||
|
setLoading(true);
|
||||||
|
props.onClickAsync().finally(() => setLoading(false));
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
styles={{
|
||||||
|
itemLabel: {
|
||||||
|
overflow: 'auto',
|
||||||
|
wordWrap: 'break-word',
|
||||||
|
},
|
||||||
|
...props.styles,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{children ?? label}
|
||||||
|
</Menu.Sub.Item>
|
||||||
|
</Menu.Sub.Target>
|
||||||
|
<Menu.Sub.Dropdown>
|
||||||
|
{React.Children.toArray(
|
||||||
|
props.items.map((subitem, subitemIndex) => (
|
||||||
|
<MenuItemRenderer
|
||||||
|
key={`bmm_subitem_${subitem?.id ?? ''}${subitemIndex}`}
|
||||||
|
{...subitem}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
</Menu.Sub.Dropdown>
|
||||||
|
</Menu.Sub>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (!props.onClick && !props.onClickAsync) {
|
if (!props.onClick && !props.onClickAsync) {
|
||||||
return <Menu.Label {...(props as Record<string,unknown>)}> {children ?? label}</Menu.Label>;
|
return <Menu.Label {...(props as Record<string, unknown>)}> {children ?? label}</Menu.Label>;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -77,12 +117,19 @@ const MenuItemRenderer = ({ children, label, ...props }: MantineBetterMenuInstan
|
|||||||
{...props}
|
{...props}
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
props.onClick?.(e );
|
props.onClick?.(e);
|
||||||
if (props.onClickAsync) {
|
if (props.onClickAsync) {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
props.onClickAsync().finally(() => setLoading(false));
|
props.onClickAsync().finally(() => setLoading(false));
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
styles={{
|
||||||
|
itemLabel: {
|
||||||
|
overflow: 'auto',
|
||||||
|
wordWrap: 'break-word',
|
||||||
|
},
|
||||||
|
...props.styles,
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{children ?? label}
|
{children ?? label}
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
|
|||||||
@ -11,12 +11,15 @@ export interface MantineBetterMenuInstance {
|
|||||||
menuProps?: MenuProps;
|
menuProps?: MenuProps;
|
||||||
renderer?: ReactNode;
|
renderer?: ReactNode;
|
||||||
visible: boolean;
|
visible: boolean;
|
||||||
|
|
||||||
x: number;
|
x: number;
|
||||||
y: number;
|
y: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MantineBetterMenuInstanceItem extends Partial<MenuItemProps> {
|
export interface MantineBetterMenuInstanceItem extends Partial<MenuItemProps> {
|
||||||
|
id?: string;
|
||||||
isDivider?: boolean;
|
isDivider?: boolean;
|
||||||
|
items?: Array<MantineBetterMenuInstanceItem>;
|
||||||
label?: string;
|
label?: string;
|
||||||
onClick?: (e?: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;
|
onClick?: (e?: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;
|
||||||
onClickAsync?: () => Promise<void>;
|
onClickAsync?: () => Promise<void>;
|
||||||
@ -28,6 +31,7 @@ export interface MantineBetterMenuInstanceItem extends Partial<MenuItemProps> {
|
|||||||
export interface MenuStoreProps {
|
export interface MenuStoreProps {
|
||||||
menus?: Array<MantineBetterMenuInstance>;
|
menus?: Array<MantineBetterMenuInstance>;
|
||||||
providerID?: string;
|
providerID?: string;
|
||||||
|
width?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type MenuStoreState = MenuStoreProps & MenuStoreStateOnly;
|
export type MenuStoreState = MenuStoreProps & MenuStoreStateOnly;
|
||||||
@ -44,61 +48,62 @@ export interface MenuStoreStateOnly {
|
|||||||
show: (id: string, options?: Partial<MantineBetterMenuInstance>) => void;
|
show: (id: string, options?: Partial<MantineBetterMenuInstance>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { Provider:MantineBetterMenusStoreProvider, useStore:useMantineBetterMenus } = createSyncStore<MenuStoreState, MenuStoreProps>(
|
const { Provider: MantineBetterMenusStoreProvider, useStore: useMantineBetterMenus } =
|
||||||
(set, get) => ({
|
createSyncStore<MenuStoreState, MenuStoreProps>(
|
||||||
hide: (id: string) => {
|
(set, get) => ({
|
||||||
const s = get();
|
hide: (id: string) => {
|
||||||
s.setInstanceState(id, 'visible', false);
|
const s = get();
|
||||||
},
|
s.setInstanceState(id, 'visible', false);
|
||||||
menus: [],
|
},
|
||||||
setInstanceState: (id, key, value) => {
|
menus: [],
|
||||||
//@ts-expect-error Type instantiation is excessively deep and possibly infinite.
|
setInstanceState: (id, key, value) => {
|
||||||
set(
|
//@ts-expect-error Type instantiation is excessively deep and possibly infinite.
|
||||||
produce((state: MenuStoreState) => {
|
|
||||||
const idx = state?.menus?.findIndex((m: MantineBetterMenuInstance) => m.id === id);
|
|
||||||
if (idx >= 0) {
|
|
||||||
state.menus[idx][key] = value;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
|
||||||
setState: (key, value) => {
|
|
||||||
set(
|
|
||||||
produce((state) => {
|
|
||||||
state[key] = value;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
|
||||||
show: (id: string, options?: Partial<Omit<MantineBetterMenuInstance, 'id'>>) => {
|
|
||||||
const s = get();
|
|
||||||
const menuIndex = s.menus.findIndex((m) => m.id === id);
|
|
||||||
const menu: Partial<MantineBetterMenuInstance> = s.menus[menuIndex]
|
|
||||||
? { ...s.menus[menuIndex] }
|
|
||||||
: {};
|
|
||||||
|
|
||||||
Object.assign(menu, options);
|
|
||||||
menu.id = menu.id ?? id;
|
|
||||||
menu.visible = !(menu.visible ?? false);
|
|
||||||
|
|
||||||
if (menuIndex < 0) {
|
|
||||||
s.setState('menus', [...s.menus, menu as MantineBetterMenuInstance]);
|
|
||||||
} else {
|
|
||||||
set(
|
set(
|
||||||
produce((state: MenuStoreState) => {
|
produce((state: MenuStoreState) => {
|
||||||
if (!state.menus) {
|
const idx = state?.menus?.findIndex((m: MantineBetterMenuInstance) => m.id === id);
|
||||||
state.menus = [];
|
if (idx >= 0) {
|
||||||
|
state.menus[idx][key] = value;
|
||||||
}
|
}
|
||||||
state.menus[menuIndex] = { ...state.menus[menuIndex], ...menu };
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
}
|
setState: (key, value) => {
|
||||||
}),
|
set(
|
||||||
(props) => {
|
produce((state) => {
|
||||||
return {
|
state[key] = value;
|
||||||
providerID: props.providerID ?? `MenuStore-${getUUID()}`
|
})
|
||||||
};
|
);
|
||||||
}
|
},
|
||||||
);
|
show: (id: string, options?: Partial<Omit<MantineBetterMenuInstance, 'id'>>) => {
|
||||||
|
const s = get();
|
||||||
|
const menuIndex = s.menus.findIndex((m) => m.id === id);
|
||||||
|
const menu: Partial<MantineBetterMenuInstance> = s.menus[menuIndex]
|
||||||
|
? { ...s.menus[menuIndex] }
|
||||||
|
: {};
|
||||||
|
|
||||||
export { MantineBetterMenusStoreProvider,useMantineBetterMenus };
|
Object.assign(menu, options);
|
||||||
|
menu.id = menu.id ?? id;
|
||||||
|
menu.visible = !(menu.visible ?? false);
|
||||||
|
|
||||||
|
if (menuIndex < 0) {
|
||||||
|
s.setState('menus', [...s.menus, menu as MantineBetterMenuInstance]);
|
||||||
|
} else {
|
||||||
|
set(
|
||||||
|
produce((state: MenuStoreState) => {
|
||||||
|
if (!state.menus) {
|
||||||
|
state.menus = [];
|
||||||
|
}
|
||||||
|
state.menus[menuIndex] = { ...state.menus[menuIndex], ...menu };
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
(props) => {
|
||||||
|
return {
|
||||||
|
providerID: props.providerID ?? `MenuStore-${getUUID()}`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export { MantineBetterMenusStoreProvider, useMantineBetterMenus };
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user