🎨 Rename "services" to "apps" in entire project

This commit is contained in:
Manuel Ruwe
2022-12-18 22:27:01 +01:00
parent 1e0a90f2ac
commit 661c05bc50
69 changed files with 661 additions and 495 deletions

View File

@@ -0,0 +1,6 @@
interface ServiceIconProps {
size: '100%' | number;
service: string;
}
export const AppIcon = ({ size }: ServiceIconProps) => null;

View File

@@ -0,0 +1,50 @@
import { openContextModalGeneric } from '../../../../tools/mantineModalManagerExtensions';
import { AppType } from '../../../../types/app';
import { GenericTileMenu } from '../GenericTileMenu';
interface TileMenuProps {
app: AppType;
}
export const AppMenu = ({ app }: TileMenuProps) => {
const handleClickEdit = () => {
openContextModalGeneric<{ app: AppType; allowAppNamePropagation: boolean }>({
modal: 'editApp',
size: 'xl',
innerProps: {
app,
allowAppNamePropagation: false,
},
styles: {
root: {
zIndex: 201,
},
},
});
};
const handleClickChangePosition = () => {
openContextModalGeneric({
modal: 'changeAppPositionModal',
innerProps: {
app,
},
styles: {
root: {
zIndex: 201,
},
},
});
};
const handleClickDelete = () => {};
return (
<GenericTileMenu
handleClickEdit={handleClickEdit}
handleClickChangePosition={handleClickChangePosition}
handleClickDelete={handleClickDelete}
displayEdit
/>
);
};

View File

@@ -0,0 +1,64 @@
import { Indicator, Tooltip } from '@mantine/core';
import { useQuery } from '@tanstack/react-query';
import { motion } from 'framer-motion';
import { useTranslation } from 'next-i18next';
import { useConfigContext } from '../../../../config/provider';
import { AppType } from '../../../../types/app';
interface AppPingProps {
app: AppType;
}
export const AppPing = ({ app }: AppPingProps) => {
const { t } = useTranslation('modules/ping');
const { config } = useConfigContext();
const active =
(config?.settings.customization.layout.enabledPing && app.network.enabledStatusChecker) ??
false;
const { data, isLoading } = useQuery({
queryKey: [`ping/${app.id}`],
queryFn: async () => {
const response = await fetch(`/api/modules/ping?url=${encodeURI(app.url)}`);
const isOk = app.network.okStatus.includes(response.status);
return {
status: response.status,
state: isOk ? 'online' : 'down',
};
},
enabled: active,
});
const isOnline = data?.state === 'online';
if (!active) return null;
return (
<motion.div
style={{ position: 'absolute', bottom: 20, right: 20 }}
animate={{
scale: isOnline ? [1, 0.7, 1] : 1,
}}
transition={{ repeat: Infinity, duration: 2.5, ease: 'easeInOut' }}
>
<Tooltip
withinPortal
radius="lg"
label={
isLoading
? t('states.loading')
: isOnline
? t('states.online', { response: data.status })
: t('states.offline', { response: data?.status })
}
>
<Indicator
size={15}
color={isLoading ? 'yellow' : isOnline ? 'green' : 'red'}
children={null}
/>
</Tooltip>
</motion.div>
);
};
type PingState = 'loading' | 'down' | 'online';

View File

@@ -0,0 +1,94 @@
import { Card, Center, Text, UnstyledButton } from '@mantine/core';
import { NextLink } from '@mantine/next';
import { createStyles } from '@mantine/styles';
import { AppType } from '../../../../types/app';
import { useCardStyles } from '../../../layout/useCardStyles';
import { useEditModeStore } from '../../Views/useEditModeStore';
import { HomarrCardWrapper } from '../HomarrCardWrapper';
import { BaseTileProps } from '../type';
import { AppMenu } from './AppMenu';
import { AppPing } from './AppPing';
interface AppTileProps extends BaseTileProps {
app: AppType;
}
export const AppTile = ({ className, app }: AppTileProps) => {
const isEditMode = useEditModeStore((x) => x.enabled);
const { cx, classes } = useStyles();
const {
classes: { card: cardClass },
} = useCardStyles();
const inner = (
<>
<Text align="center" weight={500} size="md" className={classes.appName}>
{app.name}
</Text>
<Center style={{ height: '75%', flex: 1 }}>
{/* eslint-disable-next-line @next/next/no-img-element */}
<img className={classes.image} src={app.appearance.iconUrl} alt="" />
</Center>
</>
);
return (
<HomarrCardWrapper className={className}>
{/* TODO: add app menu */}
<div style={{ position: 'absolute', top: 10, right: 10 }}>
<AppMenu app={app} />
</div>
{!app.url || isEditMode ? (
<UnstyledButton
className={classes.button}
style={{ pointerEvents: isEditMode ? 'none' : 'auto' }}
>
{inner}
</UnstyledButton>
) : (
<UnstyledButton
style={{ pointerEvents: isEditMode ? 'none' : 'auto' }}
component={NextLink}
href={app.url}
target={app.behaviour.isOpeningNewTab ? '_blank' : '_self'}
className={cx(classes.button, classes.link)}
>
{inner}
</UnstyledButton>
)}
<AppPing app={app} />
</HomarrCardWrapper>
);
};
const useStyles = createStyles((theme, _params, getRef) => ({
image: {
ref: getRef('image'),
maxHeight: '80%',
maxWidth: '80%',
transition: 'transform 100ms ease-in-out',
},
appName: {
ref: getRef('appName'),
},
button: {
height: '100%',
width: '100%',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
gap: 4,
},
link: {
[`&:hover .${getRef('image')}`]: {
// TODO: add styles for image when hovering card
},
[`&:hover .${getRef('appName')}`]: {
// TODO: add styles for app name when hovering card
},
},
}));