Show Monitoring app under "utilities", and fix its icon in "apps" and "user roles" screens
This commit is contained in:
parent
86192f28fd
commit
aea093332b
9 changed files with 73 additions and 53 deletions
1
public/markdown/monitoring.md
Normal file
1
public/markdown/monitoring.md
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Monitor your system with Grafana
|
1
public/markdown/support.md
Normal file
1
public/markdown/support.md
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Access documentation and forum
|
|
@ -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 = [
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
|
|
|
@ -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>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1 @@
|
||||||
|
export { DashboardUtility } from './DashboardUtility';
|
|
@ -1 +1,2 @@
|
||||||
export { DashboardCard } from './DashboardCard';
|
export { DashboardCard } from './DashboardCard';
|
||||||
|
export { DashboardUtility } from './DashboardUtility';
|
||||||
|
|
|
@ -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,
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
Loading…
Reference in a new issue