First pass at new server console design

This commit is contained in:
DaneEveritt 2022-06-20 17:26:47 -04:00
parent 61018b5e67
commit faff263f17
No known key found for this signature in database
GPG key ID: EEA66103B3D71F53
9 changed files with 263 additions and 189 deletions

View file

@ -0,0 +1,73 @@
import React, { useState } from 'react';
import { Button } from '@/components/elements/button/index';
import Can from '@/components/elements/Can';
import { ServerContext } from '@/state/server';
import { PowerAction } from '@/components/server/ServerConsole';
import { Dialog } from '@/components/elements/dialog';
interface PowerButtonProps {
className?: string;
}
export default ({ className }: PowerButtonProps) => {
const [ open, setOpen ] = useState(false);
const status = ServerContext.useStoreState(state => state.status.value);
const instance = ServerContext.useStoreState(state => state.socket.instance);
const killable = status === 'stopping';
const onButtonClick = (action: PowerAction | 'kill-confirmed', e: React.MouseEvent<HTMLButtonElement, MouseEvent>): void => {
e.preventDefault();
if (action === 'kill') {
return setOpen(true);
}
if (instance) {
setOpen(false);
instance.send('set state', action === 'kill-confirmed' ? 'kill' : action);
}
};
return (
<div className={className}>
<Dialog.Confirm
open={open}
hideCloseIcon
onClose={() => setOpen(false)}
title={'Forcibly Stop Process'}
confirm={'Continue'}
onConfirmed={onButtonClick.bind(this, 'kill-confirmed')}
>
Forcibly stopping a server can lead to data corruption.
</Dialog.Confirm>
<Can action={'control.start'}>
<Button
className={'w-24'}
disabled={status !== 'offline'}
onClick={onButtonClick.bind(this, 'start')}
>
Start
</Button>
</Can>
<Can action={'control.restart'}>
<Button.Text
className={'w-24'}
variant={Button.Variants.Secondary}
disabled={!status}
onClick={onButtonClick.bind(this, 'restart')}
>
Restart
</Button.Text>
</Can>
<Can action={'control.stop'}>
<Button.Danger
className={'w-24'}
variant={killable ? undefined : Button.Variants.Secondary}
disabled={status === 'offline'}
onClick={onButtonClick.bind(this, killable ? 'kill' : 'stop')}
>
{killable ? 'Kill' : 'Stop'}
</Button.Danger>
</Can>
</div>
);
};

View file

@ -0,0 +1,46 @@
import React from 'react';
import Icon from '@/components/elements/Icon';
import { IconDefinition } from '@fortawesome/free-solid-svg-icons';
import classNames from 'classnames';
import Tooltip from '@/components/elements/tooltip/Tooltip';
interface StatBlockProps {
title: string;
description?: string;
color?: string | undefined;
icon: IconDefinition;
children: React.ReactNode;
}
export default ({ title, icon, color, description, children }: StatBlockProps) => {
return (
<Tooltip arrow placement={'top'} disabled={!description} content={description || ''}>
<div className={'flex items-center space-x-4 bg-gray-600 rounded p-4 shadow-lg'}>
<div
className={classNames(
'transition-colors duration-500',
'flex-shrink-0 flex items-center justify-center w-12 h-12 rounded-lg shadow-md',
color || 'bg-gray-700',
)}
>
<Icon
icon={icon}
className={classNames(
'w-6 h-6 m-auto',
{
'text-gray-100': !color || color === 'bg-gray-700',
'text-gray-50': color && color !== 'bg-gray-700',
},
)}
/>
</div>
<div className={'flex flex-col justify-center overflow-hidden'}>
<p className={'font-header leading-tight text-sm text-gray-200'}>{title}</p>
<p className={'text-xl font-semibold text-gray-50 truncate'}>
{children}
</p>
</div>
</div>
</Tooltip>
);
};