2022-12-04 21:19:40 +01:00
|
|
|
import { Group, Space, Stack, Text, UnstyledButton } from '@mantine/core';
|
2023-01-01 16:29:12 +01:00
|
|
|
import { closeModal } from '@mantine/modals';
|
2023-01-02 01:44:24 +09:00
|
|
|
import { showNotification } from '@mantine/notifications';
|
2023-05-15 17:40:59 +09:00
|
|
|
import { IconBox, IconBoxAlignTop, IconStack } from '@tabler/icons-react';
|
2023-01-02 02:52:12 +09:00
|
|
|
import { motion } from 'framer-motion';
|
2022-12-04 21:19:40 +01:00
|
|
|
import { useTranslation } from 'next-i18next';
|
|
|
|
|
import { ReactNode } from 'react';
|
|
|
|
|
import { v4 as uuidv4 } from 'uuid';
|
2023-07-21 18:08:40 +09:00
|
|
|
|
2022-12-24 11:11:51 +01:00
|
|
|
import { useConfigContext } from '../../../../../../config/provider';
|
2023-01-01 16:29:12 +01:00
|
|
|
import { useConfigStore } from '../../../../../../config/store';
|
2022-12-04 21:19:40 +01:00
|
|
|
import { openContextModalGeneric } from '../../../../../../tools/mantineModalManagerExtensions';
|
2022-12-18 22:27:01 +01:00
|
|
|
import { AppType } from '../../../../../../types/app';
|
2023-01-02 01:44:24 +09:00
|
|
|
import { CategoryEditModalInnerProps } from '../../../../Wrappers/Category/CategoryEditModal';
|
2022-12-04 21:19:40 +01:00
|
|
|
import { useStyles } from '../Shared/styles';
|
|
|
|
|
|
|
|
|
|
interface AvailableElementTypesProps {
|
2023-01-01 16:29:12 +01:00
|
|
|
modalId: string;
|
2022-12-04 21:19:40 +01:00
|
|
|
onOpenIntegrations: () => void;
|
|
|
|
|
onOpenStaticElements: () => void;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const AvailableElementTypes = ({
|
2023-01-01 16:29:12 +01:00
|
|
|
modalId,
|
2022-12-19 19:01:29 +01:00
|
|
|
onOpenIntegrations: onOpenWidgets,
|
2022-12-04 21:19:40 +01:00
|
|
|
onOpenStaticElements,
|
|
|
|
|
}: AvailableElementTypesProps) => {
|
|
|
|
|
const { t } = useTranslation('layout/element-selector/selector');
|
2023-01-01 16:29:12 +01:00
|
|
|
const { config, name: configName } = useConfigContext();
|
|
|
|
|
const { updateConfig } = useConfigStore();
|
2022-12-24 11:11:51 +01:00
|
|
|
const getLowestWrapper = () => config?.wrappers.sort((a, b) => a.position - b.position)[0];
|
2022-12-04 21:19:40 +01:00
|
|
|
|
2023-01-01 16:29:12 +01:00
|
|
|
const onClickCreateCategory = async () => {
|
2023-01-02 01:44:24 +09:00
|
|
|
openContextModalGeneric<CategoryEditModalInnerProps>({
|
|
|
|
|
modal: 'categoryEditModal',
|
|
|
|
|
title: 'Name of new category',
|
|
|
|
|
withCloseButton: false,
|
|
|
|
|
innerProps: {
|
|
|
|
|
category: {
|
|
|
|
|
id: uuidv4(),
|
|
|
|
|
name: 'New category',
|
2023-01-10 22:36:26 +01:00
|
|
|
position: 0, // doesn't matter, is being overwritten
|
2023-01-02 01:44:24 +09:00
|
|
|
},
|
|
|
|
|
onSuccess: async (category) => {
|
|
|
|
|
if (!configName) return;
|
2023-01-01 16:29:12 +01:00
|
|
|
|
2023-01-02 01:44:24 +09:00
|
|
|
await updateConfig(configName, (previousConfig) => ({
|
|
|
|
|
...previousConfig,
|
2023-01-10 22:36:26 +01:00
|
|
|
wrappers: [
|
|
|
|
|
...previousConfig.wrappers,
|
|
|
|
|
{
|
|
|
|
|
id: uuidv4(),
|
|
|
|
|
// Thank you ChatGPT ;)
|
2023-01-23 20:35:59 +01:00
|
|
|
position: previousConfig.categories.length + 1,
|
2023-01-10 22:36:26 +01:00
|
|
|
},
|
|
|
|
|
],
|
2023-01-02 01:44:24 +09:00
|
|
|
categories: [
|
|
|
|
|
...previousConfig.categories,
|
2023-01-01 16:29:12 +01:00
|
|
|
{
|
|
|
|
|
id: uuidv4(),
|
2023-01-02 01:44:24 +09:00
|
|
|
name: category.name,
|
2023-01-10 22:36:26 +01:00
|
|
|
position: previousConfig.categories.length + 1,
|
2023-01-01 16:29:12 +01:00
|
|
|
},
|
2023-01-02 01:44:24 +09:00
|
|
|
],
|
|
|
|
|
})).then(() => {
|
|
|
|
|
closeModal(modalId);
|
|
|
|
|
showNotification({
|
|
|
|
|
title: 'Category created',
|
|
|
|
|
message: `The category ${category.name} has been created`,
|
|
|
|
|
color: 'teal',
|
|
|
|
|
});
|
|
|
|
|
});
|
2023-01-01 16:29:12 +01:00
|
|
|
},
|
2023-01-02 01:44:24 +09:00
|
|
|
},
|
|
|
|
|
});
|
2023-01-01 16:29:12 +01:00
|
|
|
};
|
|
|
|
|
|
2022-12-04 21:19:40 +01:00
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
|
<Text color="dimmed">{t('modal.text')}</Text>
|
|
|
|
|
<Space h="lg" />
|
|
|
|
|
<Group spacing="md" grow>
|
|
|
|
|
<ElementItem
|
2022-12-18 22:27:01 +01:00
|
|
|
name="Apps"
|
2022-12-04 21:19:40 +01:00
|
|
|
icon={<IconBox size={40} strokeWidth={1.3} />}
|
|
|
|
|
onClick={() => {
|
2022-12-19 19:01:29 +01:00
|
|
|
openContextModalGeneric<{ app: AppType; allowAppNamePropagation: boolean }>({
|
|
|
|
|
modal: 'editApp',
|
|
|
|
|
innerProps: {
|
|
|
|
|
app: {
|
|
|
|
|
id: uuidv4(),
|
|
|
|
|
name: 'Your app',
|
|
|
|
|
url: 'https://homarr.dev',
|
|
|
|
|
appearance: {
|
|
|
|
|
iconUrl: '/imgs/logo/logo.png',
|
|
|
|
|
},
|
|
|
|
|
network: {
|
2023-01-04 21:51:25 +09:00
|
|
|
enabledStatusChecker: true,
|
2023-05-21 15:23:43 +02:00
|
|
|
statusCodes: ['200', '301', '302', '304', '307', '308'],
|
|
|
|
|
okStatus: [200, 301, 302, 304, 307, 308],
|
2022-12-19 19:01:29 +01:00
|
|
|
},
|
|
|
|
|
behaviour: {
|
|
|
|
|
isOpeningNewTab: true,
|
2022-12-22 11:29:51 +09:00
|
|
|
externalUrl: '',
|
2022-12-19 19:01:29 +01:00
|
|
|
},
|
2022-12-24 11:11:51 +01:00
|
|
|
|
2022-12-19 19:01:29 +01:00
|
|
|
area: {
|
2022-12-24 11:11:51 +01:00
|
|
|
type: 'wrapper',
|
2022-12-19 19:01:29 +01:00
|
|
|
properties: {
|
2022-12-31 18:10:01 +01:00
|
|
|
id: getLowestWrapper()?.id ?? 'default',
|
2022-12-04 22:02:10 +01:00
|
|
|
},
|
2022-12-19 19:01:29 +01:00
|
|
|
},
|
2023-01-07 23:25:13 +01:00
|
|
|
shape: {},
|
2022-12-19 19:01:29 +01:00
|
|
|
integration: {
|
|
|
|
|
type: null,
|
|
|
|
|
properties: [],
|
|
|
|
|
},
|
2022-12-04 21:19:40 +01:00
|
|
|
},
|
2022-12-19 19:01:29 +01:00
|
|
|
allowAppNamePropagation: true,
|
|
|
|
|
},
|
|
|
|
|
size: 'xl',
|
|
|
|
|
});
|
2022-12-04 21:19:40 +01:00
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
<ElementItem
|
2022-12-19 19:01:29 +01:00
|
|
|
name="Widgets"
|
|
|
|
|
icon={<IconStack size={40} strokeWidth={1.3} />}
|
|
|
|
|
onClick={onOpenWidgets}
|
2022-12-04 21:19:40 +01:00
|
|
|
/>
|
2023-01-01 16:29:12 +01:00
|
|
|
<ElementItem
|
|
|
|
|
name="Category"
|
|
|
|
|
icon={<IconBoxAlignTop size={40} strokeWidth={1.3} />}
|
|
|
|
|
onClick={onClickCreateCategory}
|
|
|
|
|
/>
|
2022-12-04 21:19:40 +01:00
|
|
|
</Group>
|
|
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
interface ElementItemProps {
|
|
|
|
|
icon: ReactNode;
|
|
|
|
|
name: string;
|
|
|
|
|
onClick: () => void;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const ElementItem = ({ name, icon, onClick }: ElementItemProps) => {
|
|
|
|
|
const { classes, cx } = useStyles();
|
|
|
|
|
return (
|
|
|
|
|
<UnstyledButton
|
|
|
|
|
className={cx(classes.elementButton, classes.styledButton)}
|
|
|
|
|
onClick={onClick}
|
|
|
|
|
py="md"
|
|
|
|
|
>
|
|
|
|
|
<Stack className={classes.elementStack} align="center" spacing={5}>
|
2023-01-02 02:52:12 +09:00
|
|
|
<motion.div
|
|
|
|
|
// On hover zoom in
|
|
|
|
|
whileHover={{ scale: 1.2 }}
|
|
|
|
|
>
|
|
|
|
|
{icon}
|
|
|
|
|
</motion.div>
|
2022-12-04 21:19:40 +01:00
|
|
|
<Text className={classes.elementName} weight={500} size="sm">
|
|
|
|
|
{name}
|
|
|
|
|
</Text>
|
|
|
|
|
</Stack>
|
|
|
|
|
</UnstyledButton>
|
|
|
|
|
);
|
|
|
|
|
};
|