mirror of
https://github.com/ajnart/homarr.git
synced 2025-11-09 06:55:51 +01:00
♻️ Refactor icon picker (#724)
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
import { Autocomplete, createStyles, Flex, Tabs } from '@mantine/core';
|
||||
import { Flex, Tabs } from '@mantine/core';
|
||||
import { UseFormReturnType } from '@mantine/form';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useDebouncedValue } from '@mantine/hooks';
|
||||
import { useEffect } from 'react';
|
||||
import { useGetDashboardIcons } from '../../../../../../hooks/icons/useGetDashboardIcons';
|
||||
import { AppType } from '../../../../../../types/app';
|
||||
import { DebouncedAppIcon } from '../Shared/DebouncedAppIcon';
|
||||
import { IconSelector } from './IconSelector/IconSelector';
|
||||
import { IconSelector } from './IconSelector';
|
||||
|
||||
interface AppearanceTabProps {
|
||||
form: UseFormReturnType<AppType, (values: AppType) => AppType>;
|
||||
@@ -17,46 +17,39 @@ export const AppearanceTab = ({
|
||||
disallowAppNameProgagation,
|
||||
allowAppNamePropagation,
|
||||
}: AppearanceTabProps) => {
|
||||
const { t } = useTranslation('layout/modals/add-app');
|
||||
const { classes } = useStyles();
|
||||
const { isLoading, error, data } = useQuery({
|
||||
queryKey: ['autocompleteLocale'],
|
||||
queryFn: () => fetch('/api/getLocalImages').then((res) => res.json()),
|
||||
});
|
||||
const { data, isLoading } = useGetDashboardIcons();
|
||||
|
||||
const [debouncedValue] = useDebouncedValue(form.values.name, 500);
|
||||
|
||||
useEffect(() => {
|
||||
if (allowAppNamePropagation !== true) {
|
||||
return;
|
||||
}
|
||||
|
||||
const matchingDebouncedIcon = data
|
||||
?.flatMap((x) => x.entries)
|
||||
.find((x) => replaceCharacters(x.name.split('.')[0]) === replaceCharacters(debouncedValue));
|
||||
|
||||
if (!matchingDebouncedIcon) {
|
||||
return;
|
||||
}
|
||||
|
||||
form.setFieldValue('appearance.iconUrl', matchingDebouncedIcon.url);
|
||||
}, [debouncedValue]);
|
||||
|
||||
return (
|
||||
<Tabs.Panel value="appearance" pt="lg">
|
||||
<Flex gap={5}>
|
||||
<Autocomplete
|
||||
className={classes.textInput}
|
||||
icon={<DebouncedAppIcon form={form} width={20} height={20} />}
|
||||
label={t('appearance.icon.label')}
|
||||
description={t('appearance.icon.description')}
|
||||
variant="default"
|
||||
data={data?.files ?? []}
|
||||
withAsterisk
|
||||
required
|
||||
{...form.getInputProps('appearance.iconUrl')}
|
||||
/>
|
||||
<IconSelector
|
||||
onChange={(item) => {
|
||||
form.setValues({
|
||||
appearance: {
|
||||
iconUrl: item.url,
|
||||
},
|
||||
});
|
||||
disallowAppNameProgagation();
|
||||
}}
|
||||
allowAppNamePropagation={allowAppNamePropagation}
|
||||
form={form}
|
||||
data={data}
|
||||
isLoading={isLoading}
|
||||
allowAppNamePropagation={allowAppNamePropagation}
|
||||
disallowAppNameProgagation={disallowAppNameProgagation}
|
||||
/>
|
||||
</Flex>
|
||||
</Tabs.Panel>
|
||||
);
|
||||
};
|
||||
|
||||
const useStyles = createStyles(() => ({
|
||||
textInput: {
|
||||
flexGrow: 1,
|
||||
},
|
||||
}));
|
||||
const replaceCharacters = (value: string) => value.toLowerCase().replaceAll('', '-');
|
||||
|
||||
Reference in New Issue
Block a user