Skip to content
Snippets Groups Projects
Commit ac5e4e36 authored by Tin Geber's avatar Tin Geber
Browse files

moved UpdateAlert and VersionInfo to components

parent d9da3b6c
No related branches found
No related tags found
No related merge requests found
......@@ -14,6 +14,7 @@
# local environment
/frontend/local.env
/.vscode
# misc
.DS_Store
......
......@@ -10,20 +10,7 @@ import React, { useEffect } from 'react';
import { useApps } from 'src/services/apps';
import { useSysInfo } from 'src/services/sysInfo';
import { AppStatusEnum } from 'src/services/apps/types';
import { Popover, Transition } from '@headlessui/react';
import {
CheckCircleIcon,
NewspaperIcon,
SparklesIcon,
LightningBoltIcon,
ChevronDownIcon,
CalendarIcon,
BeakerIcon,
HomeIcon,
RefreshIcon,
} from '@heroicons/react/outline';
// import systemInfo from './systemInfo.json';
import { DashboardCard, DashboardUtility } from './components';
import { DashboardCard, DashboardUtility, UpdateAlert, VersionInfo } from './components';
import { DASHBOARD_QUICK_ACCESS, HIDDEN_APPS, UTILITY_APPS } from './consts';
export const Dashboard: React.FC = () => {
......@@ -43,140 +30,19 @@ export const Dashboard: React.FC = () => {
const appVersions = { ...sysInfo.sysInfo.appVersions };
const updateTime: Date = new Date(sysInfo.sysInfo.lastUpdated);
const hoursSinceUpdate = Math.floor((new Date().getTime() - updateTime.getTime()) / 3600000);
// manual toggles to test alert bar
// const hoursSinceUpdate = 21;
// const lastRelease = sysInfo.sysInfo.lastRelease;
const updateStatus =
sysInfo.sysInfo.lastRelease > sysInfo.sysInfo.version ? 'imminent' : hoursSinceUpdate <= 24 ? 'updated' : 'no';
// the update alert box has two states: when the latest version
// on the v2 branch is more recent than the current one, the yellow alert bar
// shows that an update will happen in the next 24 hours.
// After the update, a green alert bar shows with a success message
// and stays there for 24 hours
const updateAlert = (status: string) =>
status === 'imminent' ? (
<div className="update-alert w-full h-5 py-3 bg-yellow-100 flex items-center justify-center text-xs font-medium text-gray-500 gap-2">
<LightningBoltIcon className="h-4 w-4 text-primary-800" />
<p>Attention: your Stackspin instance will be updated in the next 24 hours. </p>
<a
className="hover:text-primary-500 underline"
href={sysInfo.sysInfo.releaseNotesUrl}
target="_blank"
rel="noreferrer noopener"
>
Explore new features <NewspaperIcon className="h-4 w-4 inline" />
</a>
</div>
) : status === 'updated' ? (
<div className="update-alert w-full h-5 py-3 bg-primary-200 flex items-center justify-center text-xs font-medium text-primary-700 gap-2">
<SparklesIcon className="h-4 w-4 text-primary-800" />
<p>Your Stackspin just got an update!</p>
<a
className="hover:text-primary-500 underline"
href={sysInfo.sysInfo.releaseNotesUrl}
target="_blank"
rel="noreferrer noopener"
>
See what&apos;s new <NewspaperIcon className="h-4 w-4 inline" />
</a>
</div>
) : null;
const branch = sysInfo.sysInfo.followingGit;
// eslint-disable-next-line
// let branch = 'DF234FD';
const knownMainBranch = 'v2';
const versionInfo =
branch === knownMainBranch ? (
<>
<CheckCircleIcon className="h-4 w-4 text-primary-600" />
<span>Stackspin v{sysInfo.sysInfo.version}</span>
</>
) : branch !== knownMainBranch ? (
<>
<span>Stackspin v{sysInfo.sysInfo.version}</span>
</>
) : null;
const updatesText =
branch === knownMainBranch ? (
<>
<div className="px-4 py-2 flex items-center gap-1">
<HomeIcon className="w-4 h-4 text-gray-500" />
<span>Using main branch ({branch})</span>
</div>
<div className="px-4 py-2 flex items-center gap-1">
<RefreshIcon className="w-4 h-4 text-gray-500" />
<span>Automatic updates active</span>
</div>
</>
) : branch !== knownMainBranch ? (
<div className="px-4 py-2 flex items-center gap-1">
<BeakerIcon className="w-4 h-4 text-gray-500" />
<span>Custom branch ({branch})</span>
</div>
) : null;
return (
<div className="relative">
{updateAlert(updateStatus)}
<UpdateAlert sysInfo={sysInfo.sysInfo} />
<div className="max-w-7xl mx-auto py-4 px-3 sm:px-6 lg:px-8">
<div className="mt-6 pb-5 border-b border-gray-200 sm:flex sm:items-center sm:justify-between">
<h1 className="text-3xl leading-6 font-bold text-gray-900">Dashboard</h1>
<div className="system-status text-xs font-medium text-gray-500 flex flex-col gap-2">
<div className="flex items-center gap-1">
<Popover className="relative flex items-center">
<Popover.Button className="flex text-sm px-2.5 py-1.5 group items-center gap-1 border border-transparent hover:shadow-sm focus:shadow-sm font-medium rounded-md text-gray-500 hover:bg-gray-100 focus:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">
{versionInfo}
<ChevronDownIcon className="h-4 w-4 text-primary-800" />
</Popover.Button>
<Transition
enter="transition ease-out duration-200"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-75"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
<Popover.Panel className="absolute z-10 origin-top-right right-0 top-5 mt-2 rounded-md shadow-lg py-1 bg-white ring-1 ring-black ring-opacity-5 focus:outline-none">
<div className="flex flex-col items-stretch p-4 w-60 divide-y divide-gray-100 text-xs text-gray-500">
{updatesText}
<div className="px-4 py-2 flex items-center gap-1">
<NewspaperIcon className="h-4 w-4 text-gray-500" />
<a
className="hover:text-primary-500 underline"
href={sysInfo.sysInfo.releaseNotesUrl}
target="_blank"
rel="noreferrer noopener"
>
Changelog
</a>
</div>
<div className="px-4 py-2 flex items-center gap-1">
<CalendarIcon className="h-4 w-4 text-gray-500" />
<span>Last update:</span>
<span>
{/* {updateTime.getDate()}.{updateTime.getMonth()} {updateTime.getFullYear()} */}
{updateTime.toLocaleDateString('en-uk', { day: 'numeric', year: 'numeric', month: 'short' })}
</span>
</div>
</div>
</Popover.Panel>
</Transition>
</Popover>
<VersionInfo sysInfo={sysInfo.sysInfo} />
</div>
</div>
</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="grid grid-cols-1 md:grid-cols-2 md:gap-4 lg:grid-cols-4 mb-10">
{apps
......@@ -191,7 +57,6 @@ export const Dashboard: React.FC = () => {
<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} />
......
import React from 'react';
import { LightningBoltIcon, NewspaperIcon, SparklesIcon } from '@heroicons/react/outline';
import { SysInfoState } from 'src/services/sysInfo/redux/types';
export const UpdateAlert = (sysInfo: SysInfoState) => {
const updateTime: Date = new Date(sysInfo.sysInfo.lastUpdated);
const hoursSinceUpdate = Math.floor((new Date().getTime() - updateTime.getTime()) / 3600000);
const updateStatus: string =
sysInfo.sysInfo.lastRelease > sysInfo.sysInfo.version ? 'imminent' : hoursSinceUpdate <= 24 ? 'updated' : 'no';
const updateAlert = (status: string) =>
status === 'imminent' ? (
<div className="update-alert w-full h-5 py-3 bg-yellow-100 flex items-center justify-center text-xs font-medium text-gray-500 gap-2">
<LightningBoltIcon className="h-4 w-4 text-primary-800" />
<p>Attention: your Stackspin instance will be updated in the next 24 hours. </p>
<a
className="hover:text-primary-500 underline"
href={sysInfo.sysInfo.releaseNotesUrl}
target="_blank"
rel="noreferrer noopener"
>
Explore new features <NewspaperIcon className="h-4 w-4 inline" />
</a>
</div>
) : status === 'updated' ? (
<div className="update-alert w-full h-5 py-3 bg-primary-200 flex items-center justify-center text-xs font-medium text-primary-700 gap-2">
<SparklesIcon className="h-4 w-4 text-primary-800" />
<p>Your Stackspin just got an update!</p>
<a
className="hover:text-primary-500 underline"
href={sysInfo.sysInfo.releaseNotesUrl}
target="_blank"
rel="noreferrer noopener"
>
See what&apos;s new <NewspaperIcon className="h-4 w-4 inline" />
</a>
</div>
) : null;
return <>{updateAlert('imminent')}</>;
};
export { UpdateAlert } from './UpdateAlert';
import React from 'react';
import { Popover, Transition } from '@headlessui/react';
import {
CheckCircleIcon,
NewspaperIcon,
ChevronDownIcon,
CalendarIcon,
BeakerIcon,
HomeIcon,
RefreshIcon,
} from '@heroicons/react/outline';
import { SysInfoState } from 'src/services/sysInfo/redux/types';
export const VersionInfo = (sysInfo: SysInfoState) => {
const branch = sysInfo.sysInfo.followingGit;
const updateTime: Date = new Date(sysInfo.sysInfo.lastUpdated);
// eslint-disable-next-line
// let branch = 'DF234FD';
const knownMainBranch = 'v2';
const versionInfo =
branch === knownMainBranch ? (
<>
<CheckCircleIcon className="h-4 w-4 text-primary-600" />
<span>Stackspin v{sysInfo.sysInfo.version}</span>
</>
) : branch !== knownMainBranch ? (
<>
<span>Stackspin v{sysInfo.sysInfo.version}</span>
</>
) : null;
const updatesText =
branch === knownMainBranch ? (
<>
<div className="px-4 py-2 flex items-center gap-1">
<HomeIcon className="w-4 h-4 text-gray-500" />
<span>Using main branch ({branch})</span>
</div>
<div className="px-4 py-2 flex items-center gap-1">
<RefreshIcon className="w-4 h-4 text-gray-500" />
<span>Automatic updates active</span>
</div>
</>
) : branch !== knownMainBranch ? (
<div className="px-4 py-2 flex items-center gap-1">
<BeakerIcon className="w-4 h-4 text-gray-500" />
<span>Custom branch ({branch})</span>
</div>
) : null;
return (
<Popover className="relative flex items-center">
<Popover.Button className="flex text-sm px-2.5 py-1.5 group items-center gap-1 border border-transparent hover:shadow-sm focus:shadow-sm font-medium rounded-md text-gray-500 hover:bg-gray-100 focus:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">
{versionInfo}
<ChevronDownIcon className="h-4 w-4 text-primary-800" />
</Popover.Button>
<Transition
enter="transition ease-out duration-200"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-75"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
<Popover.Panel className="absolute z-10 origin-top-right right-0 top-5 mt-2 rounded-md shadow-lg py-1 bg-white ring-1 ring-black ring-opacity-5 focus:outline-none">
<div className="flex flex-col items-stretch p-4 w-60 divide-y divide-gray-100 text-xs text-gray-500">
{updatesText}
<div className="px-4 py-2 flex items-center gap-1">
<NewspaperIcon className="h-4 w-4 text-gray-500" />
<a
className="hover:text-primary-500 underline"
href={sysInfo.sysInfo.releaseNotesUrl}
target="_blank"
rel="noreferrer noopener"
>
Changelog
</a>
</div>
<div className="px-4 py-2 flex items-center gap-1">
<CalendarIcon className="h-4 w-4 text-gray-500" />
<span>Last update:</span>
<span>
{/* {updateTime.getDate()}.{updateTime.getMonth()} {updateTime.getFullYear()} */}
{updateTime.toLocaleDateString('en-uk', { day: 'numeric', year: 'numeric', month: 'short' })}
</span>
</div>
</div>
</Popover.Panel>
</Transition>
</Popover>
);
};
export { VersionInfo } from './VersionInfo';
export { DashboardCard } from './DashboardCard';
export { DashboardUtility } from './DashboardUtility';
export { UpdateAlert } from './UpdateAlert';
export { VersionInfo } from './VersionInfo';
{
"appVersions": {
"dashboard": "0.6.5",
"nextcloud": "25.0.4",
"velero": "1.9.4",
"wekan": "5.93",
"wordpress": "6.0.1",
"zulip": "6.0",
"hedgedoc": "4.2"
},
"lastRelease": "2.4",
"lastUpdated": "2023-03-16T11:41:24Z",
"releaseNotesUrl": "https://open.greenhost.net/stackspin/stackspin/-/blob/main/CHANGELOG.md#anchor-24",
"version": "2.4"
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment