Skip to content

Commit

Permalink
Task/tup 514 merging content layout system status (#266)
Browse files Browse the repository at this point in the history
* Add hooks for system queue response

* New System Monitor Page with Job queue details

* View All systems button only renders when a job
queue is selected now

* Format check

* Linting components removing un-used components
Added error message table to system queues

* Linting

* Updated button to system monitor to not reload page

* Removed unused imports from tests

* Added keys to NavBar to stop console error

* TUP 514 System Detail Updates

* Select Frontera Nav Item if no system selected

* Linting

* To change header of sysmon depending if on dash or sysmon page

* Linting

* feat: support smaller windows (#256)

* Task/TUP-457/TUP-514 Add System Queue Details - content layout - phase 2 (#258)

* fix: move @import to top of file

* fix: bad merge

* Changed route from system_monitor to system-status and updated tests

* Changed from system_monitor to system-status and updated tests

* - Create header component for system status
- Created systemdetails prop to be able to use default prop for default
    system display
- Removed unnnecessary styles
- Removed app SystemDetail to let System handle all the app side of the
    system monitor page

* Format check

* Updated logic on system monitor table

* Added styles back to app/tup-ui/pages and removed
redundant styles from libs/tup-components

* Linting

* Updated tests for System Status

* Updated tests for System Status including new handler
and mock data

* Linting

* Task/tup 514 merging content layout system status - remove UI cruft (#267)

---------

Co-authored-by: Jake Rosenberg <[email protected]>
Co-authored-by: Wesley B <[email protected]>
Co-authored-by: Wesley Bomar <[email protected]>
  • Loading branch information
4 people authored Jul 17, 2023
1 parent 11bf57b commit cdd8845
Show file tree
Hide file tree
Showing 25 changed files with 498 additions and 56 deletions.
3 changes: 3 additions & 0 deletions apps/tup-ui/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
Mfa,
TicketDetail,
Impersonate,
Systems,
} from './pages';

const AppLayout = () => {
Expand Down Expand Up @@ -47,6 +48,8 @@ function App() {
<Route path="" element={<ProjectDetail />}></Route>
<Route path=":username" element={<ProjectMember />}></Route>
</Route>
<Route path="system-status" element={<Systems />}></Route>
<Route path="system-status/:tas_name" element={<Systems />} />
<Route path="mfa" element={<Mfa />}>
<Route path="" element={<MfaSelection />} />
<Route path="totp" element={<MfaPairingview method="totp" />} />
Expand Down
24 changes: 24 additions & 0 deletions apps/tup-ui/src/pages/Systems/Systems.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
.system-section {
display: grid;
}

.system-section > div > header {
padding-top: var(--global-space--section-top);
padding-left: var(--global-space--section-left);
}

.system-section nav {
margin-top: -15px;
height: 100%;
min-width: 175px;
padding-top: var(--global-space--section-top);
border-right:var(--global-border-width--normal) solid var(--global-color-primary--light);
}

.system-section > div > nav {
padding-left: var(--global-space--section-left);
}

.system-section > div > div {
padding: var(--global-space--section);
}
28 changes: 28 additions & 0 deletions apps/tup-ui/src/pages/Systems/Systems.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react';
import {
PageLayout,
RequireAuth,
SystemNavBar,
SystemDetails,
SystemStatusHeader,
} from '@tacc/tup-components';
import { useParams } from 'react-router-dom';
import styles from './Systems.module.css';

const Layout: React.FC = () => {
// To get the System name for the Page Header
const { tas_name } = useParams<{ tas_name: string }>();
return (
<RequireAuth>
<section className={styles['system-section']}>
<PageLayout
top={<SystemStatusHeader tas_name={tas_name} />}
left={<SystemNavBar tas_name={tas_name} />}
right={<SystemDetails tas_name={tas_name} />}
></PageLayout>
</section>
</RequireAuth>
);
};

export default Layout;
3 changes: 3 additions & 0 deletions apps/tup-ui/src/pages/Systems/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { default as Systems } from './Systems';

export default Systems;
1 change: 1 addition & 0 deletions apps/tup-ui/src/pages/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export { default as Mfa } from './Mfa/Mfa';
export { ProjectView, ProjectDetail, ProjectMember } from './ProjectView';
export { default as TicketDetail } from './Tickets/TicketDetail';
export { default as Impersonate } from './Impersonate';
export { default as Systems } from './Systems';
2 changes: 1 addition & 1 deletion libs/tup-components/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ export * from './layout';
export * from './utils';
export * from './profile';
export * from './projects';
export * from './system_monitor';
export * from './system-status';
export * from './tickets';
export * from './mfa';
export * from './news';
Expand Down
3 changes: 3 additions & 0 deletions libs/tup-components/src/layout/Sidebar/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ const Sidebar: React.FC = () => {
<NavItem icon="multiple-coversation" to={'/tickets'}>
Tickets
</NavItem>
<NavItem icon="data-files" to={'/system-status'}>
System Status
</NavItem>
<NavItem icon="user" to={'/account'}>
Manage Account
</NavItem>
Expand Down
23 changes: 23 additions & 0 deletions libs/tup-components/src/system-status/SystemMonitor.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from 'react';
import { SystemMonitor } from './SystemMonitor';
import { server, testRender } from '@tacc/tup-testing';
import { waitFor } from '@testing-library/react';
import { screen } from '@testing-library/react';
import { rest } from 'msw';

describe('System Monitor Component', () => {
it('should display an error message if an error is returned', async () => {
server.use(
rest.get('http://localhost:8001/system_monitor', (req, res, ctx) =>
res.once(ctx.status(404))
)
);
testRender(<SystemMonitor />);
await screen.findAllByText(/Unable to gather system information/);
});
it('should display the title of table on dashboard', async () => {
const { getByTestId, getByText } = testRender(<SystemMonitor />);
await waitFor(() => expect(getByTestId('loading-spinner')).toBeDefined());
expect(getByText(/System Status/)).toBeDefined();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {
import { Display, Operational, Load } from './SystemMonitorCells';
import { SystemMonitorRawSystem, useSystemMonitor } from '@tacc/tup-hooks';
import styles from './SystemMonitor.module.css';
import { EmptyTablePlaceholder } from '../utils';
import { SystemDetailProps } from '.';

export const isSystemOnline = (rawSystem: SystemMonitorRawSystem): boolean => {
if (
Expand All @@ -21,8 +23,13 @@ export const isSystemOnline = (rawSystem: SystemMonitorRawSystem): boolean => {
return true;
};

export const SystemMonitorTable: React.FC = () => {
const { data, isLoading, error } = useSystemMonitor();
export const SystemMonitorTable: React.FC<SystemDetailProps> = ({
tas_name,
}) => {
const { data: systemMonitorData, isLoading, error } = useSystemMonitor();
let data = systemMonitorData;
data = tas_name ? data?.filter((sys) => sys.tas_name === tas_name) : data;
const initialTableState = tas_name ? { hiddenColumns: ['display_name'] } : {};
const columns = useMemo<Column<SystemMonitorRawSystem>[]>(
() => [
{
Expand All @@ -32,21 +39,22 @@ export const SystemMonitorTable: React.FC = () => {
},
{
accessor: isSystemOnline,
Header: 'Status',
// To display different column headings depending if on Dashboard or in System Status page
Header: tas_name ? 'System Status' : 'Status',
Cell: Operational,
},
{
accessor: ({ load }) => (load ? Math.floor(load * 100) : ' -- '),
Header: 'Utilization',
Header: 'Load',
Cell: Load,
},
{
accessor: ({ running }) => (running ? running : ' 0 '),
Header: 'Running',
Header: 'Running Jobs',
},
{
accessor: ({ waiting }) => (waiting ? waiting : ' 0 '),
Header: 'Waiting',
Header: 'Waiting Jobs',
},
],
[]
Expand All @@ -56,6 +64,7 @@ export const SystemMonitorTable: React.FC = () => {
useTable({
columns,
data: data ?? [],
initialState: initialTableState,
});

if (isLoading) {
Expand All @@ -64,17 +73,14 @@ export const SystemMonitorTable: React.FC = () => {

if (error) {
return (
<InlineMessage type="warning">
<EmptyTablePlaceholder>
Unable to gather system information
</InlineMessage>
</EmptyTablePlaceholder>
);
}

return (
<table
{...getTableProps()}
className={`o-fixed-header-table ${styles.root}`}
>
<table {...getTableProps()} className={`${styles['systems-listing']}`}>
<thead>
{headerGroups.map((headerGroup) => (
<tr {...headerGroup.getHeaderGroupProps()}>
Expand All @@ -89,7 +95,10 @@ export const SystemMonitorTable: React.FC = () => {
rows.map((row, idx) => {
prepareRow(row);
return (
<tr {...row.getRowProps()}>
<tr
className={styles['system-listing-row']}
{...row.getRowProps()}
>
{row.cells.map((cell) => (
<td {...cell.getCellProps()}>{cell.render('Cell')}</td>
))}
Expand All @@ -110,7 +119,9 @@ export const SystemMonitorTable: React.FC = () => {
);
};

export const SystemMonitor = () => {
export const SystemMonitor: React.FC<SystemDetailProps> = ({ tas_name }) => {
/* To display a title for sys_mon table on dashboard only */
if (tas_name) return <SystemMonitorTable tas_name={tas_name} />;
return (
<SectionTableWrapper header="System Status">
<SystemMonitorTable />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import React from 'react';
import { Pill } from '@tacc/core-components';
import { Cell } from 'react-table';
import { Link } from 'react-router-dom';
import { SystemMonitorRawSystem } from '@tacc/tup-hooks';

export const Display: React.FC<{
cell: Cell<SystemMonitorRawSystem, string>;
}> = ({ cell: { value } }) => <strong>{value}</strong>;
}> = ({ cell: { row } }) => (
<Link to={`/system-status/${row.original.tas_name}`}>
{row.original.display_name}
</Link>
);

export const Operational: React.FC<{
cell: Cell<SystemMonitorRawSystem, boolean>;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
@import url('@tacc/core-styles/src/lib/_imports/tools/media-queries.css');

.panels {
display: grid;

/* To reproduce complex layout of design doc */
@media (--wide-and-above) {
gap: 25px;
grid-template-columns: 0.5fr 0.5fr;
grid-template-rows: auto 1fr;
grid-template-areas:
"monitor avgwait"
"queue avgwait";
}
/* To reproduce simple layout of narrow screens like CEPv2 */
@media (--wide-and-below) {
row-gap: 25px;
grid-template-rows: auto 1fr;
grid-template-areas:
"monitor"
"queue";
/* TODO: When avgwait table exists, show it using something like this: *//*
grid-template-rows: auto 1fr 1fr;
grid-template-areas:
"monitor"
"queue"
"avgwait";
*/
}
}
.panels > * {
overflow: auto; /* to force items to stay within their grid cells */
}
.panels > :nth-child(1) { grid-area: monitor; }
.panels > :nth-child(2) { grid-area: queue; }
.panels > :nth-child(3) { grid-area: avgwait; }
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from 'react';
import { SystemDetails } from './SystemDetails';
import { server, testRender } from '@tacc/tup-testing';
import { waitFor } from '@testing-library/react';
import { screen } from '@testing-library/react';
import { rest } from 'msw';

describe('System Monitor Component', () => {
it('should display an error message if an error is returned', async () => {
server.use(
rest.get(
'http://localhost:8001/system_monitor/:tas_name',
(req, res, ctx) => res.once(ctx.status(404))
)
);
testRender(<SystemDetails />);
await screen.findAllByText(/System job queues are unavailable/);
});
it('should display the headers of the tables', async () => {
server.use(
rest.get(
'http://localhost:8001/system_monitor/:tas_name',
(req, res, ctx) => res.once(ctx.status(200))
)
);
const { getByText, getAllByText } = testRender(<SystemDetails />);
await waitFor(() => expect(getByText('System Status')).toBeDefined());
expect(getByText('Load')).toBeDefined();
expect(getAllByText('Running Jobs')).toBeDefined();
expect(getAllByText('Waiting Jobs')).toBeDefined();
expect(getByText('Queue')).toBeDefined();
expect(getByText('Status')).toBeDefined();
expect(getByText('Idle Nodes')).toBeDefined();
});
});
Loading

0 comments on commit cdd8845

Please sign in to comment.