diff --git a/frontend/src/modules/Data/components/JSONEditor.tsx b/frontend/src/modules/Data/components/JSONEditor.tsx index d36c162c..d8bd5a50 100644 --- a/frontend/src/modules/Data/components/JSONEditor.tsx +++ b/frontend/src/modules/Data/components/JSONEditor.tsx @@ -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; @@ -137,7 +137,7 @@ export const JSONEditor = ({ title, jsonDataProp, height, showSearch = true, tog }} > {!toggleSwitch &&

{title}

} - {toggleSwitch && } + {toggleSwitch && Object.keys(jsonData).length > 0 && } {showSearch && ( handleSearch(event.target.value, event)}> )} @@ -150,16 +150,24 @@ export const JSONEditor = ({ title, jsonDataProp, height, showSearch = true, tog overflowY: "auto", }} > - handleOnSelect(path)} - theme={"dark"} - value={jsonData} - valueTypes={[imageDataType]} - displayDataTypes={false} - defaultInspectDepth={3} - style={{ overflowY: "auto", height: "100%" }} - /> + {Object.keys(jsonData).length === 0 ? ( + + ) : ( + handleOnSelect(path)} + theme={"dark"} + value={jsonData} + valueTypes={[imageDataType]} + displayDataTypes={false} + defaultInspectDepth={3} + style={{ overflowY: "auto", height: "100%" }} + /> + )} {toggleSwitch && (
diff --git a/frontend/src/modules/Nodes/components/RunningJob/RunningJob.module.scss b/frontend/src/modules/Nodes/components/RunningJob/RunningJob.module.scss index ae923c86..5e742c3e 100644 --- a/frontend/src/modules/Nodes/components/RunningJob/RunningJob.module.scss +++ b/frontend/src/modules/Nodes/components/RunningJob/RunningJob.module.scss @@ -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; } @@ -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; + 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; } \ No newline at end of file diff --git a/frontend/src/modules/Nodes/components/RunningJob/RunningJobParameters.tsx b/frontend/src/modules/Nodes/components/RunningJob/RunningJobParameters.tsx index 760c52bb..d18b0ee2 100644 --- a/frontend/src/modules/Nodes/components/RunningJob/RunningJobParameters.tsx +++ b/frontend/src/modules/Nodes/components/RunningJob/RunningJobParameters.tsx @@ -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 (
- {/*{Object.entries(runningNode?.parameters ?? {}).length > 0 && (*/} - <> + {Object.entries(runningNode?.parameters ?? {}).length > 0 && (
Parameters
+ )} + {Object.entries(runningNode?.parameters ?? {}).length > 0 ? (
- { - // expanded && - Object.entries(runningNode?.parameters ?? {}).map(([key, parameter]) => ( -
-
{parameter.title}:
-
{parameter.default?.toString()}
-
- )) - } + {Object.entries(runningNode?.parameters ?? {}).map(([key, parameter]) => ( +
+
{parameter.title}:
+
{parameter.default?.toString()}
+
+ ))}
- - {/*)}*/} + ) : ( + + )}
); }; diff --git a/frontend/src/modules/Nodes/components/StateUpdates/EmptyStateOverlay.tsx b/frontend/src/modules/Nodes/components/StateUpdates/EmptyStateOverlay.tsx new file mode 100644 index 00000000..974cf370 --- /dev/null +++ b/frontend/src/modules/Nodes/components/StateUpdates/EmptyStateOverlay.tsx @@ -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 = ({ + title, + message, + iconSize = 30 +}) => { + return ( +
+
+ +
+
+ No {title} Available +
+
+ {message} +
+
+ ); +}; diff --git a/frontend/src/modules/Nodes/components/StateUpdates/StateUpdates.module.scss b/frontend/src/modules/Nodes/components/StateUpdates/StateUpdates.module.scss index 6b9df6c1..c1d198de 100644 --- a/frontend/src/modules/Nodes/components/StateUpdates/StateUpdates.module.scss +++ b/frontend/src/modules/Nodes/components/StateUpdates/StateUpdates.module.scss @@ -93,6 +93,13 @@ text-wrap: nowrap; } +.stateWrapper { + display: flex; + font-size: 14px; + font-weight: bold; + padding: 5px 15px 5px 20px; +} + .stateUpdatesTopWrapper { overflow: scroll; } @@ -139,3 +146,33 @@ height: 20px !important; } } + +.emptyStateWrapper { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 100%; + color: #A5ACB6; + 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; +} + +.emptyStateDescription { + font-size: 12px; + line-height: 1.3; + max-width: 250px; +} diff --git a/frontend/src/modules/Nodes/components/StateUpdates/StateUpdates.tsx b/frontend/src/modules/Nodes/components/StateUpdates/StateUpdates.tsx index ed93c505..f99af094 100644 --- a/frontend/src/modules/Nodes/components/StateUpdates/StateUpdates.tsx +++ b/frontend/src/modules/Nodes/components/StateUpdates/StateUpdates.tsx @@ -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; @@ -39,30 +40,32 @@ export const StateUpdates: React.FC<{ <> {/*{Object.entries(runningNodeInfo?.state_updates ?? {}).filter(([, stateUpdateObject]) => !stateUpdateObject.stateUpdated).length >*/} {/* 0 && (*/} -
-
- State updates  - {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 && ( +
+
+ State updates  + {runningNodeInfo?.state_updates && Object.keys(runningNodeInfo?.state_updates).length > 0 + ? `(${Object.keys(runningNodeInfo?.state_updates).length})` + : ""} +
+ {updateAllButtonPressed || + (Object.entries(runningNodeInfo?.state_updates ?? {}).filter(([, stateUpdateObject]) => !stateUpdateObject.stateUpdated).length > + 0 && ( + + ))}
- {updateAllButtonPressed || - (Object.entries(runningNodeInfo?.state_updates ?? {}).filter(([, stateUpdateObject]) => !stateUpdateObject.stateUpdated).length > - 0 && ( - - ))} -
- {/*// )}*/} - {runningNodeInfo?.state_updates && ( -
- {Object.entries(runningNodeInfo?.state_updates ?? {}).map(([key, stateUpdateObject], index) => + )} + +
+ {runningNodeInfo?.state_updates && Object.keys(runningNodeInfo?.state_updates).length > 0 ? ( + Object.entries(runningNodeInfo?.state_updates ?? {}).map(([key, stateUpdateObject], index) => StateUpdateElement({ key, index, @@ -71,11 +74,15 @@ export const StateUpdates: React.FC<{ setRunningNodeInfo, updateAllButtonPressed, } as StateUpdateProps) - )} - - {/*{runningNodeInfo?.error && }*/} -
- )} + ) + ) : ( + + )} +
); };