mirror of
https://github.com/ajnart/homarr.git
synced 2025-11-12 08:25:47 +01:00
Merge branch 'feature/add-basic-authentication' of https://github.com/ajnart/homarr into feature/add-basic-authentication
This commit is contained in:
@@ -8,12 +8,19 @@ import {
|
|||||||
LoadingOverlay,
|
LoadingOverlay,
|
||||||
Menu,
|
Menu,
|
||||||
SimpleGrid,
|
SimpleGrid,
|
||||||
|
Stack,
|
||||||
Text,
|
Text,
|
||||||
Title,
|
Title,
|
||||||
} from '@mantine/core';
|
} from '@mantine/core';
|
||||||
import { useListState } from '@mantine/hooks';
|
import { useListState } from '@mantine/hooks';
|
||||||
import { modals } from '@mantine/modals';
|
import { modals } from '@mantine/modals';
|
||||||
import { IconDotsVertical, IconFolderFilled, IconPlus, IconTrash } from '@tabler/icons-react';
|
import {
|
||||||
|
IconApps,
|
||||||
|
IconDotsVertical,
|
||||||
|
IconFolderFilled,
|
||||||
|
IconPlus,
|
||||||
|
IconTrash,
|
||||||
|
} from '@tabler/icons-react';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { ManageLayout } from '~/components/layout/Templates/ManageLayout';
|
import { ManageLayout } from '~/components/layout/Templates/ManageLayout';
|
||||||
import { CommonHeader } from '~/components/layout/common-header';
|
import { CommonHeader } from '~/components/layout/common-header';
|
||||||
@@ -21,7 +28,7 @@ import { sleep } from '~/tools/client/time';
|
|||||||
import { api } from '~/utils/api';
|
import { api } from '~/utils/api';
|
||||||
|
|
||||||
const BoardsPage = () => {
|
const BoardsPage = () => {
|
||||||
const { data } = api.config.all.useQuery();
|
const { data } = api.boards.all.useQuery();
|
||||||
|
|
||||||
const [deletingDashboards, { append, filter }] = useListState<string>([]);
|
const [deletingDashboards, { append, filter }] = useListState<string>([]);
|
||||||
|
|
||||||
@@ -60,10 +67,10 @@ const BoardsPage = () => {
|
|||||||
>
|
>
|
||||||
{data.map((board, index) => (
|
{data.map((board, index) => (
|
||||||
<Card key={index} shadow="sm" padding="lg" radius="md" pos="relative" withBorder>
|
<Card key={index} shadow="sm" padding="lg" radius="md" pos="relative" withBorder>
|
||||||
<LoadingOverlay visible={deletingDashboards.includes(board)} />
|
<LoadingOverlay visible={deletingDashboards.includes(board.name)} />
|
||||||
|
|
||||||
<Text weight={500} mb="xs">
|
<Text weight={500} mb="xs">
|
||||||
{board}
|
{board.name}
|
||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
<Group mb="xl">
|
<Group mb="xl">
|
||||||
@@ -72,10 +79,31 @@ const BoardsPage = () => {
|
|||||||
</Badge>
|
</Badge>
|
||||||
</Group>
|
</Group>
|
||||||
|
|
||||||
<Text size="sm" color="dimmed">
|
<Stack spacing={3}>
|
||||||
With Fjord Tours you can explore more of the magical fjord landscapes with tours and
|
<Group position="apart">
|
||||||
activities on and around the fjords of Norway
|
<Group spacing="xs">
|
||||||
</Text>
|
<IconApps opacity={0.7} size="1rem" />
|
||||||
|
<Text color="dimmed">Apps</Text>
|
||||||
|
</Group>
|
||||||
|
<Text>{board.countApps}</Text>
|
||||||
|
</Group>
|
||||||
|
|
||||||
|
<Group position="apart">
|
||||||
|
<Group spacing="xs">
|
||||||
|
<IconApps opacity={0.7} size="1rem" />
|
||||||
|
<Text color="dimmed">Widgets</Text>
|
||||||
|
</Group>
|
||||||
|
<Text>{board.countWidgets}</Text>
|
||||||
|
</Group>
|
||||||
|
|
||||||
|
<Group position="apart">
|
||||||
|
<Group spacing="xs">
|
||||||
|
<IconApps opacity={0.7} size="1rem" />
|
||||||
|
<Text color="dimmed">Categories</Text>
|
||||||
|
</Group>
|
||||||
|
<Text>{board.countCategories}</Text>
|
||||||
|
</Group>
|
||||||
|
</Stack>
|
||||||
|
|
||||||
<Group mt="md">
|
<Group mt="md">
|
||||||
<Button
|
<Button
|
||||||
@@ -101,12 +129,12 @@ const BoardsPage = () => {
|
|||||||
modal: 'deleteBoardModal',
|
modal: 'deleteBoardModal',
|
||||||
title: <Text weight={500}>Delete board</Text>,
|
title: <Text weight={500}>Delete board</Text>,
|
||||||
innerProps: {
|
innerProps: {
|
||||||
boardName: board,
|
boardName: board.name,
|
||||||
onConfirm: async () => {
|
onConfirm: async () => {
|
||||||
append(board);
|
append(board.name);
|
||||||
// give user feedback, that it's being deleted
|
// give user feedback, that it's being deleted
|
||||||
await sleep(500);
|
await sleep(500);
|
||||||
filter((item, _) => item !== board);
|
filter((item, _) => item !== board.name);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import { rssRouter } from './routers/rss';
|
|||||||
import { usenetRouter } from './routers/usenet/router';
|
import { usenetRouter } from './routers/usenet/router';
|
||||||
import { userRouter } from './routers/user';
|
import { userRouter } from './routers/user';
|
||||||
import { weatherRouter } from './routers/weather';
|
import { weatherRouter } from './routers/weather';
|
||||||
|
import { boardRouter } from './routers/board';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the primary router for your server.
|
* This is the primary router for your server.
|
||||||
@@ -39,6 +40,7 @@ export const rootRouter = createTRPCRouter({
|
|||||||
calendar: calendarRouter,
|
calendar: calendarRouter,
|
||||||
weather: weatherRouter,
|
weather: weatherRouter,
|
||||||
invites: inviteRouter,
|
invites: inviteRouter,
|
||||||
|
boards: boardRouter
|
||||||
});
|
});
|
||||||
|
|
||||||
// export type definition of API
|
// export type definition of API
|
||||||
|
|||||||
25
src/server/api/routers/board.ts
Normal file
25
src/server/api/routers/board.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import fs from 'fs';
|
||||||
|
import { getFrontendConfig } from '~/tools/config/getFrontendConfig';
|
||||||
|
|
||||||
|
import { createTRPCRouter, publicProcedure } from '../trpc';
|
||||||
|
|
||||||
|
export const boardRouter = createTRPCRouter({
|
||||||
|
all: publicProcedure.query(async ({ ctx }) => {
|
||||||
|
const files = fs.readdirSync('./data/configs').filter((file) => file.endsWith('.json'));
|
||||||
|
return await Promise.all(
|
||||||
|
files.map(async (file) => {
|
||||||
|
const name = file.replace('.json', '');
|
||||||
|
const config = await getFrontendConfig(name);
|
||||||
|
|
||||||
|
const countApps = config.apps.length;
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: name,
|
||||||
|
countApps: countApps,
|
||||||
|
countWidgets: config.widgets.length,
|
||||||
|
countCategories: config.categories.length
|
||||||
|
};
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user