Merge branch 'dev' into feature/dashdot-consistency-changes

This commit is contained in:
Thomas Camlong
2023-02-14 10:53:46 +09:00
committed by GitHub
157 changed files with 3054 additions and 1772 deletions

View File

@@ -33,9 +33,10 @@ export const AppTile = ({ className, app }: AppTileProps) => {
justify="space-around"
align="center"
style={{ height: '100%', width: '100%' }}
className="dashboard-tile-app"
>
<Box hidden={false}>
<Title order={5} size="md" ta="center" lineClamp={1} className={classes.appName}>
<Title order={5} size="md" ta="center" lineClamp={1} className={cx(classes.appName, 'dashboard-tile-app-title')}>
{app.name}
</Title>
</Box>

View File

@@ -18,7 +18,7 @@ export const HomarrCardWrapper = ({ ...props }: HomarrCardWrapperProps) => {
return (
<Card
{...restProps}
className={cx(restProps.className, cardClass)}
className={cx(restProps.className, cardClass, 'dashboard-gs-generic-item')}
withBorder
style={{ cursor: isEditMode ? 'move' : 'default' }}
radius="lg"

View File

@@ -1,4 +1,4 @@
import create from 'zustand';
import { create } from 'zustand';
interface EditModeState {
enabled: boolean;

View File

@@ -16,7 +16,7 @@ export const DashboardCategory = ({ category }: DashboardCategoryProps) => {
const { refs, apps, widgets } = useGridstack('category', category.id);
const isEditMode = useEditModeStore((x) => x.enabled);
const { config } = useConfigContext();
const { classes: cardClasses } = useCardStyles(true);
const { classes: cardClasses, cx } = useCardStyles(true);
const categoryList = config?.categories.map((x) => x.name) ?? [];
const [toggledCategories, setToggledCategories] = useLocalStorage({
@@ -28,7 +28,7 @@ export const DashboardCategory = ({ category }: DashboardCategoryProps) => {
return (
<Accordion
classNames={{
item: cardClasses.card,
item: cx(cardClasses.card, 'dashboard-gs-category'),
}}
mx={10}
chevronPosition="left"

View File

@@ -1,5 +1,5 @@
import { useMantineTheme } from '@mantine/core';
import create from 'zustand';
import { create } from 'zustand';
import { useConfigContext } from '../../../../config/provider';
import { GridstackBreakpoints } from '../../../../constants/gridstack-breakpoints';

View File

@@ -1,6 +1,6 @@
import { Accordion, Grid, Group, Stack, Text } from '@mantine/core';
import { IconBrush, IconChartCandle, IconDragDrop, IconLayout } from '@tabler/icons';
import { useTranslation } from 'next-i18next';
import { Accordion, Checkbox, Grid, Group, Stack, Switch, Text } from '@mantine/core';
import { IconBrush, IconChartCandle, IconCode, IconDragDrop, IconLayout } from '@tabler/icons';
import { i18n, useTranslation } from 'next-i18next';
import { ReactNode } from 'react';
import { GridstackConfiguration } from './Layout/GridstackConfiguration';
import { LayoutSelector } from './Layout/LayoutSelector';
@@ -55,7 +55,7 @@ const getItems = () => {
'settings/customization/general',
'settings/customization/color-selector',
]);
return [
const items = [
{
id: 'layout',
image: <IconLayout />,
@@ -114,4 +114,26 @@ const getItems = () => {
),
},
];
if (process.env.NODE_ENV === 'development') {
items.push({
id: 'dev',
image: <IconCode />,
label: 'Developer options',
description: 'Options to help when developing',
content: (
<Stack>
<Checkbox
label="Use debug language"
defaultChecked={i18n?.language === 'cimode'}
description="This will show the translation keys instead of the actual translations"
onChange={(e) =>
// Change to CI mode language
i18n?.changeLanguage(e.target.checked ? 'cimode' : 'en')
}
/>
</Stack>
),
});
}
return items;
};

View File

@@ -1,24 +1,13 @@
import {
Box,
createStyles,
Group,
Loader,
ScrollArea,
Stack,
Text,
useMantineTheme,
} from '@mantine/core';
import { Box, createStyles, Group, Loader, Stack, Text, useMantineTheme } from '@mantine/core';
import { useDebouncedValue } from '@mantine/hooks';
import { useTranslation } from 'next-i18next';
import dynamic from 'next/dynamic';
import { ChangeEvent, useEffect, useState } from 'react';
import { useEffect, useState } from 'react';
import Editor from 'react-simple-code-editor';
import { highlight, languages } from 'prismjs';
import { useConfigContext } from '../../../../config/provider';
import { useConfigStore } from '../../../../config/store';
const CodeEditor = dynamic(
() => import('@uiw/react-textarea-code-editor').then((mod) => mod.default),
{ ssr: false }
);
import 'prismjs/components/prism-css';
import 'prismjs/themes/prism.css';
export const CustomCssChanger = () => {
const { t } = useTranslation('settings/customization/page-appearance');
@@ -53,22 +42,20 @@ export const CustomCssChanger = () => {
<Stack spacing={4} mt="xl">
<Text>{t('customCSS.label')}</Text>
<Text color="dimmed" size="xs">
{t('customCSS.description')}
{t('customCSS.description')}
</Text>
<div className={classes.codeEditorRoot}>
<ScrollArea style={{ height: codeEditorHeight }}>
<CodeEditor
className={classes.codeEditor}
placeholder={t('customCSS.placeholder')}
value={nonDebouncedCustomCSS}
onChange={(event: ChangeEvent<HTMLTextAreaElement>) =>
setNonDebouncedCustomCSS(event.target.value.trim())
}
language="css"
data-color-mode={colorScheme}
minHeight={codeEditorHeight}
/>
</ScrollArea>
<Editor
value={nonDebouncedCustomCSS}
onValueChange={(code) => setNonDebouncedCustomCSS(code)}
highlight={(code) => highlight(code, languages.extend('css', {}), 'css')}
padding={10}
style={{
fontFamily: '"Fira code", "Fira Mono", monospace',
fontSize: 12,
minHeight: codeEditorHeight,
}}
/>
{codeIsDirty && (
<Box className={classes.codeEditorFooter}>
<Group p="xs" spacing="xs">

View File

@@ -19,6 +19,7 @@ export default function Layout({ children }: any) {
minHeight: 'calc(100vh - var(--mantine-header-height))',
},
}}
className="dashboard-app-shell"
>
<Head />
<Background />

View File

@@ -17,12 +17,14 @@ export function Logo({ size = 'md', withoutText = false }: LogoProps) {
width={size === 'md' ? 50 : 12}
src={config?.settings.customization.logoImageUrl || '/imgs/logo/logo-color.svg'}
alt="Homarr Logo"
className="dashboard-header-logo-image"
/>
{withoutText ? null : (
<Text
size={size === 'md' ? 22 : 10}
weight="bold"
variant="gradient"
className="dashboard-header-logo-text"
gradient={primaryGradient}
>
{config?.settings.customization.pageTitle || 'Homarr'}

View File

@@ -13,7 +13,7 @@ export const HeaderHeight = 64;
export function Header(props: any) {
const { classes } = useStyles();
const { classes: cardClasses } = useCardStyles(false);
const { classes: cardClasses, cx } = useCardStyles(false);
const { attributes } = usePackageAttributesStore();
const { isLoading, error, data } = useQuery({
@@ -27,12 +27,12 @@ export function Header(props: any) {
data?.tag_name > `v${attributes.packageVersion}` ? data?.tag_name : undefined;
return (
<MantineHeader height="auto" className={cardClasses.card}>
<MantineHeader height="auto" className={cx(cardClasses.card, 'dashboard-header')}>
<Group p="xs" noWrap grow>
<Box className={classes.hide}>
<Box className={cx(classes.hide, 'dashboard-header-logo-root')}>
<Logo />
</Box>
<Group position="right" style={{ maxWidth: 'none' }} noWrap>
<Group className="dashboard-header-group-right" position="right" style={{ maxWidth: 'none' }} noWrap>
<Search />
<ToggleEditModeAction />
<DockerMenuButton />

View File

@@ -57,7 +57,7 @@ export function Search() {
const { config } = useConfigContext();
const [searchQuery, setSearchQuery] = useState('');
const [debounced] = useDebouncedValue(searchQuery, 250);
const { classes: cardClasses } = useCardStyles(true);
const { classes: cardClasses, cx } = useCardStyles(true);
const isOverseerrEnabled = config?.apps.some(
(x) => x.integration.type === 'overseerr' || x.integration.type === 'jellyseerr'
@@ -216,7 +216,8 @@ export function Search() {
}
}}
classNames={{
input: cardClasses.card,
input: cx(cardClasses.card, 'dashboard-header-search-input'),
root: 'dashboard-header-search-root',
}}
radius="lg"
size="md"