diff --git a/.eslintrc.js b/.eslintrc.js index b682aa9dc..abde8f7cb 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -20,6 +20,7 @@ module.exports = { }, rules: { 'react/react-in-jsx-scope': 'off', + 'react/no-children-prop': 'off', "unused-imports/no-unused-imports": "warn", "@typescript-eslint/no-unused-vars": "off", "@typescript-eslint/no-unused-imports": "off", diff --git a/.storybook/main.js b/.storybook/main.js index 6449361d8..80bc56834 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -3,6 +3,7 @@ module.exports = { addons: [ 'storybook-dark-mode', '@storybook/addon-links', + 'storybook-addon-mock/register', '@storybook/addon-essentials', { name: 'storybook-addon-turbo-build', diff --git a/README.md b/README.md index f92a99571..221858ee8 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,7 @@ - [📊 Modules](#-modules) - [🔍 Search Bar](#-search-bar) - [💖 Contributing](#-contributing) + - [🍏 Request Icons](#-request-icons) @@ -168,10 +169,13 @@ Icons are requested in the following way:
Modules are blocks shown on the sides of the Homarr dashboard that display information. They can be enabled in settings. **Clock Module** -The clock module will display your current time and date. +The Clock Module will display your current time and date. **Calendar Module** -The Calendar module uses [integrations](#--integrations-1) to display new content. +The Calendar Module uses [integrations](#--integrations-1) to display new content. + +**Weather Module** +The Weather Module uses your devices location to display the current, highest, and lowest temperature. **[⤴️ Back to Top](#-table-of-contents)** @@ -187,5 +191,11 @@ The Search Bar will open any Search Query after the Query URL you've specified i **Please read our [Contribution Guidelines](/CONTRIBUTING.md)** All contributions are highly appreciated. + +**[⤴️ Back to Top](#-table-of-contents)** + +## 🍏 Request Icons + +The icons used in Homarr are automatically requested from the [dashboard-icons](https://github.com/walkxhub/dashboard-icons) repo. You can make a icon request by creating an [issue](https://github.com/walkxhub/dashboard-icons/issues/new/choose). **[⤴️ Back to Top](#-table-of-contents)** diff --git a/data/constants.ts b/data/constants.ts index 11dbe4c3b..377bac1ff 100644 --- a/data/constants.ts +++ b/data/constants.ts @@ -1,2 +1,2 @@ export const REPO_URL = 'ajnart/homarr'; -export const CURRENT_VERSION = 'v0.3.1'; +export const CURRENT_VERSION = 'v0.4.0'; diff --git a/package.json b/package.json index 6c6ee0354..8b110f68e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "homarr", - "version": "0.3.0", + "version": "0.4.0", "private": "false", "description": "Homarr - A homepage for your server.", "repository": { @@ -79,9 +79,13 @@ "eslint-plugin-unused-imports": "^2.0.0", "jest": "^27.5.1", "prettier": "^2.6.2", + "storybook-addon-mock": "^2.3.2", "storybook-addon-turbo-build": "^1.1.0", "storybook-dark-mode": "^1.0.9", "ts-jest": "^27.1.4", "typescript": "4.6.3" + }, + "resolutions": { + "@types/react": "17.0.30" } } diff --git a/src/components/AppShelf/AddAppShelfItem.tsx b/src/components/AppShelf/AddAppShelfItem.tsx index cd6b7ff68..ccc6569f2 100644 --- a/src/components/AppShelf/AddAppShelfItem.tsx +++ b/src/components/AppShelf/AddAppShelfItem.tsx @@ -154,7 +154,14 @@ export function AddAppShelfItemForm(props: { setOpened: (b: boolean) => void } & return ( <>
- Placeholder + Placeholder
{ diff --git a/src/components/AppShelf/AppShelf.tsx b/src/components/AppShelf/AppShelf.tsx index 76ec5df39..10cbee4ec 100644 --- a/src/components/AppShelf/AppShelf.tsx +++ b/src/components/AppShelf/AppShelf.tsx @@ -1,17 +1,28 @@ import React, { useState } from 'react'; import { motion } from 'framer-motion'; -import { Text, AspectRatio, Card, Image, useMantineTheme, Center, Grid } from '@mantine/core'; +import { Text, AspectRatio, Card, Image, Center, Grid, createStyles } from '@mantine/core'; import { useConfig } from '../../tools/state'; import { serviceItem } from '../../tools/types'; import AppShelfMenu from './AppShelfMenu'; +import PingComponent from '../modules/ping/PingModule'; + +const useStyles = createStyles((theme) => ({ + item: { + transition: 'box-shadow 150ms ease, transform 100ms ease', + + '&:hover': { + boxShadow: `${theme.shadows.md} !important`, + transform: 'scale(1.05)', + }, + }, +})); const AppShelf = (props: any) => { const { config } = useConfig(); - return ( {config.services.map((service) => ( - + ))} @@ -22,9 +33,14 @@ const AppShelf = (props: any) => { export function AppShelfItem(props: any) { const { service }: { service: serviceItem } = props; const [hovering, setHovering] = useState(false); - const theme = useMantineTheme(); + const { classes, theme } = useStyles(); return ( { setHovering(true); @@ -33,7 +49,7 @@ export function AppShelfItem(props: any) { setHovering(false); }} > - + {service.name} @@ -41,8 +57,8 @@ export function AppShelfItem(props: any) { + diff --git a/src/components/AppShelf/AppShelfMenu.tsx b/src/components/AppShelf/AppShelfMenu.tsx index ae905dfbf..257d61629 100644 --- a/src/components/AppShelf/AppShelfMenu.tsx +++ b/src/components/AppShelf/AppShelfMenu.tsx @@ -1,4 +1,4 @@ -import { Menu, Modal, Text } from '@mantine/core'; +import { Menu, Modal, Text, useMantineTheme } from '@mantine/core'; import { showNotification } from '@mantine/notifications'; import { useState } from 'react'; import { Check, Edit, Trash } from 'tabler-icons-react'; @@ -8,12 +8,13 @@ import { AddAppShelfItemForm } from './AddAppShelfItem'; export default function AppShelfMenu(props: any) { const { service } = props; const { config, setConfig } = useConfig(); + const theme = useMantineTheme(); const [opened, setOpened] = useState(false); return ( <> setOpened(false)} title="Modify a service" @@ -28,7 +29,16 @@ export default function AppShelfMenu(props: any) { message="Save service" /> - + Settings - } - title="Update available" - radius="lg" - hidden={current === latest} - > - Version {latest} is available. Current: {current} - Search engine )} - - - setConfig({ - ...config, - settings: { - ...config.settings, - searchBar: e.currentTarget.checked, - }, - }) - } - checked={config.settings.searchBar} - label="Enable search bar" - /> - @@ -125,20 +97,7 @@ function SettingsMenu(props: any) { } export function SettingsMenuButton(props: any) { - const [update, setUpdate] = useState(false); const [opened, setOpened] = useState(false); - const [latestVersion, setLatestVersion] = useState(CURRENT_VERSION); - useEffect(() => { - // Fetch Data here when component first mounted - fetch(`https://api.github.com/repos/${REPO_URL}/releases/latest`).then((res) => { - res.json().then((data) => { - setLatestVersion(data.tag_name); - if (data.tag_name !== CURRENT_VERSION) { - setUpdate(true); - } - }); - }); - }, []); return ( <> setOpened(false)} > - + setOpened(true)} > - - - + diff --git a/src/components/layout/Aside.tsx b/src/components/layout/Aside.tsx index 912b231ac..6cef6eb4e 100644 --- a/src/components/layout/Aside.tsx +++ b/src/components/layout/Aside.tsx @@ -1,7 +1,6 @@ import { Aside as MantineAside, Group } from '@mantine/core'; -import { DateModule } from '../modules'; -import { CalendarModule } from '../modules/calendar/CalendarModule'; -import ModuleWrapper from '../modules/moduleWrapper'; +import { WeatherModule, DateModule, CalendarModule } from '../modules'; +import { ModuleWrapper } from '../modules/moduleWrapper'; export default function Aside(props: any) { return ( @@ -18,6 +17,7 @@ export default function Aside(props: any) { + ); diff --git a/src/components/layout/Footer.tsx b/src/components/layout/Footer.tsx index 697f02123..115809781 100644 --- a/src/components/layout/Footer.tsx +++ b/src/components/layout/Footer.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { createStyles, Anchor, @@ -6,8 +6,11 @@ import { Group, ActionIcon, Footer as FooterComponent, + Alert, + useMantineTheme, } from '@mantine/core'; -import { BrandGithub } from 'tabler-icons-react'; +import { AlertCircle, BrandGithub } from 'tabler-icons-react'; +import { CURRENT_VERSION, REPO_URL } from '../../../data/constants'; const useStyles = createStyles((theme) => ({ footer: { @@ -40,6 +43,8 @@ interface FooterCenteredProps { } export function Footer({ links }: FooterCenteredProps) { + const [update, setUpdate] = useState(false); + const theme = useMantineTheme(); const { classes } = useStyles(); const items = links.map((link) => ( @@ -54,27 +59,87 @@ export function Footer({ links }: FooterCenteredProps) { )); - return ( - - - component="a" href="https://github.com/ajnart/homarr" size="lg"> - - - - Made with ❤️ by @ - { + // Fetch Data here when component first mounted + fetch(`https://api.github.com/repos/${REPO_URL}/releases/latest`).then((res) => { + res.json().then((data) => { + setLatestVersion(data.tag_name); + if (data.tag_name !== CURRENT_VERSION) { + setUpdate(true); + } + }); + }); + }, []); + + return ( + + + + setOpen(false)} + icon={} + title={`Updated version: ${latestVersion} is available. Current version: ${CURRENT_VERSION}`} + withCloseButton + radius="lg" + hidden={CURRENT_VERSION === latestVersion || !isOpen} + variant="outline" + styles={{ + root: { + backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark[6] : 'white', + }, + + closeButton: { + marginLeft: '5px', + }, + }} + children={undefined} + /> + + + + component="a" href="https://github.com/ajnart/homarr" size="lg"> + + + + {CURRENT_VERSION} + + + - ajnart - - + Made with ❤️ by @ + + ajnart + + + ); diff --git a/src/components/layout/Header.tsx b/src/components/layout/Header.tsx index f319c4c0e..28ed95f46 100644 --- a/src/components/layout/Header.tsx +++ b/src/components/layout/Header.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { createStyles, Header as Head, Group, Box } from '@mantine/core'; import { Logo } from './Logo'; -import SearchBar from '../SearchBar/SearchBar'; +import SearchBar from '../modules/search/SearchModule'; import { AddItemShelfButton } from '../AppShelf/AddAppShelfItem'; import { SettingsMenuButton } from '../Settings/SettingsMenu'; diff --git a/src/components/layout/Layout.tsx b/src/components/layout/Layout.tsx index 8b82b4a74..ac2c3c742 100644 --- a/src/components/layout/Layout.tsx +++ b/src/components/layout/Layout.tsx @@ -10,11 +10,7 @@ const useStyles = createStyles((theme) => ({ export default function Layout({ children, style }: any) { const { classes, cx } = useStyles(); return ( - } - header={
} - footer={