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 (
}
>
);
}