feat(ui): health status widget

This commit is contained in:
nick-delirium 2023-02-17 12:30:20 +01:00 committed by Delirium
parent 09e788a29f
commit b2ce9a7aff
11 changed files with 411 additions and 4 deletions

View file

@ -19,6 +19,7 @@ import UserMenu from './UserMenu';
import SettingsMenu from './SettingsMenu'; import SettingsMenu from './SettingsMenu';
import DefaultMenuView from './DefaultMenuView'; import DefaultMenuView from './DefaultMenuView';
import PreferencesView from './PreferencesView'; import PreferencesView from './PreferencesView';
import HealthStatus from './HealthStatus'
const CLIENT_PATH = client(CLIENT_DEFAULT_TAB); const CLIENT_PATH = client(CLIENT_DEFAULT_TAB);
@ -78,6 +79,8 @@ const Header = (props) => {
</Tooltip> </Tooltip>
</div> </div>
<HealthStatus />
<div className={cn(styles.userDetails, 'group cursor-pointer')}> <div className={cn(styles.userDetails, 'group cursor-pointer')}>
<div className="flex items-center"> <div className="flex items-center">
<div className="w-10 h-10 bg-tealx rounded-full flex items-center justify-center color-white"> <div className="w-10 h-10 bg-tealx rounded-full flex items-center justify-center color-white">

View file

@ -0,0 +1,38 @@
import React from 'react';
import { Icon } from 'UI';
function Footer() {
return (
<div className={'flex w-full p-4 items-center justify-center bg-gray-lightest gap-4'}>
<a
href={'https://docs.openreplay.com/en/troubleshooting/'}
target="_blank"
rel="noreferrer noopener"
className={'flex items-center gap-2 hover:underline'}
>
<Icon name={'tools'} size={16} />
Troubleshooting guide
</a>
<a
href={'https://slack.openreplay.com/'}
target="_blank"
rel="noreferrer noopener"
className={'flex items-center gap-2 hover:underline'}
>
<Icon name={'slack'} size={16} />
Ask slack community
</a>
<a
href={'https://github.com/openreplay/openreplay/issues/new/choose'}
target="_blank"
rel="noreferrer noopener"
className={'flex items-center gap-2 hover:underline'}
>
<Icon name={'github'} size={16} />
Raise an issue
</a>
</div>
);
}
export default Footer;

View file

@ -0,0 +1,66 @@
import React from 'react';
import slide from 'App/svg/cheers.svg';
import { Icon, Button } from 'UI';
import Footer from './Footer'
function Category({ name, healthOk }: { name: string; healthOk: boolean }) {
const icon = healthOk ? ('check-circle-fill' as const) : ('exclamation-circle-fill' as const);
return (
<div
className={'p-4 flex items-center gap-2 border-b cursor-pointer hover:bg-gray-lightest'}
>
<Icon name={icon} size={20} color={'green'} />
{name}
</div>
)
}
function HealthModal({ healthOk }: { healthOk: boolean }) {
return (
<div
style={{
width: 640,
position: 'fixed',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
}}
className={'flex flex-col bg-white rounded border border-figmaColors-divider'}
>
<div
className={
'flex w-full justify-between items-center p-4 border-b border-figmaColors-divider'
}
>
<div className={'text-xl font-semibold'}>Installation Status</div>
<Button icon={'arrow-repeat'} variant={'text-primary'}>
Recheck
</Button>
</div>
<div className={'flex w-full'}>
<div className={'flex flex-col h-full'} style={{ flex: 1 }}>
<Category name={'Databases'} healthOk={true} />
<Category name={'Ingestion Pipeline'} healthOk={false} />
<Category name={'Backend'} healthOk={false} />
<Category name={'SSL'} healthOk={true} />
</div>
<div
className={'bg-gray-lightest border-l w-fit border-figmaColors-divider'}
style={{ flex: 2 }}
>
<img src={slide} width={392} />
</div>
</div>
<div className={'p-4 w-full border-t border-figmaColors-divider'}>
<Button variant={'primary'} className={'ml-auto'}>
Create Account
</Button>
</div>
<Footer />
</div>
);
}
export default HealthModal;

View file

@ -0,0 +1,92 @@
import React from 'react';
import { Icon, Tooltip } from 'UI';
import cn from 'classnames';
import HealthModal from 'Components/Header/HealthStatus/HealthModal/HealthModal';
function HealthStatus() {
const [healthOk, setHealth] = React.useState(false);
const icon = healthOk ? 'pulse' : ('exclamation-circle-fill' as const);
return (
<div className={'relative group h-full'}>
<div
className={
'rounded cursor-pointer p-2 flex items-center hover:bg-figmaColors-secondary-outlined-hover-background'
}
>
<div className={'rounded p-2 border border-light-gray bg-white flex items-center '}>
<Icon name={icon} size={18} />
</div>
</div>
<HealthMenu healthOk={healthOk} setHealth={setHealth} />
<HealthModal />
</div>
);
}
function HealthMenu({ healthOk, setHealth }: { healthOk: boolean; setHealth: any }) {
const title = healthOk ? 'All Systems Operational' : 'Service disruption';
const icon = healthOk ? ('check-circle-fill' as const) : ('exclamation-circle-fill' as const);
return (
<div
style={{ width: 220, top: '100%', right: '-30%', height: '110%' }}
className={'absolute group invisible group-hover:visible pt-4'}
>
<div
className={
'w-full flex flex-col border border-light-gray gap-2 rounded items-center p-4 bg-white'
}
>
<div
className={cn(
'p-2 gap-2 w-full font-semibold flex items-center rounded',
healthOk
? 'color-green bg-figmaColors-secondary-outlined-hover-background'
: 'bg-red-lightest'
)}
>
<Icon name={icon} size={16} color={'green'} />
<span>{title}</span>
</div>
<div className={'text-secondary flex w-full justify-between items-center text-sm'}>
<span>Last checked 22 mins. ago </span>
<div className={'cursor-pointer'} onClick={() => setHealth(!healthOk)}>
<Icon name={'arrow-repeat'} size={16} color={'main'} />
</div>
</div>
<div className={'divider w-full border border-b-light-gray'} />
<div className={'w-full'}>
<div className="flex items-center justify-between mt-2">
<div className="py-1 px-2 font-medium">Version</div>
<div className="code-font text-black rounded text-base bg-active-blue px-2 py-1 whitespace-nowrap overflow-hidden text-clip">
123 123
</div>
</div>
{healthOk ? (
<>
<div className="flex items-center justify-between mt-2">
<div className="py-1 px-2 font-medium">Sessions</div>
<div className="code-font text-black rounded text-base bg-active-blue px-2 py-1 whitespace-nowrap overflow-hidden text-clip">
10 000
</div>
</div>
<div className="flex items-center justify-between mt-2">
<div className="py-1 px-2 font-medium">Events</div>
<div className="code-font text-black rounded text-base bg-active-blue px-2 py-1 whitespace-nowrap overflow-hidden text-clip">
90 000
</div>
</div>
</>
) : (
<div>Observed installation Issue with the following</div>
)}
</div>
</div>
</div>
);
}
export default HealthStatus;

View file

@ -0,0 +1 @@
export { default } from './HealthStatus'

View file

@ -24,11 +24,9 @@ export default function MetaInfo({
{Object.keys(envObject).map((envTag) => ( {Object.keys(envObject).map((envTag) => (
<div key={envTag} className="flex items-center"> <div key={envTag} className="flex items-center">
<div className="py-1 px-2 font-medium">{envTag}</div> <div className="py-1 px-2 font-medium">{envTag}</div>
<div className="rounded bg-active-blue px-2 py-1 whitespace-nowrap overflow-hidden text-clip"> <div className="rounded text-base bg-active-blue px-2 py-1 whitespace-nowrap overflow-hidden text-clip">
<span className="text-base">
{/* @ts-ignore */} {/* @ts-ignore */}
{envObject[envTag]} {envObject[envTag]}
</span>
</div> </div>
</div> </div>
))} ))}

File diff suppressed because one or more lines are too long

193
frontend/app/svg/cheers.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 76 KiB

View file

@ -0,0 +1,10 @@
<svg width="20" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_2633_13471)">
<path d="M17.4795 9.00002C17.4795 11.2489 16.5862 13.4057 14.9959 14.9959C13.4057 16.5862 11.2489 17.4795 9.00002 17.4795C6.75112 17.4795 4.59432 16.5862 3.0041 14.9959C1.41388 13.4057 0.520508 11.2489 0.520508 9.00002C0.520508 6.75112 1.41388 4.59432 3.0041 3.0041C4.59432 1.41388 6.75112 0.520508 9.00002 0.520508C11.2489 0.520508 13.4057 1.41388 14.9959 3.0041C16.5862 4.59432 17.4795 6.75112 17.4795 9.00002ZM9.00002 4.76027C8.86605 4.76034 8.73359 4.78848 8.61115 4.84286C8.48872 4.89725 8.37904 4.97668 8.28917 5.07603C8.1993 5.17539 8.13124 5.29247 8.08937 5.41972C8.0475 5.54698 8.03276 5.6816 8.04608 5.81491L8.41706 9.53211C8.42952 9.67814 8.49634 9.81418 8.60429 9.91331C8.71224 10.0124 8.85346 10.0674 9.00002 10.0674C9.14658 10.0674 9.28781 10.0124 9.39576 9.91331C9.50371 9.81418 9.57053 9.67814 9.58299 9.53211L9.95397 5.81491C9.96729 5.6816 9.95254 5.54698 9.91068 5.41972C9.86881 5.29247 9.80075 5.17539 9.71088 5.07603C9.62101 4.97668 9.51133 4.89725 9.38889 4.84286C9.26646 4.78848 9.13399 4.76034 9.00002 4.76027ZM9.00214 11.1199C8.72103 11.1199 8.45143 11.2316 8.25265 11.4304C8.05388 11.6291 7.9422 11.8987 7.9422 12.1798C7.9422 12.461 8.05388 12.7306 8.25265 12.9293C8.45143 13.1281 8.72103 13.2398 9.00214 13.2398C9.28326 13.2398 9.55286 13.1281 9.75163 12.9293C9.95041 12.7306 10.0621 12.461 10.0621 12.1798C10.0621 11.8987 9.95041 11.6291 9.75163 11.4304C9.55286 11.2316 9.28326 11.1199 9.00214 11.1199Z" fill="#CC0000"/>
</g>
<defs>
<clipPath id="clip0_2633_13471">
<rect width="16.959" height="16.959" fill="white" transform="translate(0.520508 0.520508)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -0,0 +1,3 @@
<svg viewBox="0 0 26 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M1.11657 0.397539C0.979908 0.301587 0.817004 0.250071 0.650024 0.25C0.483045 0.250071 0.320141 0.301587 0.183482 0.397539C0.0468245 0.493491 -0.0569525 0.629218 -0.113726 0.78625L-3.16873 9.1875H-8.28748C-8.50296 9.1875 -8.70963 9.2731 -8.862 9.42548C-9.01437 9.57785 -9.09998 9.78451 -9.09998 10C-9.09998 10.2155 -9.01437 10.4222 -8.862 10.5745C-8.70963 10.7269 -8.50296 10.8125 -8.28748 10.8125H-2.59998C-2.43319 10.8125 -2.27043 10.7613 -2.13379 10.6656C-1.99716 10.57 -1.89327 10.4346 -1.83623 10.2779L0.650024 3.4415L6.38627 19.2137C6.4432 19.3706 6.54705 19.5061 6.68369 19.6019C6.82034 19.6977 6.98316 19.749 7.15002 19.749C7.31689 19.749 7.47971 19.6977 7.61635 19.6019C7.753 19.5061 7.85684 19.3706 7.91377 19.2137L10.9688 10.8125H12.5125H16.0875H18.2C18.3668 10.8125 18.5296 10.7613 18.6662 10.6656C18.8028 10.57 18.9067 10.4346 18.9638 10.2779L21.45 3.4415L27.1863 19.2137C27.2432 19.3706 27.347 19.5061 27.4837 19.6019C27.6203 19.6977 27.7832 19.749 27.95 19.749C28.1169 19.749 28.2797 19.6977 28.4164 19.6019C28.553 19.5061 28.6568 19.3706 28.7138 19.2137L31.7688 10.8125H36.8875C36.9425 10.8125 36.9969 10.8069 37.05 10.7961C37.1031 10.8069 37.1575 10.8125 37.2125 10.8125H42.9C43.0668 10.8125 43.2296 10.7613 43.3662 10.6656C43.5028 10.57 43.6067 10.4346 43.6638 10.2779L46.15 3.4415L51.8863 19.2137C51.9432 19.3706 52.0471 19.5061 52.1837 19.6019C52.3203 19.6977 52.4832 19.749 52.65 19.749C52.8169 19.749 52.9797 19.6977 53.1164 19.6019C53.253 19.5061 53.3568 19.3706 53.4138 19.2137L56.4688 10.8125H61.5875C61.803 10.8125 62.0097 10.7269 62.162 10.5745C62.3144 10.4222 62.4 10.2155 62.4 10C62.4 9.78451 62.3144 9.57785 62.162 9.42548C62.0097 9.2731 61.803 9.1875 61.5875 9.1875H55.9C55.7334 9.18733 55.5708 9.23837 55.4342 9.33371C55.2976 9.42905 55.1936 9.56407 55.1363 9.7205L52.65 16.5585L46.9138 0.78625C46.857 0.629218 46.7532 0.493491 46.6166 0.397539C46.4799 0.301587 46.317 0.250071 46.15 0.25C45.983 0.250071 45.8201 0.301587 45.6835 0.397539C45.5468 0.493491 45.443 0.629218 45.3863 0.78625L42.3313 9.1875H37.2125C37.1575 9.1875 37.1031 9.19308 37.05 9.20391C36.9969 9.19308 36.9425 9.1875 36.8875 9.1875H31.2C31.0334 9.18733 30.8708 9.23837 30.7342 9.33371C30.5976 9.42905 30.4936 9.56407 30.4363 9.7205L27.95 16.5585L22.2138 0.78625C22.157 0.629218 22.0532 0.493491 21.9166 0.397539C21.7799 0.301587 21.617 0.250071 21.45 0.25C21.283 0.250071 21.1201 0.301587 20.9835 0.397539C20.8468 0.493491 20.743 0.629218 20.6863 0.78625L17.6313 9.1875H16.0875H12.5125H10.4C10.2334 9.18733 10.0708 9.23837 9.9342 9.33371C9.79759 9.42905 9.69358 9.56407 9.63627 9.7205L7.15002 16.5585L1.41377 0.78625C1.357 0.629218 1.25322 0.493491 1.11657 0.397539Z" fill="#42AE5E"/>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -57,5 +57,6 @@ module.exports = {
'text-disabled': 'rgba(0,0,0, 0.38)', 'text-disabled': 'rgba(0,0,0, 0.38)',
'text-primary': 'rgba(0,0,0, 0.87)', 'text-primary': 'rgba(0,0,0, 0.87)',
'outlined-border': 'rgba(0,0,0, 0.23)', 'outlined-border': 'rgba(0,0,0, 0.23)',
'divider': 'rgba(0, 0, 0, 0.12)',
} }
} }