add-frames #1
5 changed files with 34 additions and 88 deletions
32
src/App.tsx
32
src/App.tsx
|
@ -1,36 +1,26 @@
|
||||||
import React, { createContext } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import { Helmet } from 'react-helmet';
|
import { Helmet } from 'react-helmet';
|
||||||
import { Toaster } from 'react-hot-toast';
|
import { Toaster } from 'react-hot-toast';
|
||||||
import { Navigate, Route, Routes } from 'react-router-dom';
|
import { Navigate, Route, Routes } from 'react-router-dom';
|
||||||
|
|
||||||
import { fetchApps } from './services/apps/api';
|
|
||||||
import { Layout } from './components';
|
import { Layout } from './components';
|
||||||
import { Dashboard } from './modules';
|
import { Dashboard } from './modules';
|
||||||
import { AppIframe } from './modules/dashboard/AppIframe';
|
import { AppIframe } from './modules/dashboard/AppIframe';
|
||||||
|
import { useApps } from './services/apps';
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
function App() {
|
function App() {
|
||||||
const host = window.location.hostname;
|
const host = window.location.hostname;
|
||||||
const splitedDomain = host.split('.');
|
const splitedDomain = host.split('.');
|
||||||
splitedDomain.shift();
|
splitedDomain.shift();
|
||||||
const rootDomain = splitedDomain.join('.');
|
const { apps, loadApps } = useApps();
|
||||||
// @ts-ignore
|
|
||||||
const DASHBOARD_APPS = [
|
useEffect(() => {
|
||||||
{
|
if (apps.length === 0) {
|
||||||
id: '1',
|
loadApps();
|
||||||
name: 'Dateiablage',
|
}
|
||||||
assetSrc: '/assets/nextcloud.svg',
|
}, [loadApps, apps.length]);
|
||||||
internalUrl: `files`,
|
|
||||||
externalUrl: `https://cloud`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '2',
|
|
||||||
name: 'Projektboard',
|
|
||||||
assetSrc: '/assets/vikunja.png',
|
|
||||||
internalUrl: `projects`,
|
|
||||||
externalUrl: `https://vikunja`,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Helmet>
|
<Helmet>
|
||||||
|
@ -50,7 +40,7 @@ function App() {
|
||||||
<Route path="/dashboard" element={<Dashboard />} />
|
<Route path="/dashboard" element={<Dashboard />} />
|
||||||
{
|
{
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
DASHBOARD_APPS.map((app) => (
|
apps.map((app) => (
|
||||||
<Route key={app.name} path={app.internalUrl} element={<AppIframe app={app} />} />
|
<Route key={app.name} path={app.internalUrl} element={<AppIframe app={app} />} />
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,31 +3,14 @@ import { Disclosure } from '@headlessui/react';
|
||||||
import { MenuIcon, XIcon } from '@heroicons/react/outline';
|
import { MenuIcon, XIcon } from '@heroicons/react/outline';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { Link, useLocation } from 'react-router-dom';
|
import { Link, useLocation } from 'react-router-dom';
|
||||||
import { fetchApps } from '../../services/apps/api';
|
import { useApps } from 'src/services/apps';
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||||
interface HeaderProps {}
|
interface HeaderProps {}
|
||||||
|
|
||||||
const Header: React.FC<HeaderProps> = () => {
|
const Header: React.FC<HeaderProps> = () => {
|
||||||
const { pathname } = useLocation();
|
const { pathname } = useLocation();
|
||||||
const rootDomain = 'foobar';
|
const { apps, loadApps, appTableLoading } = useApps();
|
||||||
// @ts-ignore
|
|
||||||
const DASHBOARD_APPS = [
|
|
||||||
{
|
|
||||||
id: '1',
|
|
||||||
name: 'Dateiablage',
|
|
||||||
assetSrc: '/assets/nextcloud.svg',
|
|
||||||
internalUrl: `files`,
|
|
||||||
externalUrl: `https://cloud`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '2',
|
|
||||||
name: 'Projektboard',
|
|
||||||
assetSrc: '/assets/vikunja.png',
|
|
||||||
internalUrl: `projects`,
|
|
||||||
externalUrl: `https://vikunja`,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -54,9 +37,7 @@ const Header: React.FC<HeaderProps> = () => {
|
||||||
</Link>
|
</Link>
|
||||||
<div className="hidden sm:ml-6 sm:flex sm:space-x-8">
|
<div className="hidden sm:ml-6 sm:flex sm:space-x-8">
|
||||||
{/* Current: "border-primary-500 text-gray-900", Default: "border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700" */}
|
{/* Current: "border-primary-500 text-gray-900", Default: "border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700" */}
|
||||||
{
|
{apps.map((app) => (
|
||||||
// @ts-ignore
|
|
||||||
DASHBOARD_APPS.map((app) => (
|
|
||||||
<Link
|
<Link
|
||||||
key={app.name}
|
key={app.name}
|
||||||
to={app.internalUrl}
|
to={app.internalUrl}
|
||||||
|
@ -70,8 +51,7 @@ const Header: React.FC<HeaderProps> = () => {
|
||||||
>
|
>
|
||||||
{app.name}
|
{app.name}
|
||||||
</Link>
|
</Link>
|
||||||
))
|
))}
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -81,7 +61,7 @@ const Header: React.FC<HeaderProps> = () => {
|
||||||
<div className="pt-2 pb-4 space-y-1">
|
<div className="pt-2 pb-4 space-y-1">
|
||||||
{
|
{
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
DASHBOARD_APPS.map((app) => (
|
apps.map((app) => (
|
||||||
<Link
|
<Link
|
||||||
key={app.name}
|
key={app.name}
|
||||||
to={app.internalUrl}
|
to={app.internalUrl}
|
||||||
|
|
|
@ -1,14 +1,9 @@
|
||||||
import React, { useEffect } from 'react';
|
import React from 'react';
|
||||||
import { useApps } from 'src/services/apps';
|
import { useApps } from 'src/services/apps';
|
||||||
import { DashboardCard } from './components';
|
import { DashboardCard } from './components';
|
||||||
|
|
||||||
export const Dashboard: React.FC = () => {
|
export const Dashboard: React.FC = () => {
|
||||||
const { apps, loadApps, appTableLoading } = useApps();
|
const { apps, appTableLoading } = useApps();
|
||||||
const foo = 42;
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
loadApps();
|
|
||||||
}, [foo]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
|
@ -19,9 +14,7 @@ export const Dashboard: React.FC = () => {
|
||||||
</div>
|
</div>
|
||||||
<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">
|
||||||
{!appTableLoading &&
|
{!appTableLoading && apps.map((app) => <DashboardCard app={app} key={app.name} />)}
|
||||||
// @ts-ignore
|
|
||||||
apps.map((app) => <DashboardCard app={app} key={app.name} />)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { env } from '../../env';
|
import { env } from '../../env';
|
||||||
import { createApiCall, performApiCall } from '../api';
|
import { performApiCall } from '../api';
|
||||||
import { transformApp } from './transformations';
|
import { transformApp } from './transformations';
|
||||||
import { App } from './types';
|
import { App } from './types';
|
||||||
|
|
||||||
|
@ -8,20 +8,4 @@ export const fetchApps = async (): Promise<App> => {
|
||||||
|
|
||||||
const res = await performApiCall({ hostname: apiUrl, path: '/apps', method: 'GET' });
|
const res = await performApiCall({ hostname: apiUrl, path: '/apps', method: 'GET' });
|
||||||
return transformApp(res);
|
return transformApp(res);
|
||||||
// return new Promise(() => [
|
|
||||||
// {
|
|
||||||
// id: '1',
|
|
||||||
// name: 'Dateiablage',
|
|
||||||
// assetSrc: '/assets/nextcloud.svg',
|
|
||||||
// internalUrl: `files`,
|
|
||||||
// externalUrl: `https://cloud`,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// id: '2',
|
|
||||||
// name: 'Projektboard',
|
|
||||||
// assetSrc: '/assets/vikunja.png',
|
|
||||||
// internalUrl: `projects`,
|
|
||||||
// externalUrl: `https://vikunja`,
|
|
||||||
// },
|
|
||||||
// ]);
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
import _ from 'lodash';
|
|
||||||
import { App } from './types';
|
import { App } from './types';
|
||||||
|
|
||||||
export const transformApp = (response: any): App => {
|
export const transformApp = (response: any): App => {
|
||||||
return {
|
return {
|
||||||
id: response.id ?? '',
|
id: response.id ?? '',
|
||||||
name: response.name ?? '',
|
name: response.name ?? '',
|
||||||
assetSrc: response.icon ?? '',
|
assetSrc: response.assetSrc ?? '',
|
||||||
internalUrl: response.internalUrl ?? '',
|
internalUrl: response.internalUrl ?? '',
|
||||||
externalUrl: response.externalUrl ?? '',
|
externalUrl: response.externalUrl ?? '',
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue