import {FormTextField} from '../../ui/forms/input-field/text-field/text-field'; import {Trans} from '../../i18n/trans'; import {useValueLists} from '../../http/value-lists'; import {useTrans} from '../../i18n/use-trans'; import {FormChipField} from '../../ui/forms/input-field/chip-field/form-chip-field'; import {Item} from '../../ui/forms/listbox/item'; import {Fragment, useEffect, useMemo} from 'react'; import { buildPermissionList, prettyName, } from '../../auth/ui/permission-selector'; import {Section} from '../../ui/forms/listbox/section'; import {useFormContext} from 'react-hook-form'; import {MenuItemConfig} from '../../core/settings/settings'; import {FormSelect, Option} from '../../ui/forms/select/select'; import {useAvailableRoutes} from '../appearance/sections/menus/hooks/available-routes'; import {ButtonBaseProps} from '../../ui/buttons/button-base'; import {createSvgIconFromTree, IconTree} from '../../icons/create-svg-icon'; import {DialogTrigger} from '../../ui/overlays/dialog/dialog-trigger'; import {IconButton} from '../../ui/buttons/icon-button'; import {EditIcon} from '../../icons/material/Edit'; import {IconPickerDialog} from '../../ui/icon-picker/icon-picker-dialog'; import {message} from '../../i18n/message'; import {usePrevious} from '../../utils/hooks/use-previous'; interface NameProps { prefixName: (name: string) => string; } interface MenuItemFormProps { formPathPrefix?: string; hideRoleAndPermissionFields?: boolean; } export function MenuItemForm({ formPathPrefix, hideRoleAndPermissionFields, }: MenuItemFormProps) { const {trans} = useTrans(); const prefixName = (name: string): string => { return formPathPrefix ? `${formPathPrefix}.${name}` : name; }; return ( } placeholder={trans(message('No label...'))} startAppend={} /> {!hideRoleAndPermissionFields && ( )} ); } interface IconDialogTriggerProps extends ButtonBaseProps, NameProps {} function IconDialogTrigger({ prefixName, ...buttonProps }: IconDialogTriggerProps) { const {watch, setValue} = useFormContext(); const fieldName = prefixName('icon') as 'icon'; const watchedItemIcon = watch(fieldName); const Icon = watchedItemIcon && createSvgIconFromTree(watchedItemIcon); return ( { // null will be set explicitly if icon is cleared via icon picker if (iconTree || iconTree === null) { setValue(fieldName, iconTree, { shouldDirty: true, }); } }} > {Icon ? : } ); } function DestinationSelector({prefixName}: NameProps) { const form = useFormContext(); const currentType = form.watch(prefixName('type') as 'type'); const previousType = usePrevious(currentType); const {data} = useValueLists(['menuItemCategories']); const categories = data?.menuItemCategories || []; const selectedCategory = categories.find(c => c.type === currentType); const {trans} = useTrans(); const routeItems = useAvailableRoutes(); // clear "action" field when "type" field changes useEffect(() => { if (previousType && previousType !== currentType) { form.setValue(prefixName('action') as 'action', ''); } }, [currentType, previousType, form, prefixName]); return ( } > {categories.map(category => ( ))} {currentType === 'link' && ( } /> )} {currentType === 'route' && ( } searchPlaceholder={trans(message('Search pages'))} showSearchField selectionMode="single" > {item => ( {item.label} )} )} {selectedCategory && ( } > {item => ( )} )} ); } function RoleSelector({prefixName}: NameProps) { const {data} = useValueLists(['roles', 'permissions']); const roles = data?.roles || []; const {trans} = useTrans(); return ( } name={prefixName('roles')} chipSize="sm" suggestions={roles} valueKey="id" displayWith={c => roles.find(r => r.id === c.id)?.name} > {role => ( )} ); } function PermissionSelector({prefixName}: NameProps) { const {data} = useValueLists(['roles', 'permissions']); const {trans} = useTrans(); const groupedPermissions = useMemo(() => { return buildPermissionList(data?.permissions || [], [], false); }, [data?.permissions]); return ( } placeholder={trans({message: 'Add permission...'})} chipSize="sm" suggestions={groupedPermissions} name={prefixName('permissions')} valueKey="name" > {({groupName, items}) => (
{items.map(permission => ( } > ))}
)}
); } function TargetSelect({prefixName}: NameProps) { const form = useFormContext(); const watchedType = form.watch(prefixName('type') as 'type'); // routes and pages can only be "_self" if (watchedType !== 'link') { return null; } return ( } > ); }