mirror of
https://github.com/ajnart/homarr.git
synced 2025-11-09 23:15:46 +01:00
feat: could position widgets at left
This commit is contained in:
@@ -4,6 +4,7 @@ import { IconBrandGithub as BrandGithub } from '@tabler/icons';
|
|||||||
import { CURRENT_VERSION } from '../../../data/constants';
|
import { CURRENT_VERSION } from '../../../data/constants';
|
||||||
import { useConfig } from '../../tools/state';
|
import { useConfig } from '../../tools/state';
|
||||||
import { ColorSchemeSwitch } from '../ColorSchemeToggle/ColorSchemeSwitch';
|
import { ColorSchemeSwitch } from '../ColorSchemeToggle/ColorSchemeSwitch';
|
||||||
|
import { WidgetsPositionSwitch } from '../WidgetsPositionSwitch/WidgetsPositionSwitch';
|
||||||
import ConfigChanger from '../Config/ConfigChanger';
|
import ConfigChanger from '../Config/ConfigChanger';
|
||||||
import SaveConfigComponent from '../Config/SaveConfig';
|
import SaveConfigComponent from '../Config/SaveConfig';
|
||||||
import ModuleEnabler from './ModuleEnabler';
|
import ModuleEnabler from './ModuleEnabler';
|
||||||
@@ -67,8 +68,8 @@ export default function CommonSettings(args: any) {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Group>
|
</Group>
|
||||||
|
|
||||||
<ColorSchemeSwitch />
|
<ColorSchemeSwitch />
|
||||||
|
<WidgetsPositionSwitch />
|
||||||
<ModuleEnabler />
|
<ModuleEnabler />
|
||||||
<ConfigChanger />
|
<ConfigChanger />
|
||||||
<SaveConfigComponent />
|
<SaveConfigComponent />
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import { createStyles, Switch, Group } from '@mantine/core';
|
||||||
|
import { useConfig } from '../../tools/state';
|
||||||
|
|
||||||
|
const useStyles = createStyles((theme) => ({
|
||||||
|
root: {
|
||||||
|
position: 'relative',
|
||||||
|
'& *': {
|
||||||
|
cursor: 'pointer',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
icon: {
|
||||||
|
pointerEvents: 'none',
|
||||||
|
position: 'absolute',
|
||||||
|
zIndex: 1,
|
||||||
|
top: 3,
|
||||||
|
},
|
||||||
|
|
||||||
|
iconLight: {
|
||||||
|
left: 4,
|
||||||
|
color: theme.white,
|
||||||
|
},
|
||||||
|
|
||||||
|
iconDark: {
|
||||||
|
right: 4,
|
||||||
|
color: theme.colors.gray[6],
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
export function WidgetsPositionSwitch() {
|
||||||
|
const { config, setConfig } = useConfig();
|
||||||
|
const { classes, cx } = useStyles();
|
||||||
|
const defaultPosition = config?.settings?.widgetPosition || 'right';
|
||||||
|
const [widgetPosition, setWidgetPosition] = useState(defaultPosition);
|
||||||
|
const toggleWidgetPosition = () => {
|
||||||
|
const position = widgetPosition === 'right' ? 'left' : 'right';
|
||||||
|
setWidgetPosition(position);
|
||||||
|
setConfig({
|
||||||
|
...config,
|
||||||
|
settings: {
|
||||||
|
...config.settings,
|
||||||
|
widgetPosition: position,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Group>
|
||||||
|
<div className={classes.root}>
|
||||||
|
<Switch checked={widgetPosition === 'left'} onChange={() => toggleWidgetPosition()} size="md" />
|
||||||
|
</div>
|
||||||
|
Position widgets on left
|
||||||
|
</Group>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
import { Aside as MantineAside, createStyles, Group } from '@mantine/core';
|
import { Aside as MantineAside, createStyles } from '@mantine/core';
|
||||||
import { useMediaQuery } from '@mantine/hooks';
|
import Widgets from './Widgets';
|
||||||
import { WeatherModule, DateModule, CalendarModule, TotalDownloadsModule } from '../modules';
|
|
||||||
import { ModuleWrapper } from '../modules/moduleWrapper';
|
|
||||||
|
|
||||||
const useStyles = createStyles((theme) => ({
|
const useStyles = createStyles((theme) => ({
|
||||||
hide: {
|
hide: {
|
||||||
@@ -18,8 +16,6 @@ const useStyles = createStyles((theme) => ({
|
|||||||
|
|
||||||
export default function Aside(props: any) {
|
export default function Aside(props: any) {
|
||||||
const { classes, cx } = useStyles();
|
const { classes, cx } = useStyles();
|
||||||
const matches = useMediaQuery('(min-width: 800px)');
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MantineAside
|
<MantineAside
|
||||||
pr="md"
|
pr="md"
|
||||||
@@ -34,16 +30,7 @@ export default function Aside(props: any) {
|
|||||||
base: 'auto',
|
base: 'auto',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<>
|
<Widgets />
|
||||||
{matches && (
|
|
||||||
<Group my="sm" grow direction="column" style={{ width: 300 }}>
|
|
||||||
<ModuleWrapper module={CalendarModule} />
|
|
||||||
<ModuleWrapper module={TotalDownloadsModule} />
|
|
||||||
<ModuleWrapper module={WeatherModule} />
|
|
||||||
<ModuleWrapper module={DateModule} />
|
|
||||||
</Group>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
</MantineAside>
|
</MantineAside>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,10 @@ import { AppShell, createStyles } from '@mantine/core';
|
|||||||
import { Header } from './Header';
|
import { Header } from './Header';
|
||||||
import { Footer } from './Footer';
|
import { Footer } from './Footer';
|
||||||
import Aside from './Aside';
|
import Aside from './Aside';
|
||||||
|
import Navbar from './Navbar';
|
||||||
import { HeaderConfig } from './HeaderConfig';
|
import { HeaderConfig } from './HeaderConfig';
|
||||||
import { Background } from './Background';
|
import { Background } from './Background';
|
||||||
|
import { useConfig } from '../../tools/state';
|
||||||
|
|
||||||
const useStyles = createStyles((theme) => ({
|
const useStyles = createStyles((theme) => ({
|
||||||
main: {},
|
main: {},
|
||||||
@@ -11,8 +13,16 @@ const useStyles = createStyles((theme) => ({
|
|||||||
|
|
||||||
export default function Layout({ children, style }: any) {
|
export default function Layout({ children, style }: any) {
|
||||||
const { classes, cx } = useStyles();
|
const { classes, cx } = useStyles();
|
||||||
|
const { config } = useConfig();
|
||||||
|
const widgetPosition = config?.settings?.widgetPosition === 'left';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppShell aside={<Aside />} header={<Header />} footer={<Footer links={[]} />}>
|
<AppShell
|
||||||
|
header={<Header />}
|
||||||
|
navbar={widgetPosition ? <Navbar /> : <></>}
|
||||||
|
aside={widgetPosition ? <></> : <Aside />}
|
||||||
|
footer={<Footer links={[]} />}
|
||||||
|
>
|
||||||
<HeaderConfig />
|
<HeaderConfig />
|
||||||
<Background />
|
<Background />
|
||||||
<main
|
<main
|
||||||
|
|||||||
@@ -1,24 +1,37 @@
|
|||||||
import { Group, Navbar as MantineNavbar } from '@mantine/core';
|
import { createStyles, Navbar as MantineNavbar } from '@mantine/core';
|
||||||
import { WeatherModule, DateModule } from '../modules';
|
import Widgets from './Widgets';
|
||||||
import { ModuleWrapper } from '../modules/moduleWrapper';
|
|
||||||
|
const useStyles = createStyles((theme) => ({
|
||||||
|
hide: {
|
||||||
|
[theme.fn.smallerThan('xs')]: {
|
||||||
|
display: 'none',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
burger: {
|
||||||
|
[theme.fn.largerThan('sm')]: {
|
||||||
|
display: 'none',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
export default function Navbar() {
|
export default function Navbar() {
|
||||||
|
const { classes, cx } = useStyles();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MantineNavbar
|
<MantineNavbar
|
||||||
hiddenBreakpoint="lg"
|
pl="md"
|
||||||
|
hiddenBreakpoint="sm"
|
||||||
hidden
|
hidden
|
||||||
|
className={cx(classes.hide)}
|
||||||
style={{
|
style={{
|
||||||
border: 'none',
|
border: 'none',
|
||||||
|
background: 'none',
|
||||||
}}
|
}}
|
||||||
width={{
|
width={{
|
||||||
base: 'auto',
|
base: 'auto',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Group mt="sm" direction="column" align="center">
|
<Widgets />
|
||||||
<ModuleWrapper module={DateModule} />
|
|
||||||
<ModuleWrapper module={WeatherModule} />
|
|
||||||
<ModuleWrapper module={WeatherModule} />
|
|
||||||
</Group>
|
|
||||||
</MantineNavbar>
|
</MantineNavbar>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
21
src/components/layout/Widgets.tsx
Normal file
21
src/components/layout/Widgets.tsx
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { Group } from '@mantine/core';
|
||||||
|
import { useMediaQuery } from '@mantine/hooks';
|
||||||
|
import { CalendarModule, DateModule, TotalDownloadsModule, WeatherModule } from '../modules';
|
||||||
|
import { ModuleWrapper } from '../modules/moduleWrapper';
|
||||||
|
|
||||||
|
export default function Widgets(props: any) {
|
||||||
|
const matches = useMediaQuery('(min-width: 800px)');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{matches && (
|
||||||
|
<Group my="sm" grow direction="column" style={{ width: 300 }}>
|
||||||
|
<ModuleWrapper module={CalendarModule} />
|
||||||
|
<ModuleWrapper module={TotalDownloadsModule} />
|
||||||
|
<ModuleWrapper module={WeatherModule} />
|
||||||
|
<ModuleWrapper module={DateModule} />
|
||||||
|
</Group>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@ export interface Settings {
|
|||||||
primaryShade?: MantineTheme['primaryShade'];
|
primaryShade?: MantineTheme['primaryShade'];
|
||||||
background?: string;
|
background?: string;
|
||||||
appOpacity?: number;
|
appOpacity?: number;
|
||||||
|
widgetPosition?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Config {
|
export interface Config {
|
||||||
|
|||||||
Reference in New Issue
Block a user