feat: about page initial version

Adding something to the about page for now, including the app version to better know what versions
of the app people are running
This commit is contained in:
sct
2020-12-15 07:27:30 +00:00
parent ff618956b5
commit 3f2a04c881
8 changed files with 178 additions and 0 deletions

View File

@@ -37,4 +37,5 @@ jobs:
username: ${{ secrets.DOCKER_USERNAME }} username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }} password: ${{ secrets.DOCKER_PASSWORD }}
repository: sctx/overseerr repository: sctx/overseerr
build_args: COMMIT_TAG=${{ github.sha }}
tags: develop tags: develop

View File

@@ -12,6 +12,9 @@ RUN yarn cache clean
FROM node:12.18-alpine FROM node:12.18-alpine
ARG COMMIT_TAG
ENV COMMIT_TAG=${COMMIT_TAG}
COPY . /app COPY . /app
WORKDIR /app WORKDIR /app

View File

@@ -1478,6 +1478,29 @@ paths:
application/json: application/json:
schema: schema:
$ref: '#/components/schemas/DiscordSettings' $ref: '#/components/schemas/DiscordSettings'
/settings/about:
get:
summary: Return current about stats
description: Returns current server stats in JSON format
tags:
- settings
responses:
'200':
description: Returned about settings
content:
application/json:
schema:
type: object
properties:
version:
type: string
example: '1.0.0'
totalRequests:
type: number
example: 100
totalMediaItems:
type: number
example: 100
/auth/me: /auth/me:
get: get:
summary: Returns the currently logged in user summary: Returns the currently logged in user

View File

@@ -0,0 +1,5 @@
export interface SettingsAboutResponse {
version: string;
totalRequests: number;
totalMediaItems: number;
}

View File

@@ -17,6 +17,9 @@ import { scheduledJobs } from '../job/schedule';
import { Permission } from '../lib/permissions'; import { Permission } from '../lib/permissions';
import { isAuthenticated } from '../middleware/auth'; import { isAuthenticated } from '../middleware/auth';
import { merge } from 'lodash'; import { merge } from 'lodash';
import { version } from '../../package.json';
import Media from '../entity/Media';
import { MediaRequest } from '../entity/MediaRequest';
const settingsRoutes = Router(); const settingsRoutes = Router();
@@ -431,4 +434,23 @@ settingsRoutes.post('/notifications/email', (req, res) => {
res.status(200).json(settings.notifications.agents.email); res.status(200).json(settings.notifications.agents.email);
}); });
settingsRoutes.get('/about', async (req, res) => {
const mediaRepository = getRepository(Media);
const mediaRequestRepository = getRepository(MediaRequest);
const totalMediaItems = await mediaRepository.count();
const totalRequests = await mediaRequestRepository.count();
let finalVersion = version;
if (version === '0.1.0') {
finalVersion = `develop-${process.env.COMMIT_TAG ?? 'local'}`;
}
return res.status(200).json({
version: finalVersion,
totalMediaItems,
totalRequests,
});
});
export default settingsRoutes; export default settingsRoutes;

View File

@@ -0,0 +1,40 @@
import React from 'react';
import { withProperties } from '../../../utils/typeHelpers';
interface ListItemProps {
title: string;
}
const ListItem: React.FC<ListItemProps> = ({ title, children }) => {
return (
<div className="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4">
<dt className="text-sm font-medium text-gray-200">{title}</dt>
<dd className="mt-1 flex text-sm text-gray-400 sm:mt-0 sm:col-span-2">
<span className="flex-grow">{children}</span>
</dd>
</div>
);
};
interface ListProps {
title: string;
subTitle?: string;
}
const List: React.FC<ListProps> = ({ title, subTitle, children }) => {
return (
<>
<div>
<h3 className="text-lg leading-6 font-medium text-gray-100">{title}</h3>
{subTitle && (
<p className="mt-1 max-w-2xl text-sm text-gray-300">{subTitle}</p>
)}
</div>
<div className="mt-5 border-t border-gray-800">
<dl className="divide-y divide-gray-800">{children}</dl>
</div>
</>
);
};
export default withProperties(List, { Item: ListItem });

View File

@@ -0,0 +1,67 @@
import React from 'react';
import useSWR from 'swr';
import Error from '../../../pages/_error';
import List from '../../Common/List';
import LoadingSpinner from '../../Common/LoadingSpinner';
import { SettingsAboutResponse } from '../../../../server/interfaces/api/settingsInterfaces';
import { FormattedNumber } from 'react-intl';
const SettingsAbout: React.FC = () => {
const { data, error } = useSWR<SettingsAboutResponse>(
'/api/v1/settings/about'
);
if (error) {
return <Error statusCode={500} />;
}
if (!data && !error) {
return <LoadingSpinner />;
}
if (!data) {
return <LoadingSpinner />;
}
return (
<>
<div className="mb-8">
<List title="Overseerr Information">
<List.Item title="Version">{data.version}</List.Item>
<List.Item title="Total Media">
<FormattedNumber value={data.totalMediaItems} />
</List.Item>
<List.Item title="Total Requests">
<FormattedNumber value={data.totalRequests} />
</List.Item>
</List>
</div>
<div className="mb-8">
<List title="Getting Support">
<List.Item title="GitHub Discussions">
<a
href="https://github.com/sct/overseerr/discussions"
target="_blank"
rel="noreferrer"
className="text-indigo-500 hover:underline"
>
https://github.com/sct/overseerr/discussions
</a>
</List.Item>
<List.Item title="Discord">
<a
href="https://discord.gg/PkCWJSeCk7"
target="_blank"
rel="noreferrer"
className="text-indigo-500 hover:underline"
>
Click here to join our Discord server.
</a>
</List.Item>
</List>
</div>
</>
);
};
export default SettingsAbout;

View File

@@ -0,0 +1,17 @@
import { NextPage } from 'next';
import React from 'react';
import SettingsAbout from '../../components/Settings/SettingsAbout';
import SettingsLayout from '../../components/Settings/SettingsLayout';
import useRouteGuard from '../../hooks/useRouteGuard';
import { Permission } from '../../hooks/useUser';
const SettingsAboutPage: NextPage = () => {
useRouteGuard(Permission.MANAGE_SETTINGS);
return (
<SettingsLayout>
<SettingsAbout />
</SettingsLayout>
);
};
export default SettingsAboutPage;