Skip to content

Commit

Permalink
Toggle between dashboard and code views
Browse files Browse the repository at this point in the history
  • Loading branch information
kiahna-tucker committed Jan 7, 2025
1 parent 0250ebe commit 9d17a18
Show file tree
Hide file tree
Showing 9 changed files with 214 additions and 55 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { Box, ToggleButtonGroup } from '@mui/material';
import OutlinedToggleButton from 'components/shared/buttons/OutlinedToggleButton';
import { outlinedToggleButtonGroupStyling } from 'context/Theme';
import { useIntl } from 'react-intl';
import { useEntityStatusStore } from 'stores/EntityStatus/Store';

export default function SectionFormatter() {
const intl = useIntl();

const format = useEntityStatusStore((state) => state.format);
const setFormat = useEntityStatusStore((state) => state.setFormat);

return (
<Box style={{ paddingTop: 4 }}>
<ToggleButtonGroup
size="small"
exclusive
sx={outlinedToggleButtonGroupStyling}
>
<OutlinedToggleButton
size="small"
value="dashboard"
selected={format === 'dashboard'}
onClick={(_event, value) => setFormat(value, 'code')}
>
{intl.formatMessage({
id: 'details.ops.status.cta.formatted',
})}
</OutlinedToggleButton>

<OutlinedToggleButton
size="small"
value="code"
selected={format === 'code'}
onClick={(_event, value) => setFormat(value, 'dashboard')}
>
{intl.formatMessage({ id: 'details.ops.status.cta.raw' })}
</OutlinedToggleButton>
</ToggleButtonGroup>
</Box>
);
}
34 changes: 34 additions & 0 deletions src/components/shared/Entity/Details/Logs/Status/SectionViews.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Divider, Typography } from '@mui/material';
import ControllerStatusHistoryTable from 'components/tables/ControllerStatusHistory';
import { useIntl } from 'react-intl';
import { useEntityStatusStore } from 'stores/EntityStatus/Store';
import Overview from './Overview';
import StatusResponseViewer from './StatusResponseViewer';

