mirror of
https://github.com/ajnart/homarr.git
synced 2025-11-10 07:25:48 +01:00
✨App tile UI change (#1231)
* 💄 Rework the App tile UI * 🤡 Forgot one * Make it so the app title gets hidden properly Now if the value is missing it won't by "hover" or "hidden" so it won't hide * Turn the `Tooltip` into `HoverCard` * Make save and cancel button not wrap anymore * 💄 Used InfoCard in options + translations * ♻️ Remove fallback value for label translations --------- Co-authored-by: Thomas Camlong <49837342+ajnart@users.noreply.github.com> Co-authored-by: Meier Lukas <meierschlumpf@gmail.com>
This commit is contained in:
@@ -25,6 +25,10 @@
|
|||||||
"label": "Open in new tab",
|
"label": "Open in new tab",
|
||||||
"description": "Open the app in a new tab instead of the current one."
|
"description": "Open the app in a new tab instead of the current one."
|
||||||
},
|
},
|
||||||
|
"tooltipDescription":{
|
||||||
|
"label": "Application Description",
|
||||||
|
"description": "The text you enter will appear when hovering over your app.\r\nUse this to give users more details about your app or leave empty to have nothing."
|
||||||
|
},
|
||||||
"customProtocolWarning": "Using a non-standard protocol. This may require pre-installed applications and can introduce security risks. Ensure that your address is secure and trusted."
|
"customProtocolWarning": "Using a non-standard protocol. This may require pre-installed applications and can introduce security risks. Ensure that your address is secure and trusted."
|
||||||
},
|
},
|
||||||
"network": {
|
"network": {
|
||||||
@@ -49,6 +53,25 @@
|
|||||||
"title": "Loading external icons",
|
"title": "Loading external icons",
|
||||||
"text": "This may take a few seconds"
|
"text": "This may take a few seconds"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"appNameStatus":{
|
||||||
|
"label":"App Name Status",
|
||||||
|
"description":"Choose where you want the title to show up, if at all.",
|
||||||
|
"dropdown": {
|
||||||
|
"normal":"Show title on tile only",
|
||||||
|
"hover":"Show title on tooltip hover only",
|
||||||
|
"hidden":"Don't show at all"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"positionAppName":{
|
||||||
|
"label":"App Name Position",
|
||||||
|
"description":"Position of the app's name relative to the icon.",
|
||||||
|
"dropdown": {
|
||||||
|
"top":"Top",
|
||||||
|
"right":"Right",
|
||||||
|
"bottom":"Bottom",
|
||||||
|
"left":"Left"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"integration": {
|
"integration": {
|
||||||
|
|||||||
@@ -211,7 +211,7 @@ export const EditAppModal = ({
|
|||||||
<IntegrationTab form={form} />
|
<IntegrationTab form={form} />
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
<Group position="right" mt="md">
|
<Group noWrap position="right" mt="md">
|
||||||
<Button onClick={closeModal} px={50} variant="light" color="gray">
|
<Button onClick={closeModal} px={50} variant="light" color="gray">
|
||||||
{t('common:cancel')}
|
{t('common:cancel')}
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Flex, Tabs } from '@mantine/core';
|
import { Flex, Select, Stack, Switch, Tabs } from '@mantine/core';
|
||||||
import { UseFormReturnType } from '@mantine/form';
|
import { UseFormReturnType } from '@mantine/form';
|
||||||
import { useDebouncedValue } from '@mantine/hooks';
|
import { useDebouncedValue } from '@mantine/hooks';
|
||||||
|
import { useTranslation } from 'next-i18next';
|
||||||
import { useEffect, useRef } from 'react';
|
import { useEffect, useRef } from 'react';
|
||||||
|
|
||||||
import { AppType } from '../../../../../../types/app';
|
import { AppType } from '../../../../../../types/app';
|
||||||
@@ -19,6 +20,7 @@ export const AppearanceTab = ({
|
|||||||
}: AppearanceTabProps) => {
|
}: AppearanceTabProps) => {
|
||||||
const iconSelectorRef = useRef();
|
const iconSelectorRef = useRef();
|
||||||
const [debouncedValue] = useDebouncedValue(form.values.name, 500);
|
const [debouncedValue] = useDebouncedValue(form.values.name, 500);
|
||||||
|
const { t } = useTranslation('layout/modals/add-app');
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (allowAppNamePropagation !== true) {
|
if (allowAppNamePropagation !== true) {
|
||||||
@@ -38,17 +40,54 @@ export const AppearanceTab = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Tabs.Panel value="appearance" pt="lg">
|
<Tabs.Panel value="appearance" pt="lg">
|
||||||
<Flex gap={5}>
|
<Stack spacing="xs">
|
||||||
<IconSelector
|
<Flex gap={5} mb="xs">
|
||||||
defaultValue={form.values.appearance.iconUrl}
|
<IconSelector
|
||||||
|
defaultValue={form.values.appearance.iconUrl}
|
||||||
|
onChange={(value) => {
|
||||||
|
form.setFieldValue('appearance.iconUrl', value);
|
||||||
|
disallowAppNameProgagation();
|
||||||
|
}}
|
||||||
|
value={form.values.appearance.iconUrl}
|
||||||
|
ref={iconSelectorRef}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
<Select
|
||||||
|
label={t('appearance.appNameStatus.label')}
|
||||||
|
description={t('appearance.appNameStatus.description')}
|
||||||
|
data={[
|
||||||
|
{ value: 'normal', label: t('appearance.appNameStatus.dropdown.normal') as string },
|
||||||
|
{ value: 'hover', label: t('appearance.appNameStatus.dropdown.hover') as string },
|
||||||
|
{ value: 'hidden', label: t('appearance.appNameStatus.dropdown.hidden') as string },
|
||||||
|
]}
|
||||||
|
{...form.getInputProps('appearance.appNameStatus')}
|
||||||
onChange={(value) => {
|
onChange={(value) => {
|
||||||
form.setFieldValue('appearance.iconUrl', value);
|
form.setFieldValue('appearance.appNameStatus', value);
|
||||||
disallowAppNameProgagation();
|
|
||||||
}}
|
}}
|
||||||
value={form.values.appearance.iconUrl}
|
|
||||||
ref={iconSelectorRef}
|
|
||||||
/>
|
/>
|
||||||
</Flex>
|
{form.values.appearance.appNameStatus === 'normal' && (
|
||||||
|
<Select
|
||||||
|
label={t('appearance.positionAppName.label')}
|
||||||
|
description={t('appearance.positionAppName.description')}
|
||||||
|
data={[
|
||||||
|
{ value: 'column', label: t('appearance.positionAppName.dropdown.top') as string },
|
||||||
|
{
|
||||||
|
value: 'row-reverse',
|
||||||
|
label: t('appearance.positionAppName.dropdown.right') as string,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'column-reverse',
|
||||||
|
label: t('appearance.positionAppName.dropdown.bottom') as string,
|
||||||
|
},
|
||||||
|
{ value: 'row', label: t('appearance.positionAppName.dropdown.left') as string },
|
||||||
|
]}
|
||||||
|
{...form.getInputProps('appearance.positionAppName')}
|
||||||
|
onChange={(value) => {
|
||||||
|
form.setFieldValue('appearance.positionAppName', value);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Stack>
|
||||||
</Tabs.Panel>
|
</Tabs.Panel>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { Switch, Tabs } from '@mantine/core';
|
import { Text, TextInput, Tooltip, Stack, Switch, Tabs, Group, useMantineTheme, HoverCard } from '@mantine/core';
|
||||||
import { UseFormReturnType } from '@mantine/form';
|
import { UseFormReturnType } from '@mantine/form';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
|
|
||||||
import { AppType } from '../../../../../../types/app';
|
import { AppType } from '../../../../../../types/app';
|
||||||
|
import { InfoCard } from '~/components/InfoCard/InfoCard'
|
||||||
|
|
||||||
interface BehaviourTabProps {
|
interface BehaviourTabProps {
|
||||||
form: UseFormReturnType<AppType, (values: AppType) => AppType>;
|
form: UseFormReturnType<AppType, (values: AppType) => AppType>;
|
||||||
@@ -10,14 +11,29 @@ interface BehaviourTabProps {
|
|||||||
|
|
||||||
export const BehaviourTab = ({ form }: BehaviourTabProps) => {
|
export const BehaviourTab = ({ form }: BehaviourTabProps) => {
|
||||||
const { t } = useTranslation('layout/modals/add-app');
|
const { t } = useTranslation('layout/modals/add-app');
|
||||||
|
const { primaryColor } = useMantineTheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tabs.Panel value="behaviour" pt="xs">
|
<Tabs.Panel value="behaviour" pt="xs">
|
||||||
<Switch
|
<Stack spacing="xs">
|
||||||
label={t('behaviour.isOpeningNewTab.label')}
|
<Switch
|
||||||
description={t('behaviour.isOpeningNewTab.description')}
|
label={t('behaviour.isOpeningNewTab.label')}
|
||||||
{...form.getInputProps('behaviour.isOpeningNewTab', { type: 'checkbox' })}
|
description={t('behaviour.isOpeningNewTab.description')}
|
||||||
/>
|
styles={{ label: { fontWeight: 500, }, description: { marginTop: 0, }, }}
|
||||||
|
{...form.getInputProps('behaviour.isOpeningNewTab', { type: 'checkbox' })}
|
||||||
|
/>
|
||||||
|
<Stack spacing="0.25rem">
|
||||||
|
<Group>
|
||||||
|
<Text size="0.875rem" weight={500}>
|
||||||
|
{t('behaviour.tooltipDescription.label')}
|
||||||
|
</Text>
|
||||||
|
<InfoCard message={t('behaviour.tooltipDescription.description')}/>
|
||||||
|
</Group>
|
||||||
|
<TextInput
|
||||||
|
{...form.getInputProps('behaviour.tooltipDescription')}
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
</Stack>
|
||||||
</Tabs.Panel>
|
</Tabs.Panel>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Tabs, Text, TextInput } from '@mantine/core';
|
import { Stack, Tabs, Text, TextInput } from '@mantine/core';
|
||||||
import { UseFormReturnType } from '@mantine/form';
|
import { UseFormReturnType } from '@mantine/form';
|
||||||
import { IconClick, IconCursorText, IconLink } from '@tabler/icons-react';
|
import { IconClick, IconCursorText, IconLink } from '@tabler/icons-react';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
@@ -15,41 +15,44 @@ export const GeneralTab = ({ form, openTab }: GeneralTabProps) => {
|
|||||||
const { t } = useTranslation('layout/modals/add-app');
|
const { t } = useTranslation('layout/modals/add-app');
|
||||||
return (
|
return (
|
||||||
<Tabs.Panel value="general" pt="sm">
|
<Tabs.Panel value="general" pt="sm">
|
||||||
<TextInput
|
<Stack spacing="xs">
|
||||||
icon={<IconCursorText size={16} />}
|
<TextInput
|
||||||
label={t('general.appname.label')}
|
icon={<IconCursorText size={16} />}
|
||||||
description={t('general.appname.description')}
|
label={t('general.appname.label')}
|
||||||
placeholder="My example app"
|
description={t('general.appname.description')}
|
||||||
variant="default"
|
placeholder="My example app"
|
||||||
withAsterisk
|
variant="default"
|
||||||
mb="md"
|
withAsterisk
|
||||||
{...form.getInputProps('name')}
|
{...form.getInputProps('name')}
|
||||||
/>
|
/>
|
||||||
<TextInput
|
<TextInput
|
||||||
icon={<IconLink size={16} />}
|
icon={<IconLink size={16} />}
|
||||||
label={t('general.internalAddress.label')}
|
label={t('general.internalAddress.label')}
|
||||||
description={t('general.internalAddress.description')}
|
description={t('general.internalAddress.description')}
|
||||||
placeholder="https://google.com"
|
placeholder="https://google.com"
|
||||||
variant="default"
|
variant="default"
|
||||||
withAsterisk
|
withAsterisk
|
||||||
mb="md"
|
{...form.getInputProps('url')}
|
||||||
{...form.getInputProps('url')}
|
onChange={(e) => {
|
||||||
/>
|
form.setFieldValue('url', e.target.value);
|
||||||
<TextInput
|
}}
|
||||||
icon={<IconClick size={16} />}
|
/>
|
||||||
label={t('general.externalAddress.label')}
|
<TextInput
|
||||||
description={t('general.externalAddress.description')}
|
icon={<IconClick size={16} />}
|
||||||
placeholder="https://homarr.mywebsite.com/"
|
label={t('general.externalAddress.label')}
|
||||||
variant="default"
|
description={t('general.externalAddress.description')}
|
||||||
{...form.getInputProps('behaviour.externalUrl')}
|
placeholder="https://homarr.mywebsite.com/"
|
||||||
/>
|
variant="default"
|
||||||
|
{...form.getInputProps('behaviour.externalUrl')}
|
||||||
|
/>
|
||||||
|
|
||||||
{!form.values.behaviour.externalUrl.startsWith('https://') &&
|
{!form.values.behaviour.externalUrl.startsWith('https://') &&
|
||||||
!form.values.behaviour.externalUrl.startsWith('http://') && (
|
!form.values.behaviour.externalUrl.startsWith('http://') && (
|
||||||
<Text color="red" mt="sm" size="sm">
|
<Text color="red" mt="sm" size="sm">
|
||||||
{t('behaviour.customProtocolWarning')}
|
{t('behaviour.customProtocolWarning')}
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
|
</Stack>
|
||||||
</Tabs.Panel>
|
</Tabs.Panel>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { MultiSelect, Switch, Tabs } from '@mantine/core';
|
import { MultiSelect, Stack, Switch, Tabs } from '@mantine/core';
|
||||||
import { UseFormReturnType } from '@mantine/form';
|
import { UseFormReturnType } from '@mantine/form';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
|
|
||||||
@@ -16,26 +16,28 @@ export const NetworkTab = ({ form }: NetworkTabProps) => {
|
|||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<Tabs.Panel value="network" pt="lg">
|
<Tabs.Panel value="network" pt="lg">
|
||||||
<Switch
|
<Stack spacing="xs">
|
||||||
label={t('network.statusChecker.label')}
|
<Switch
|
||||||
description={t('network.statusChecker.description')}
|
label={t('network.statusChecker.label')}
|
||||||
mb="md"
|
description={t('network.statusChecker.description')}
|
||||||
defaultChecked={form.values.network.enabledStatusChecker}
|
styles={{ label: { fontWeight: 500, }, description: { marginTop: 0, }, }}
|
||||||
{...form.getInputProps('network.enabledStatusChecker')}
|
defaultChecked={form.values.network.enabledStatusChecker}
|
||||||
/>
|
{...form.getInputProps('network.enabledStatusChecker')}
|
||||||
{form.values.network.enabledStatusChecker && (
|
|
||||||
<MultiSelect
|
|
||||||
required
|
|
||||||
label={t('network.statusCodes.label')}
|
|
||||||
description={t('network.statusCodes.description')}
|
|
||||||
data={StatusCodes}
|
|
||||||
clearable
|
|
||||||
searchable
|
|
||||||
defaultValue={acceptableStatusCodes}
|
|
||||||
variant="default"
|
|
||||||
{...form.getInputProps('network.statusCodes')}
|
|
||||||
/>
|
/>
|
||||||
)}
|
{form.values.network.enabledStatusChecker && (
|
||||||
|
<MultiSelect
|
||||||
|
required
|
||||||
|
label={t('network.statusCodes.label')}
|
||||||
|
description={t('network.statusCodes.description')}
|
||||||
|
data={StatusCodes}
|
||||||
|
clearable
|
||||||
|
searchable
|
||||||
|
defaultValue={acceptableStatusCodes}
|
||||||
|
variant="default"
|
||||||
|
{...form.getInputProps('network.statusCodes')}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Stack>
|
||||||
</Tabs.Panel>
|
</Tabs.Panel>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -93,6 +93,8 @@ export const AvailableElementTypes = ({
|
|||||||
url: 'https://homarr.dev',
|
url: 'https://homarr.dev',
|
||||||
appearance: {
|
appearance: {
|
||||||
iconUrl: '/imgs/logo/logo.png',
|
iconUrl: '/imgs/logo/logo.png',
|
||||||
|
appNameStatus: 'normal',
|
||||||
|
positionAppName: 'column',
|
||||||
},
|
},
|
||||||
network: {
|
network: {
|
||||||
enabledStatusChecker: true,
|
enabledStatusChecker: true,
|
||||||
@@ -164,4 +166,4 @@ const ElementItem = ({ name, icon, onClick }: ElementItemProps) => {
|
|||||||
</Stack>
|
</Stack>
|
||||||
</UnstyledButton>
|
</UnstyledButton>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Box, Stack, Title, UnstyledButton } from '@mantine/core';
|
import { Box, Flex, Text, Tooltip, UnstyledButton } from '@mantine/core';
|
||||||
import { createStyles } from '@mantine/styles';
|
import { createStyles, useMantineTheme } from '@mantine/styles';
|
||||||
import { motion } from 'framer-motion';
|
import { motion } from 'framer-motion';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
|
||||||
@@ -20,49 +20,76 @@ export const AppTile = ({ className, app }: AppTileProps) => {
|
|||||||
|
|
||||||
const { cx, classes } = useStyles();
|
const { cx, classes } = useStyles();
|
||||||
|
|
||||||
|
const { colorScheme } = useMantineTheme();
|
||||||
|
|
||||||
|
const tooltipContent = [
|
||||||
|
app.appearance.appNameStatus === "hover" ? app.name : undefined,
|
||||||
|
app.behaviour.tooltipDescription
|
||||||
|
].filter( e => e ).join( ': ' );
|
||||||
|
|
||||||
const {
|
const {
|
||||||
classes: { card: cardClass },
|
classes: { card: cardClass },
|
||||||
} = useCardStyles(false);
|
} = useCardStyles(false);
|
||||||
|
|
||||||
function Inner() {
|
function Inner() {
|
||||||
return (
|
return (
|
||||||
<>
|
<Tooltip.Floating
|
||||||
<Stack
|
label={tooltipContent}
|
||||||
|
position="right-start"
|
||||||
|
c={ colorScheme === 'light' ? "black" : "dark.0" }
|
||||||
|
color={ colorScheme === 'light' ? "gray.2" : "dark.4" }
|
||||||
|
multiline
|
||||||
|
disabled={tooltipContent === ''}
|
||||||
|
styles={{ tooltip: { '&': { maxWidth: 300, }, }, }}
|
||||||
|
>
|
||||||
|
<Flex
|
||||||
m={0}
|
m={0}
|
||||||
p={0}
|
p={0}
|
||||||
spacing="xs"
|
|
||||||
justify="space-around"
|
justify="space-around"
|
||||||
align="center"
|
align="center"
|
||||||
style={{ height: '100%', width: '100%' }}
|
h="100%"
|
||||||
|
w="100%"
|
||||||
className="dashboard-tile-app"
|
className="dashboard-tile-app"
|
||||||
|
direction={app.appearance.positionAppName ?? 'column'}
|
||||||
>
|
>
|
||||||
<Box hidden={false}>
|
<Box px={10} hidden={["hover", "hidden"].includes(app.appearance.appNameStatus)}>
|
||||||
<Title
|
<Text
|
||||||
order={5}
|
w="max-content"
|
||||||
size="md"
|
size="md"
|
||||||
ta="center"
|
ta="center"
|
||||||
lineClamp={1}
|
weight={700}
|
||||||
className={cx(classes.appName, 'dashboard-tile-app-title')}
|
className={cx(classes.appName, 'dashboard-tile-app-title')}
|
||||||
>
|
>
|
||||||
{app.name}
|
{app.name}
|
||||||
</Title>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
<motion.img
|
<Box
|
||||||
className={classes.image}
|
w="100%"
|
||||||
height="85%"
|
h="100%"
|
||||||
width="85%"
|
display="flex"
|
||||||
style={{
|
sx={{
|
||||||
objectFit: 'contain',
|
alignContent: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
flex: '1 1 auto',
|
||||||
|
flexWrap: 'wrap',
|
||||||
}}
|
}}
|
||||||
src={app.appearance.iconUrl}
|
>
|
||||||
alt={app.name}
|
<motion.img
|
||||||
whileHover={{
|
className={classes.image}
|
||||||
scale: 1.2,
|
height="85%"
|
||||||
transition: { duration: 0.2 },
|
style={{
|
||||||
}}
|
objectFit: 'contain',
|
||||||
/>
|
}}
|
||||||
</Stack>
|
src={app.appearance.iconUrl}
|
||||||
</>
|
alt={app.name}
|
||||||
|
whileHover={{
|
||||||
|
scale: 1.2,
|
||||||
|
transition: { duration: 0.2 },
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</Flex>
|
||||||
|
</Tooltip.Floating>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,7 +128,6 @@ const useStyles = createStyles((theme, _params, getRef) => ({
|
|||||||
wordBreak: 'break-word',
|
wordBreak: 'break-word',
|
||||||
},
|
},
|
||||||
button: {
|
button: {
|
||||||
paddingBottom: 10,
|
|
||||||
height: '100%',
|
height: '100%',
|
||||||
width: '100%',
|
width: '100%',
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
|
|||||||
@@ -129,6 +129,8 @@ export default function ContainerActionBar({ selected, reload }: ContainerAction
|
|||||||
url: address,
|
url: address,
|
||||||
appearance: {
|
appearance: {
|
||||||
iconUrl: '/imgs/logo/logo.png',
|
iconUrl: '/imgs/logo/logo.png',
|
||||||
|
appNameStatus: 'normal',
|
||||||
|
positionAppName: 'column'
|
||||||
},
|
},
|
||||||
network: {
|
network: {
|
||||||
enabledStatusChecker: true,
|
enabledStatusChecker: true,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { Icon, IconKey, IconPassword, IconUser } from '@tabler/icons-react';
|
import { Icon, IconKey, IconPassword, IconUser } from '@tabler/icons-react';
|
||||||
|
import { Property } from 'csstype'
|
||||||
|
|
||||||
import { TileBaseType } from './tile';
|
import { TileBaseType } from './tile';
|
||||||
|
|
||||||
@@ -19,6 +20,7 @@ export type ConfigAppType = Omit<AppType, 'integration'> & {
|
|||||||
interface AppBehaviourType {
|
interface AppBehaviourType {
|
||||||
externalUrl: string;
|
externalUrl: string;
|
||||||
isOpeningNewTab: boolean;
|
isOpeningNewTab: boolean;
|
||||||
|
tooltipDescription?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface AppNetworkType {
|
interface AppNetworkType {
|
||||||
@@ -32,6 +34,8 @@ interface AppNetworkType {
|
|||||||
|
|
||||||
interface AppAppearanceType {
|
interface AppAppearanceType {
|
||||||
iconUrl: string;
|
iconUrl: string;
|
||||||
|
appNameStatus: "normal"|"hover"|"hidden";
|
||||||
|
positionAppName: Property.FlexDirection;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type IntegrationType =
|
export type IntegrationType =
|
||||||
|
|||||||
Reference in New Issue
Block a user