Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 20 additions & 12 deletions frontend/src/modules/Data/components/JSONEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { useNodesContext } from "../../Nodes/context/NodesContext";
import Iframe from "../../../common/ui-components/common/Iframe/Iframe";
import { useFlexLayoutContext } from "../../../routing/flexLayout/FlexLayoutContext";
import { ModuleKey } from "../../../routing/ModulesRegistry";

import { EmptyStateOverlay } from "../../Nodes/components/StateUpdates/EmptyStateOverlay";
interface IJSONEditorProps {
title: string;
jsonDataProp: object;
Expand Down Expand Up @@ -137,7 +137,7 @@ export const JSONEditor = ({ title, jsonDataProp, height, showSearch = true, tog
}}
>
{!toggleSwitch && <h1 style={{ paddingTop: "10px", paddingBottom: "5px" }}>{title}</h1>}
{toggleSwitch && <ToggleSwitch title={title} activeTab={activeTab} setActiveTab={setActiveTab} />}
{toggleSwitch && Object.keys(jsonData).length > 0 && <ToggleSwitch title={title} activeTab={activeTab} setActiveTab={setActiveTab} />}
{showSearch && (
<InputField value={searchTerm} title={"Search"} onChange={(_e, event) => handleSearch(event.target.value, event)}></InputField>
)}
Expand All @@ -150,16 +150,24 @@ export const JSONEditor = ({ title, jsonDataProp, height, showSearch = true, tog
overflowY: "auto",
}}
>
<JsonViewer
rootName={false}
onSelect={(path) => handleOnSelect(path)}
theme={"dark"}
value={jsonData}
valueTypes={[imageDataType]}
displayDataTypes={false}
defaultInspectDepth={3}
style={{ overflowY: "auto", height: "100%" }}
/>
{Object.keys(jsonData).length === 0 ? (

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't that readable (needs to be extracted).

<EmptyStateOverlay
title="Results"
message="Results will appear here once a node has been executed and data is available for display."
iconSize={100}
/>
) : (
<JsonViewer
rootName={false}
onSelect={(path) => handleOnSelect(path)}
theme={"dark"}
value={jsonData}
valueTypes={[imageDataType]}
displayDataTypes={false}
defaultInspectDepth={3}
style={{ overflowY: "auto", height: "100%" }}
/>
)}
</div>
{toggleSwitch && (
<div style={{ width: "100%", height: "100%", display: activeTab === "live" ? "block" : "none" }}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,6 @@
padding-right: 10px;
scrollbar-width: thin;
scrollbar-color: #A5ACB6 transparent;
max-height: calc(100% - 51px);
margin-bottom: 10px;
margin-top: 6px;
}
Expand Down Expand Up @@ -504,4 +503,49 @@ input:focus {

.bar_error {
--progress-color: var(--status-color-error);
}

.emptyStateWrapper {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
color: #A5ACB6;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extract color

font-family: Roboto, sans-serif;
text-align: center;
padding: 20px;
animation: subtle-pulse 2s ease-in-out infinite;
}

@keyframes subtle-pulse {
0% {
opacity: 0.7;
}

50% {
opacity: 1;
}

100% {
opacity: 0.7;
}
}

.emptyStateIcon {
margin-bottom: 12px;
opacity: 0.6;
}

.emptyStateTitle {
font-size: 14px;
font-weight: 500;
margin-bottom: 6px;
color: #E0E0E0;
}

.emptyStateDescription {
font-size: 12px;
line-height: 1.3;
max-width: 250px;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,32 @@ import React from "react";
// eslint-disable-next-line css-modules/no-unused-class
import styles from "./RunningJob.module.scss";
import { useNodesContext } from "../../context/NodesContext";
import { EmptyStateOverlay } from "../StateUpdates/EmptyStateOverlay";

export const RunningJobParameters: React.FC = () => {
const { runningNode } = useNodesContext();
return (
<div className={styles.parametersWrapper} data-testid="parameters-wrapper">
{/*{Object.entries(runningNode?.parameters ?? {}).length > 0 && (*/}
<>
{Object.entries(runningNode?.parameters ?? {}).length > 0 && (
<div className={styles.parameterTitleWrapper} data-testid="parameter-title">Parameters</div>
)}
{Object.entries(runningNode?.parameters ?? {}).length > 0 ? (
<div data-testid="parameters-list">
{
// expanded &&
Object.entries(runningNode?.parameters ?? {}).map(([key, parameter]) => (
<div key={key} className={styles.parameterValues} data-testid={`parameter-item-${key}`}>
<div className={styles.parameterLabel} data-testid={`parameter-label-${key}`}
>{parameter.title}:</div>
<div className={styles.parameterValue} data-testid={`parameter-value-${key}`}>{parameter.default?.toString()}</div>
</div>
))
}
{Object.entries(runningNode?.parameters ?? {}).map(([key, parameter]) => (

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't that readable (needs to be extracted).

<div key={key} className={styles.parameterValues} data-testid={`parameter-item-${key}`}>
<div className={styles.parameterLabel} data-testid={`parameter-label-${key}`}
>{parameter.title}:</div>
<div className={styles.parameterValue} data-testid={`parameter-value-${key}`}>{parameter.default?.toString()}</div>
</div>
))}
</div>
</>
{/*)}*/}
) : (
<EmptyStateOverlay
title="Parameters"
message="Parameters will appear here when a node is running and has configurable parameters."
iconSize={30}
/>
)}
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from "react";
import NoNodeRunningIcon from "../../../../ui-lib/Icons/NoNodeRunningIcon";
// eslint-disable-next-line css-modules/no-unused-class
import styles from "../RunningJob/RunningJob.module.scss";

interface EmptyStateOverlayProps {
title: string;
message: string;
iconSize?: number;
}

export const EmptyStateOverlay: React.FC<EmptyStateOverlayProps> = ({
title,
message,
iconSize = 30
}) => {
return (
<div className={styles.emptyStateWrapper}>
<div className={styles.emptyStateIcon}>
<NoNodeRunningIcon height={iconSize} width={iconSize} />
</div>
<div className={styles.emptyStateTitle}>
No {title} Available
</div>
<div className={styles.emptyStateDescription}>
{message}
</div>
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,13 @@
text-wrap: nowrap;
}

.stateWrapper {
display: flex;
font-size: 14px;
font-weight: bold;
padding: 5px 15px 5px 20px;
}

.stateUpdatesTopWrapper {
overflow: scroll;
}
Expand Down Expand Up @@ -139,3 +146,33 @@
height: 20px !important;
}
}

.emptyStateWrapper {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
color: #A5ACB6;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extract color

font-family: Roboto, sans-serif;
text-align: center;
padding: 20px;
}

.emptyStateIcon {
margin-bottom: 12px;
opacity: 0.6;
}

.emptyStateTitle {
font-size: 14px;
font-weight: 500;
margin-bottom: 6px;
color: #E0E0E0;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extract color

}

.emptyStateDescription {
font-size: 12px;
line-height: 1.3;
max-width: 250px;
}
63 changes: 35 additions & 28 deletions frontend/src/modules/Nodes/components/StateUpdates/StateUpdates.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { StateUpdateElement, StateUpdateProps } from "./StateUpdateElement";
import { Button } from "@mui/material";
// import { ErrorStatusWrapper } from "../../../common/Error/ErrorStatusWrapper";
import { useSnapshotsContext } from "../../../Snapshots/context/SnapshotsContext";
import { EmptyStateOverlay } from "./EmptyStateOverlay";

export const StateUpdates: React.FC<{
runningNodeInfo: RunningNodeInfo | undefined;
Expand Down Expand Up @@ -39,30 +40,32 @@ export const StateUpdates: React.FC<{
<>
{/*{Object.entries(runningNodeInfo?.state_updates ?? {}).filter(([, stateUpdateObject]) => !stateUpdateObject.stateUpdated).length >*/}
{/* 0 && (*/}
<div className={styles.stateWrapper} data-testid="state-wrapper">
<div className={styles.stateTitle} data-testid="state-title">
State updates&nbsp;
{runningNodeInfo?.state_updates && Object.keys(runningNodeInfo?.state_updates).length > 0
? `(${Object.keys(runningNodeInfo?.state_updates).length})`
: ""}
{runningNodeInfo?.state_updates && Object.keys(runningNodeInfo?.state_updates).length > 0 && (

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs to be extracted/separated.

<div className={styles.stateWrapper} data-testid="state-wrapper">
<div className={styles.stateTitle} data-testid="state-title">
State updates&nbsp;
{runningNodeInfo?.state_updates && Object.keys(runningNodeInfo?.state_updates).length > 0
? `(${Object.keys(runningNodeInfo?.state_updates).length})`
: ""}
</div>
{updateAllButtonPressed ||
(Object.entries(runningNodeInfo?.state_updates ?? {}).filter(([, stateUpdateObject]) => !stateUpdateObject.stateUpdated).length >
0 && (
<Button
className={styles.updateAllButton}
data-testid="update-all-button"
disabled={updateAllButtonPressed}
onClick={() => handleClick(runningNodeInfo?.state_updates ?? {})}
>
Accept All
</Button>
))}
</div>
{updateAllButtonPressed ||
(Object.entries(runningNodeInfo?.state_updates ?? {}).filter(([, stateUpdateObject]) => !stateUpdateObject.stateUpdated).length >
0 && (
<Button
className={styles.updateAllButton}
data-testid="update-all-button"
disabled={updateAllButtonPressed}
onClick={() => handleClick(runningNodeInfo?.state_updates ?? {})}
>
Accept All
</Button>
))}
</div>
{/*// )}*/}
{runningNodeInfo?.state_updates && (
<div className={styles.stateUpdatesTopWrapper} data-testid="state-updates-top-wrapper">
{Object.entries(runningNodeInfo?.state_updates ?? {}).map(([key, stateUpdateObject], index) =>
)}

<div className={styles.stateUpdatesTopWrapper} data-testid="state-updates-top-wrapper">

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't that readable (needs to be extracted).

{runningNodeInfo?.state_updates && Object.keys(runningNodeInfo?.state_updates).length > 0 ? (
Object.entries(runningNodeInfo?.state_updates ?? {}).map(([key, stateUpdateObject], index) =>
StateUpdateElement({
key,
index,
Expand All @@ -71,11 +74,15 @@ export const StateUpdates: React.FC<{
setRunningNodeInfo,
updateAllButtonPressed,
} as StateUpdateProps)
)}

{/*{runningNodeInfo?.error && <ErrorStatusWrapper error={runningNodeInfo?.error} />}*/}
</div>
)}
)
) : (
<EmptyStateOverlay
title="State Updates"
message="State updates will appear here when a node is running and generates parameter changes."
iconSize={30}
/>
)}
</div>
</>
);
};
Loading