Show Monitoring app under "utilities", and fix its icon in "apps" and "user roles" screens

This commit is contained in:
Maarten de Waard 2022-10-03 15:17:17 +02:00
parent 86192f28fd
commit aea093332b
No known key found for this signature in database
GPG key ID: 1D3E893A657CC8DA
9 changed files with 73 additions and 53 deletions

View file

@ -0,0 +1 @@
Monitor your system with Grafana

View file

@ -0,0 +1 @@
Access documentation and forum

View file

@ -25,6 +25,12 @@ export const appAccessList = [
label: 'Zulip', label: 'Zulip',
documentationUrl: 'https://docs.zulip.com/help/', documentationUrl: 'https://docs.zulip.com/help/',
}, },
{
name: 'monitoring',
image: '/assets/monitoring.svg',
label: 'Monitoring',
documentationUrl: 'https://grafana.com/docs/',
},
]; ];
export const allAppAccessList = [ export const allAppAccessList = [

View file

@ -5,7 +5,6 @@ import { SearchIcon } from '@heroicons/react/solid';
import { showToast, ToastType } from 'src/common/util/show-toast'; import { showToast, ToastType } from 'src/common/util/show-toast';
import _, { debounce } from 'lodash'; import _, { debounce } from 'lodash';
import { Table } from 'src/components'; import { Table } from 'src/components';
import { appAccessList } from 'src/components/UserModal/consts';
import { App, AppStatus, useApps } from 'src/services/apps'; import { App, AppStatus, useApps } from 'src/services/apps';
import { AppInstallModal } from './components'; import { AppInstallModal } from './components';
import { getConstForStatus } from './consts'; import { getConstForStatus } from './consts';
@ -40,11 +39,10 @@ export const Apps: React.FC = () => {
accessor: 'name', accessor: 'name',
Cell: (e: any) => { Cell: (e: any) => {
const app = e.cell.row.original as App; const app = e.cell.row.original as App;
const imageSrc = _.find(appAccessList, { name: app.slug })?.image;
return ( return (
<div className="flex items-center"> <div className="flex items-center">
<div className="flex-shrink-0 h-10 w-10"> <div className="flex-shrink-0 h-10 w-10">
<img className="h-10 w-10 rounded-md overflow-hidden" src={imageSrc} alt={app.name} /> <img className="h-10 w-10 rounded-md overflow-hidden" src={app.assetSrc} alt={app.name} />
</div> </div>
<div className="ml-4"> <div className="ml-4">
<div className="text-sm font-medium text-gray-900">{app.name}</div> <div className="text-sm font-medium text-gray-900">{app.name}</div>

View file

@ -1,15 +1,14 @@
/* eslint-disable react-hooks/exhaustive-deps */ /* eslint-disable react-hooks/exhaustive-deps */
import React, { useEffect } from 'react'; import React, { useEffect } from 'react';
import clsx from 'clsx';
import { useApps } from 'src/services/apps'; import { useApps } from 'src/services/apps';
// import { DASHBOARD_QUICK_ACCESS } from './consts'; import { DASHBOARD_QUICK_ACCESS } from './consts';
import { DashboardCard } from './components'; import { DashboardCard, DashboardUtility } from './components';
export const Dashboard: React.FC = () => { export const Dashboard: React.FC = () => {
const host = window.location.hostname; const host = window.location.hostname;
const splitedDomain = host.split('.'); const splitedDomain = host.split('.');
splitedDomain.shift(); splitedDomain.shift();
const { apps, appTableLoading, loadApps } = useApps(); const { apps, loadApps } = useApps();
// Tell React to load the apps // Tell React to load the apps
useEffect(() => { useEffect(() => {
@ -29,11 +28,27 @@ export const Dashboard: React.FC = () => {
<div className="max-w-7xl mx-auto py-4 px-3 sm:px-6 lg:px-8 h-full flex-grow"> <div className="max-w-7xl mx-auto py-4 px-3 sm:px-6 lg:px-8 h-full flex-grow">
<div className="grid grid-cols-1 md:grid-cols-2 md:gap-4 lg:grid-cols-4 mb-10"> <div className="grid grid-cols-1 md:grid-cols-2 md:gap-4 lg:grid-cols-4 mb-10">
{apps {apps
.filter((app) => app.slug !== 'dashboard') .filter((app) => ['dashboard', 'monitoring'].indexOf(app.slug) === -1)
.map((app) => ( .map((app) => (
<DashboardCard app={app} key={app.name} /> <DashboardCard app={app} key={app.name} />
))} ))}
</div> </div>
<div className="max-w-4xl mx-auto py-4 sm:px-6 lg:px-8 h-full flex-grow">
<div className="pb-4 border-b border-gray-200 sm:flex sm:items-center">
<h3 className="text-lg leading-6 font-medium text-gray-900">Utilities</h3>
</div>
<dl className="mt-5 grid grid-cols-1 gap-2 sm:grid-cols-2">
{DASHBOARD_QUICK_ACCESS.map((item) => (
<DashboardUtility item={item} key={item.name} />
))}
{apps
.filter((app) => app.slug === 'monitoring' && app.url !== null)
.map((app) => (
<DashboardUtility item={app} key={app.name} />
))}
</dl>
</div>
</div> </div>
</div> </div>
); );

View file

@ -0,0 +1,38 @@
import React, { useState, useEffect } from 'react';
import ReactMarkdown from 'react-markdown';
export const DashboardUtility: React.FC<any> = ({ item }: { item: any }) => {
const [content, setContent] = useState('');
useEffect(() => {
fetch(item.markdownSrc)
.then((res) => res.text())
.then((md) => {
return setContent(md);
})
.catch(() => {});
}, [item.markdownSrc]);
return (
<>
<a
href={item.url}
key={item.name}
target="_blank"
rel="noreferrer"
className="bg-white rounded-lg overflow-hidden sm:p-2 flex items-center group"
>
<div className="w-16 h-16 flex items-center justify-center bg-primary-100 group-hover:bg-primary-200 transition-colors rounded-lg mr-4">
{item.icon && <item.icon className="h-6 w-6 text-primary-900" aria-hidden="true" />}
{item.assetSrc && <img className="h-6 w-6" src={item.assetSrc} alt={item.name} />}
</div>
<div>
<dt className="truncate text-sm leading-5 font-medium">{item.name}</dt>
<dd className="mt-1 text-gray-500 text-sm leading-5 font-normal">
<ReactMarkdown>{content}</ReactMarkdown>
</dd>
</div>
</a>
</>
);
};

View file

@ -0,0 +1 @@
export { DashboardUtility } from './DashboardUtility';

View file

@ -1 +1,2 @@
export { DashboardCard } from './DashboardCard'; export { DashboardCard } from './DashboardCard';
export { DashboardUtility } from './DashboardUtility';

View file

@ -1,51 +1,10 @@
import { ChartBarIcon, InformationCircleIcon } from '@heroicons/react/outline'; import { InformationCircleIcon } from '@heroicons/react/outline';
export const DASHBOARD_APPS = (rootDomain: string) => [ export const DASHBOARD_QUICK_ACCESS = [
{ {
id: 1, name: 'Support',
name: 'Nextcloud',
assetSrc: '/assets/nextcloud.svg',
markdownSrc: '/markdown/nextcloud.md',
url: `https://files.${rootDomain}`,
},
{
id: 2,
name: 'Wekan',
assetSrc: '/assets/wekan.svg',
markdownSrc: '/markdown/wekan.md',
url: `https://wekan.${rootDomain}`,
},
{
id: 3,
name: 'Zulip',
assetSrc: '/assets/zulip.svg',
markdownSrc: '/markdown/zulip.md',
url: `https://zulip.${rootDomain}`,
},
{
id: 4,
name: 'Wordpress',
assetSrc: '/assets/wordpress.svg',
markdownSrc: '/markdown/wordpress.md',
url: `https://www.${rootDomain}`,
},
];
export const DASHBOARD_QUICK_ACCESS = (rootDomain: string) => [
{
id: 1,
name: 'Monitoring →',
url: `https://grafana.${rootDomain}`,
description: 'Monitor your system with Grafana',
icon: ChartBarIcon,
active: true,
},
{
id: 2,
name: 'Support →',
url: 'https://docs.stackspin.net', url: 'https://docs.stackspin.net',
description: 'Access documentation and forum', markdownSrc: '/markdown/support.md',
icon: InformationCircleIcon, icon: InformationCircleIcon,
active: true,
}, },
]; ];