export default function SectionViews() {
const intl = useIntl();

const format = useEntityStatusStore((state) => state.format);

if (format === 'dashboard') {
return (
<>
<Overview />

<Divider />

<Typography
style={{ fontSize: 18, fontWeight: 400, marginBottom: 24 }}
>
{intl.formatMessage({
id: 'details.ops.status.table.header',
})}
</Typography>

<ControllerStatusHistoryTable serverErrorExists={false} />
</>
);
} else {
return <StatusResponseViewer />;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { Editor } from '@monaco-editor/react';
import { Box, Divider, Paper, useTheme } from '@mui/material';
import { MonacoEditorSkeleton } from 'components/editor/MonacoEditor/EditorSkeletons';
import { editorToolBarSx } from 'context/Theme';
import * as monacoEditor from 'monaco-editor/esm/vs/editor/editor.api';
import { useRef } from 'react';
import { logRocketConsole } from 'services/shared';
import { stringifyJSON } from 'services/stringify';
import { useEntityStatusStore } from 'stores/EntityStatus/Store';
import { DEFAULT_TOOLBAR_HEIGHT } from 'utils/editor-utils';
import { hasLength } from 'utils/misc-utils';

const EDITOR_HEIGHT = 400;

export default function StatusResponseViewer() {
const theme = useTheme();
const editorRef = useRef<monacoEditor.editor.IStandaloneCodeEditor | null>(
null
);

const response = useEntityStatusStore((state) => state.response);

if (response) {
return (
<Paper sx={{ width: '100%' }} variant="outlined">
<Box
sx={{
...editorToolBarSx,
minHeight: DEFAULT_TOOLBAR_HEIGHT,
}}
/>

<Divider />

<Editor
defaultLanguage="json"
height={EDITOR_HEIGHT}
onMount={(
editor: monacoEditor.editor.IStandaloneCodeEditor
) => {
logRocketConsole('handlers:mount');
editorRef.current = editor;
}}
options={{
readOnly: true,
minimap: {
enabled: false,
},
}}
path={
hasLength(response.catalog_name)
? response.catalog_name
: 'preset_status_path'
}
saveViewState={false}
theme={theme.palette.mode === 'light' ? 'vs' : 'vs-dark'}
value={stringifyJSON(response)}
/>
</Paper>
);
} else {
return <MonacoEditorSkeleton editorHeight={EDITOR_HEIGHT} />;
}
}
88 changes: 38 additions & 50 deletions src/components/shared/Entity/Details/Logs/Status/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { Box, Button, Divider, Stack, Typography } from '@mui/material';
import ControllerStatusHistoryTable from 'components/tables/ControllerStatusHistory';
import { Box, Button, Stack, Typography } from '@mui/material';
import useEntityStatus from 'hooks/entityStatus/useEntityStatus';
import useGlobalSearchParams, {
GlobalSearchParams,
} from 'hooks/searchParams/useGlobalSearchParams';
import { Refresh } from 'iconoir-react';
import { useIntl } from 'react-intl';
import { isEntityControllerStatus } from 'utils/entityStatus-utils';
import Overview from './Overview';
import SectionFormatter from './SectionFormatter';
import SectionViews from './SectionViews';

export default function Status() {
const catalogName = useGlobalSearchParams(GlobalSearchParams.CATALOG_NAME);
Expand All @@ -18,55 +17,44 @@ export default function Status() {

return (
<Stack spacing={2} style={{ marginTop: 40 }}>
<Box>
<Stack
direction="row"
spacing={2}
style={{ alignItems: 'center' }}
>
<Typography variant="h6" style={{ marginBottom: 4 }}>
{intl.formatMessage({
id: 'details.ops.status.header',
})}
</Typography>

<Button
variant="text"
startIcon={<Refresh style={{ fontSize: 12 }} />}
onClick={() => refresh()}
disabled={data === undefined}
<Stack
direction="row"
spacing={4}
style={{ justifyContent: 'space-between' }}
>
<Box>
<Stack
direction="row"
spacing={2}
style={{ alignItems: 'center' }}
>
{intl.formatMessage({ id: 'cta.refresh' })}
</Button>
</Stack>

<Typography>
This is a placeholder description for this section that is
used to mock the Account Access tab of the Admin page.
</Typography>
</Box>

<Overview />

<Divider />
<Typography variant="h6" style={{ marginBottom: 4 }}>
{intl.formatMessage({
id: 'details.ops.status.header',
})}
</Typography>

<Button
variant="text"
startIcon={<Refresh style={{ fontSize: 12 }} />}
onClick={() => refresh()}
disabled={data === undefined}
>
{intl.formatMessage({ id: 'cta.refresh' })}
</Button>
</Stack>

<Typography>
This is a placeholder description for this section that
is used to mock the Account Access tab of the Admin
page.
</Typography>
</Box>

<Typography
style={{ fontSize: 18, fontWeight: 400, marginBottom: 24 }}
>
{intl.formatMessage({
id: 'details.ops.status.table.header',
})}
</Typography>
<SectionFormatter />
</Stack>

<ControllerStatusHistoryTable
history={
data?.[0].controller_status &&
isEntityControllerStatus(data[0].controller_status)
? data[0].controller_status.publications?.history
: []
}
serverErrorExists={false}
/>
<SectionViews />
</Stack>
);
}
16 changes: 13 additions & 3 deletions src/components/tables/ControllerStatusHistory/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ import { Box, Table, TableContainer } from '@mui/material';
import EntityTableBody from 'components/tables/EntityTable/TableBody';
import EntityTableHeader from 'components/tables/EntityTable/TableHeader';
import { useDisplayTableColumns } from 'context/TableSettings';
import { PublicationInfo } from 'deps/control-plane/types';
import { useEffect, useMemo, useState } from 'react';
import { useIntl } from 'react-intl';
import { useEntityStatusStore } from 'stores/EntityStatus/Store';
import { TablePrefixes } from 'stores/Tables/hooks';
import { SortDirection, TableColumns, TableState, TableStatuses } from 'types';
import { isEntityControllerStatus } from 'utils/entityStatus-utils';
import Rows from './Rows';
import { TableProps } from './types';

Expand Down Expand Up @@ -41,11 +44,18 @@ const evaluateColumnsToShow = (columnsToHide: string[]) =>
);

export default function ControllerStatusHistoryTable({
history,
serverErrorExists,
}: TableProps) {
const intl = useIntl();

const history: PublicationInfo[] | null | undefined = useEntityStatusStore(
(state) =>
state.response?.controller_status &&
isEntityControllerStatus(state.response.controller_status)
? state.response.controller_status.publications?.history
: []
);

const [tableState, setTableState] = useState<TableState>({
status: TableStatuses.LOADING,
});
Expand All @@ -66,9 +76,9 @@ export default function ControllerStatusHistoryTable({
};

useEffect(() => {
if (history === null) {
if (!history) {
setTableState({ status: TableStatuses.LOADING });
} else if (history && history.length > 0) {
} else if (history.length > 0) {
setTableState({
status: TableStatuses.DATA_FETCHED,
});
Expand Down
1 change: 0 additions & 1 deletion src/components/tables/ControllerStatusHistory/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,5 @@ export interface RowsProps {
}

export interface TableProps {
history: PublicationInfo[] | null | undefined;
serverErrorExists: boolean;
}
2 changes: 2 additions & 0 deletions src/lang/en-US/Details.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ export const Details: Record<string, string> = {
'details.history.noPublications': `No publications were found.`,

'details.ops.status.header': `Status`,
'details.ops.status.cta.formatted': `Dashboard`,
'details.ops.status.cta.raw': `Code`,
'details.ops.status.overview.autoDiscovery.header': `Auto Discovery`,
'details.ops.status.overview.autoDiscovery.subheaderFirstFailure': `First Failed`,
'details.ops.status.overview.autoDiscovery.subheaderLastSuccess': `Last Success`,
Expand Down
16 changes: 15 additions & 1 deletion src/stores/EntityStatus/Store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ import { create, StoreApi } from 'zustand';
import { devtools, NamedSet } from 'zustand/middleware';
import { EntityStatusState } from './types';

const getInitialStateData = (): Pick<EntityStatusState, 'response'> => ({
const getInitialStateData = (): Pick<
EntityStatusState,
'format' | 'response'
> => ({
format: 'dashboard',
response: null,
});

Expand All @@ -14,6 +18,16 @@ const getInitialState = (
): EntityStatusState => ({
...getInitialStateData(),

setFormat: (value, invertedValue) => {
set(
produce((state: EntityStatusState) => {
state.format = state.format === value ? invertedValue : value;
}),
false,
'Format set'
);
},

setResponse: (value) => {
set(
produce((state: EntityStatusState) => {
Expand Down
6 changes: 6 additions & 0 deletions src/stores/EntityStatus/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,10 @@ import { EntityStatusResponse } from 'deps/control-plane/types';
export interface EntityStatusState {
response: EntityStatusResponse | null;
setResponse: (value: EntityStatusResponse) => void;

format: 'code' | 'dashboard';
setFormat: (
value: EntityStatusState['format'],
invertedValue: EntityStatusState['format']
) => void;
}

0 comments on commit 9d17a18

Please sign in to comment.