diff --git a/public/assets/monitoring.svg b/public/assets/monitoring.svg new file mode 100644 index 0000000000000000000000000000000000000000..fa9380825724e61e8f04f7effc0d83c41506ea0a --- /dev/null +++ b/public/assets/monitoring.svg @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Generator: Adobe Illustrator 24.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> +<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" + viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve"> +<style type="text/css"> + .st0{fill:url(#SVGID_1_);} +</style> +<g> + + <linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="-0.7593" y1="513.0059" x2="1.0811" y2="513.0059" gradientTransform="matrix(1.431349e-14 -254.0268 254.0268 1.690345e-14 -130061.25 434.0558)"> + <stop offset="0" style="stop-color:#FFF100"/> + <stop offset="1" style="stop-color:#F05A28"/> + </linearGradient> + <path class="st0" d="M490.8,226c-0.8-8.6-2.3-18.5-5.1-29.5c-2.8-10.9-7.1-22.8-13.3-35.3c-6.2-12.4-14.2-25.2-24.7-37.8 + c-4.1-4.9-8.6-9.7-13.4-14.4c7.2-28.6-8.7-53.5-8.7-53.5c-27.5-1.7-45,8.6-51.5,13.3c-1.1-0.4-2.1-1-3.2-1.4 + c-4.7-1.8-9.5-3.7-14.5-5.2c-4.9-1.6-10-3-15.2-4.2c-5.2-1.3-10.4-2.3-15.8-3.1c-1-0.1-1.8-0.3-2.8-0.4C310.6,16.1,276.1,0,276.1,0 + c-38.5,24.4-45.7,58.5-45.7,58.5s-0.1,0.7-0.4,2c-2.1,0.6-4.2,1.3-6.3,1.8c-3,0.8-5.9,2-8.7,3.1c-3,1.1-5.8,2.3-8.7,3.5 + c-5.8,2.5-11.6,5.4-17.2,8.5c-5.5,3.1-10.9,6.5-16.1,10c-0.7-0.3-1.4-0.6-1.4-0.6C118.2,66.6,70.9,91,70.9,91 + c-4.4,56.7,21.3,92.4,26.4,98.9c-1.3,3.5-2.4,7.1-3.5,10.6c-3.9,12.8-6.9,26-8.7,39.6c-0.3,2-0.6,3.9-0.7,5.9 + c-49.4,24.4-63.9,74.2-63.9,74.2c41,47.3,89,50.2,89,50.2l0.1-0.1c6.1,10.9,13.1,21.2,21,30.9c3.4,4.1,6.8,7.9,10.4,11.7 + c-15,42.9,2.1,78.4,2.1,78.4c45.7,1.7,75.7-20,82.1-25c4.5,1.6,9.2,3,13.8,4.1c14.1,3.7,28.5,5.8,42.9,6.3 + c3.5,0.1,7.2,0.3,10.7,0.1h1.7h1.1h2.3l2.3-0.1v0.1c21.6,30.7,59.4,35.1,59.4,35.1c26.9-28.4,28.5-56.6,28.5-62.6c0,0,0-0.1,0-0.4 + c0-0.6,0-0.8,0-0.8c0-0.4,0-0.8,0-1.3c5.6-4,11-8.2,16.1-12.8c10.7-9.7,20.2-20.9,28.1-32.9c0.7-1.1,1.4-2.3,2.1-3.4 + c30.5,1.7,52-18.9,52-18.9c-5.1-31.7-23.1-47.3-26.9-50.2c0,0-0.1-0.1-0.4-0.3c-0.3-0.1-0.3-0.3-0.3-0.3c-0.1-0.1-0.4-0.3-0.7-0.4 + c0.1-2,0.3-3.8,0.4-5.8c0.3-3.4,0.3-6.9,0.3-10.3V309v-1.3v-0.7c0-0.8,0-0.6,0-0.8l-0.1-2.1l-0.1-2.8c0-1-0.1-1.8-0.3-2.7 + c-0.1-0.8-0.1-1.8-0.3-2.7l-0.3-2.7l-0.4-2.7c-0.6-3.5-1.1-6.9-2-10.4c-3.2-13.7-8.6-26.7-15.5-38.4c-7.1-11.7-15.8-22-25.8-30.7 + c-9.9-8.7-21-15.8-32.6-21c-11.7-5.2-23.8-8.6-36-10.2c-6.1-0.8-12.1-1.1-18.2-1h-2.3h-0.6h-0.7h-1l-2.3,0.1 + c-0.8,0-1.7,0.1-2.4,0.1c-3.1,0.3-6.2,0.7-9.2,1.3c-12.1,2.3-23.6,6.6-33.6,12.7c-10,6.1-18.8,13.5-25.8,22 + c-7.1,8.5-12.6,17.9-16.4,27.6s-5.9,19.9-6.5,29.6c-0.1,2.4-0.1,4.9-0.1,7.3c0,0.6,0,1.3,0,1.8l0.1,2c0.1,1.1,0.1,2.4,0.3,3.5 + c0.4,4.9,1.4,9.7,2.7,14.2c2.7,9.2,6.9,17.5,12.1,24.5c5.2,7.1,11.6,12.8,18.2,17.5c6.6,4.5,13.8,7.8,20.9,9.9 + c7.1,2.1,14.1,3,20.7,3c0.8,0,1.7,0,2.4,0c0.4,0,0.8,0,1.3,0s0.8,0,1.3-0.1c0.7,0,1.4-0.1,2.1-0.1l0.6-0.1l0.7-0.1 + c0.4,0,0.8-0.1,1.3-0.1c0.8-0.1,1.6-0.3,2.4-0.4c0.8-0.1,1.6-0.3,2.3-0.6c1.6-0.3,3-0.8,4.4-1.3c2.8-1,5.6-2.1,8-3.4 + c2.5-1.3,4.8-2.8,7.1-4.2c0.6-0.4,1.3-0.8,1.8-1.4c2.3-1.8,2.7-5.2,0.8-7.5c-1.6-2-4.4-2.5-6.6-1.3c-0.6,0.3-1.1,0.6-1.7,0.8 + c-2,1-3.9,1.8-6.1,2.5c-2.1,0.7-4.4,1.3-6.6,1.7c-1.1,0.1-2.3,0.3-3.5,0.4c-0.6,0-1.1,0.1-1.8,0.1c-0.6,0-1.3,0-1.7,0 + c-0.6,0-1.1,0-1.7,0c-0.7,0-1.4,0-2.1-0.1c0,0-0.4,0-0.1,0h-0.3h-0.4c-0.3,0-0.7,0-1-0.1c-0.7-0.1-1.3-0.1-2-0.3 + c-5.2-0.7-10.4-2.3-15.4-4.5c-5.1-2.3-9.9-5.4-14.2-9.3c-4.4-4-8.2-8.6-11.1-14c-3-5.4-5.1-11.3-6.1-17.5c-0.4-3.1-0.7-6.3-0.6-9.5 + c0-0.8,0.1-1.7,0.1-2.5c0,0.3,0-0.1,0-0.1v-0.3v-0.7c0-0.4,0.1-0.8,0.1-1.3c0.1-1.7,0.4-3.4,0.7-5.1c2.4-13.5,9.2-26.8,19.6-36.8 + c2.7-2.5,5.5-4.8,8.5-6.9c3-2.1,6.2-3.9,9.6-5.5c3.4-1.6,6.8-2.8,10.4-3.8c3.5-1,7.2-1.6,11-2c1.8-0.1,3.7-0.3,5.6-0.3 + c0.6,0,0.8,0,1.3,0h1.6h1c0.4,0,0,0,0.1,0h0.4l1.6,0.1c4.1,0.3,8,0.8,12,1.8c7.9,1.7,15.7,4.7,22.8,8.6c14.4,8,26.7,20.5,34.1,35.4 + c3.8,7.5,6.5,15.5,7.8,23.8c0.3,2.1,0.6,4.2,0.7,6.3l0.1,1.6l0.1,1.6c0,0.6,0,1.1,0,1.6c0,0.6,0,1.1,0,1.6v1.4v1.6 + c0,1-0.1,2.7-0.1,3.7c-0.1,2.3-0.4,4.7-0.7,6.9c-0.3,2.3-0.7,4.5-1.1,6.8c-0.4,2.3-1,4.5-1.6,6.6c-1.1,4.4-2.5,8.7-4.2,13.1 + c-3.4,8.5-7.9,16.6-13.3,24.1c-10.9,15-25.7,27.1-42.6,34.8c-8.5,3.8-17.3,6.6-26.5,8c-4.5,0.8-9.2,1.3-13.8,1.4h-0.8h-0.7h-1.6 + h-2.3h-1.1c0.6,0-0.1,0-0.1,0h-0.4c-2.5,0-4.9-0.1-7.5-0.4c-9.9-0.7-19.6-2.5-29.2-5.2c-9.5-2.7-18.6-6.5-27.4-11 + c-17.3-9.3-33-22-45.1-37.4c-6.1-7.6-11.4-15.9-15.8-24.5c-4.4-8.6-7.9-17.8-10.4-26.9c-2.5-9.3-4.1-18.8-4.8-28.4l-0.1-1.8v-0.4 + v-0.4v-0.8v-1.6v-0.4v-0.6v-1.1V268v-0.4c0,0,0,0.1,0-0.1v-0.8c0-1.1,0-2.4,0-3.5c0.1-4.7,0.6-9.6,1.1-14.4 + c0.6-4.8,1.4-9.7,2.4-14.5c1-4.8,2.1-9.6,3.5-14.4c2.7-9.5,6.1-18.6,10-27.2c8-17.2,18.5-32.6,31-44.9c3.1-3.1,6.3-5.9,9.7-8.7 + c3.4-2.7,6.9-5.2,10.6-7.6c3.5-2.4,7.3-4.5,11.1-6.5c1.8-1,3.8-2,5.8-2.8c1-0.4,2-0.8,3-1.3c1-0.4,2-0.8,3-1.3 + c3.9-1.7,8-3.1,12.3-4.4c1-0.3,2.1-0.6,3.1-1c1-0.3,2.1-0.6,3.1-0.8c2.1-0.6,4.2-1.1,6.3-1.6c1-0.3,2.1-0.4,3.2-0.7 + c1.1-0.3,2.1-0.4,3.2-0.7c1.1-0.1,2.1-0.4,3.2-0.6l1.6-0.3l1.7-0.3c1.1-0.1,2.1-0.3,3.2-0.4c1.3-0.1,2.4-0.3,3.7-0.4 + c1-0.1,2.7-0.3,3.7-0.4c0.7-0.1,1.6-0.1,2.3-0.3l1.6-0.1l0.7-0.1h0.8c1.3-0.1,2.4-0.1,3.7-0.3l1.8-0.1c0,0,0.7,0,0.1,0h0.4h0.8 + c1,0,2.1-0.1,3.1-0.1c4.1-0.1,8.3-0.1,12.4,0c8.2,0.3,16.2,1.3,24,2.7c15.7,3,30.3,7.9,43.7,14.5c13.4,6.5,25.2,14.5,35.7,23.3 + c0.7,0.6,1.3,1.1,2,1.7c0.6,0.6,1.3,1.1,1.8,1.7c1.3,1.1,2.4,2.3,3.7,3.4c1.3,1.1,2.4,2.3,3.5,3.4c1.1,1.1,2.3,2.3,3.4,3.5 + c4.4,4.7,8.5,9.3,12.1,14.1c7.3,9.5,13.3,19,17.9,28.1c0.3,0.6,0.6,1.1,0.8,1.7s0.6,1.1,0.8,1.7c0.6,1.1,1.1,2.3,1.6,3.4 + c0.6,1.1,1,2.1,1.6,3.2c0.4,1.1,1,2.1,1.4,3.2c1.7,4.2,3.4,8.3,4.7,12.1c2.1,6.2,3.7,11.7,4.9,16.5c0.4,2,2.3,3.2,4.2,3 + c2.1-0.1,3.7-1.8,3.7-3.9C491.7,238.9,491.5,232.9,490.8,226z"/> +</g> +</svg> diff --git a/src/components/UserModal/consts.ts b/src/components/UserModal/consts.ts index b0b0deaeaa38070dcdb50f6d53b7ee831732b827..8f2aa98a9d0476e55523c9c184a79d3a638ee67f 100644 --- a/src/components/UserModal/consts.ts +++ b/src/components/UserModal/consts.ts @@ -5,28 +5,24 @@ export const appAccessList = [ name: 'wekan', image: '/assets/wekan.svg', label: 'Wekan', - defaultSubdomain: 'wekan.{domain}', documentationUrl: 'https://github.com/wekan/wekan/wiki', }, { name: 'wordpress', image: '/assets/wordpress.svg', label: 'Wordpress', - defaultSubdomain: 'www.{domain}', documentationUrl: 'https://wordpress.org/support/', }, { name: 'nextcloud', image: '/assets/nextcloud.svg', label: 'Nextcloud', - defaultSubdomain: 'files.{domain}', documentationUrl: 'https://docs.nextcloud.com/server/latest/user_manual/en/', }, { name: 'zulip', image: '/assets/zulip.svg', label: 'Zulip', - defaultSubdomain: 'zulip.{domain}', documentationUrl: 'https://docs.zulip.com/help/', }, ]; diff --git a/src/modules/apps/components/AppInstallModal/AppInstallModal.tsx b/src/modules/apps/components/AppInstallModal/AppInstallModal.tsx index 57bca8ad7339ef6a22af198ae213fe84b597b499..14e0b1a11f601e23d885149ae18d762ccf48c330 100644 --- a/src/modules/apps/components/AppInstallModal/AppInstallModal.tsx +++ b/src/modules/apps/components/AppInstallModal/AppInstallModal.tsx @@ -4,7 +4,6 @@ import _ from 'lodash'; import { App, useApps } from 'src/services/apps'; import { Modal } from 'src/components'; import { Input } from 'src/components/Form'; -import { appAccessList } from 'src/components/UserModal/consts'; import { AppInstallModalProps } from './types'; import { initialAppForm, initialCode } from './consts'; @@ -16,8 +15,6 @@ export const AppInstallModal = ({ open, onClose, appSlug }: AppInstallModalProps defaultValues: initialAppForm, }); - const getDefaultSubdomain = () => _.get(_.find(appAccessList, ['name', appSlug]), 'defaultSubdomain', ''); - useEffect(() => { if (appSlug) { loadApp(appSlug); @@ -32,11 +29,11 @@ export const AppInstallModal = ({ open, onClose, appSlug }: AppInstallModalProps useEffect(() => { if (!_.isEmpty(app)) { setAppName(app.name); - reset({ subdomain: getDefaultSubdomain(), configuration: initialCode, slug: appSlug ?? '' }); + reset({ url: app.url, configuration: initialCode, slug: appSlug ?? '' }); } return () => { - reset({ subdomain: getDefaultSubdomain(), configuration: initialCode, slug: appSlug ?? '' }); + reset({ url: initialAppForm.url, configuration: initialCode, slug: appSlug ?? '' }); }; // eslint-disable-next-line react-hooks/exhaustive-deps }, [app, reset, open]); @@ -73,13 +70,7 @@ export const AppInstallModal = ({ open, onClose, appSlug }: AppInstallModalProps <div className="mt-6 grid grid-cols-1 gap-y-6 gap-x-4 sm:grid-cols-6"> <div className="sm:col-span-3"> - <Input - control={control} - name="subdomain" - label="Subdomain" - onKeyPress={handleKeyPress} - required={false} - /> + <Input control={control} name="url" label="URL" onKeyPress={handleKeyPress} required={false} /> </div> </div> </div> diff --git a/src/modules/apps/components/AppInstallModal/consts.ts b/src/modules/apps/components/AppInstallModal/consts.ts index c3d5fa9dc111f7caef2e2592db075b9e9680dd80..22a30bcef0eb0be688147dcdfaf9f6ad6e7d1b47 100644 --- a/src/modules/apps/components/AppInstallModal/consts.ts +++ b/src/modules/apps/components/AppInstallModal/consts.ts @@ -23,5 +23,5 @@ search: great: stomach`; export const initialAppForm = { - subdomain: '', + url: '', } as App; diff --git a/src/modules/dashboard/Dashboard.tsx b/src/modules/dashboard/Dashboard.tsx index 959b99fd1d608e9ac1546bea7cf5c106370581f9..612cc3922fc40d498e79293b08829bd2a96bf6b2 100644 --- a/src/modules/dashboard/Dashboard.tsx +++ b/src/modules/dashboard/Dashboard.tsx @@ -1,13 +1,22 @@ -import React from 'react'; +/* eslint-disable react-hooks/exhaustive-deps */ +import React, { useEffect } from 'react'; import clsx from 'clsx'; -import { DASHBOARD_APPS, DASHBOARD_QUICK_ACCESS } from './consts'; +import { useApps } from 'src/services/apps'; +// import { DASHBOARD_QUICK_ACCESS } from './consts'; import { DashboardCard } from './components'; export const Dashboard: React.FC = () => { const host = window.location.hostname; const splitedDomain = host.split('.'); splitedDomain.shift(); - const rootDomain = splitedDomain.join('.'); + const { apps, appTableLoading, loadApps } = useApps(); + + // Tell React to load the apps + useEffect(() => { + loadApps(); + + return () => {}; + }, []); return ( <div className="relative"> @@ -19,37 +28,11 @@ 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="grid grid-cols-1 md:grid-cols-2 md:gap-4 lg:grid-cols-4 mb-10"> - {DASHBOARD_APPS(rootDomain!).map((app) => ( - <DashboardCard app={app} key={app.name} /> - ))} - </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(rootDomain!).map((item) => ( - <a - href={item.url} - key={item.name} - target="_blank" - rel="noreferrer" - className={clsx('bg-white rounded-lg overflow-hidden sm:p-2 flex items-center group', { - 'opacity-40 cursor-default': !item.active, - })} - > - <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 className="h-6 w-6 text-primary-900" aria-hidden="true" /> - </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">{item.description}</dd> - </div> - </a> + {apps + .filter((app) => app.slug !== 'dashboard') + .map((app) => ( + <DashboardCard app={app} key={app.name} /> ))} - </dl> </div> </div> </div> diff --git a/src/modules/dashboard/components/DashboardCard/DashboardCard.tsx b/src/modules/dashboard/components/DashboardCard/DashboardCard.tsx index d8142e06151e6da786a18dbd77ab253d251dc089..1b9b820090d41765ab6ba4bb21181eb0776aee6c 100644 --- a/src/modules/dashboard/components/DashboardCard/DashboardCard.tsx +++ b/src/modules/dashboard/components/DashboardCard/DashboardCard.tsx @@ -25,7 +25,7 @@ export const DashboardCard: React.FC<any> = ({ app }: { app: any }) => { <img className="h-16 w-16 rounded-md overflow-hidden mr-4 flex-shrink-0" src={app.assetSrc} - alt="Nextcloud" + alt={app.name} /> <div> diff --git a/src/services/apps/redux/reducers.ts b/src/services/apps/redux/reducers.ts index e3031536ceb169397e868965891b3d87077d78cd..26736ae5e20562473e84116c2d59737d50238756 100644 --- a/src/services/apps/redux/reducers.ts +++ b/src/services/apps/redux/reducers.ts @@ -1,13 +1,13 @@ import { AppActionTypes } from './actions'; -const initialUsersState: any = { - users: [], - user: {}, - userModalLoading: false, - usersLoading: false, +const initialAppsState: any = { + apps: [], + app: {}, + appModalLoading: false, + appsLoading: false, }; -const appsReducer = (state: any = initialUsersState, action: any) => { +const appsReducer = (state: any = initialAppsState, action: any) => { switch (action.type) { case AppActionTypes.FETCH_APPS: return { diff --git a/src/services/apps/transformations.ts b/src/services/apps/transformations.ts index aa4f0ede8ae8ca21f490b3eb8cfca69ec3ea9ae1..6542336f905d04827223ec23f0821f9ba2e9ab43 100644 --- a/src/services/apps/transformations.ts +++ b/src/services/apps/transformations.ts @@ -2,14 +2,14 @@ import { App, AppStatus } from './types'; const transformAppStatus = (status: string) => { switch (status) { - case 'installed': + case 'App installed and running': return AppStatus.Installed; - case 'installing': - return AppStatus.Installing; - case 'not_installed': + case 'Not installed': return AppStatus.NotInstalled; + // For now default to "Installing" status for any app that isn't installed + // or not installed. Could also mean "upgrading", or "broken"... default: - return AppStatus.NotInstalled; + return AppStatus.Installing; } }; @@ -19,8 +19,10 @@ export const transformApp = (response: any): App => { name: response.name ?? '', slug: response.slug ?? '', status: transformAppStatus(response.status), - subdomain: response.subdomain, + url: response.url, automaticUpdates: response.automatic_updates, + assetSrc: `/assets/${response.slug}.svg`, + markdownSrc: `/markdown/${response.slug}.md`, }; }; @@ -33,7 +35,7 @@ export const transformAppRequest = (data: App) => { export const transformInstallAppRequest = (data: App) => { return { - subdomain: data.subdomain, + url: data.url, configuration: data.configuration, }; }; diff --git a/src/services/apps/types.ts b/src/services/apps/types.ts index 317f1718be6db86dcd0006fed0f978c60f6b548d..17708b1f92726d1964421315b536efb91759f6c4 100644 --- a/src/services/apps/types.ts +++ b/src/services/apps/types.ts @@ -3,9 +3,11 @@ export interface App { name: string; slug: string; status?: AppStatus; - subdomain?: string; + url: string; automaticUpdates: boolean; configuration?: string; + assetSrc?: string; + markdownSrc?: string; } export interface DisableAppForm { diff --git a/yarn.lock b/yarn.lock index 7eefd82bcb4976b58fbe32bba31690447d13c118..b8d82ca5206b4926492578ea8023735d190bd99c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1862,6 +1862,11 @@ jest-diff "^26.0.0" pretty-format "^26.0.0" +"@types/js-yaml@^4.0.5": + version "4.0.5" + resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-4.0.5.tgz#738dd390a6ecc5442f35e7f03fa1431353f7e138" + integrity sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA== + "@types/json-schema@*", "@types/json-schema@^7.0.3", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8": version "7.0.9" resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz"