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
14 changes: 14 additions & 0 deletions frontend/src/modules/Nodes/NodesPage.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,18 @@
background-color: #bbb;
border-radius: 50%;
display: inline-block;
}
.sliderArrowWrapper {
justify-items: center;
padding-bottom: 8px;
div {
width: fit-content;
}
svg {
cursor: pointer;
}
}
.sliderArrowRotated {
transition: transform 0.3s ease-in-out;
transform: rotate(180deg);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
max-height: 52%;
//padding: 30px;
color: #A5ACB6;
padding-bottom: 28px;
padding-bottom: 8px;
}

.title {
Expand All @@ -16,6 +16,7 @@
gap: 10px;
font-size: 20px;
vertical-align: middle;
height: 30px;
}

.runningJobWrapper {
Expand Down Expand Up @@ -76,6 +77,45 @@
border-radius: 4px;
}

.parametersStateCollapsedComponent {
display: flex;
padding-left: 20px;
padding-top: 16px;
padding-bottom: 10px;
color: var(--Gray, #A5ACB6);
font-family: Roboto, serif;
font-size: 14px;
font-style: normal;
font-weight: 400;
line-height: normal;
}

.tooltipElement {
pointer-events: none;
z-index: 10000;
position: absolute;
div {
width: fit-content;
}
}

.hide {
display: none;
}

.show {
display: block;
}

.collapsedTitleWrapper {
padding-right: 10px;
}

.collapsedIconWrapper {
cursor: pointer;
//pointer-events: none;
}

.runInfoWrapper {
display: flex;
padding-left: 20px;
Expand Down Expand Up @@ -125,9 +165,13 @@

.parameterTitleWrapper {
display: flex;
font-family: Roboto, serif;
font-style: normal;
font-weight: 400;
font-size: 14px;
font-weight: bold;
padding: 10px 15px 1px 6px;
padding: 10px 15px 0 0;
color: var(--Gray, #A5ACB6);
line-height: normal;
}

.parameterValues {
Expand Down Expand Up @@ -159,6 +203,12 @@
.stateTitle {
width: 100%;
text-wrap-mode: nowrap;
color: var(--Gray, #A5ACB6);
font-family: Roboto, serif;
font-size: 14px;
font-style: normal;
font-weight: 400;
line-height: normal;
}

.updateAllButton {
Expand All @@ -170,6 +220,12 @@
text-transform: none !important;
}

.stateUpdatesTooltipWrapper {
width: 432px;
padding-top: 15px;
padding-left: 15px;
padding-bottom: 15px;
}
.stateUpdatesTopWrapper {
overflow-y: scroll;
max-height: calc(100% - 51px);
Expand Down
126 changes: 73 additions & 53 deletions frontend/src/modules/Nodes/components/RunningJob/RunningJob.tsx
Original file line number Diff line number Diff line change
@@ -1,69 +1,89 @@
import React from "react";
import React, { useState } from "react";
// eslint-disable-next-line css-modules/no-unused-class
import styles from "./RunningJob.module.scss";
import { useNodesContext } from "../../context/NodesContext";
import { SnapshotsApi } from "../../../Snapshots/api/SnapshotsApi";
import { StateUpdates } from "../StateUpdates/StateUpdates";
import { StopIcon } from "../../../../ui-lib/Icons/StopIcon";
import { RunningJobInfoSection } from "./RunningJobInfoSection";
import { RunningJobParameters } from "./RunningJobParameters";
import { RunningJobTitleRow } from "./RunningJobTitle";
import { CollapsedComponentIcon } from "../../../../ui-lib/Icons/CollapsedComponentIcon";
import { classNames } from "../../../../utils/classnames";
import { StateUpdatesTooltip } from "../StateUpdates/StateUpdatesTooltip";

export const RunningJob: React.FC = () => {
const {
runningNode,
runningNodeInfo,
setRunningNodeInfo,
isNodeRunning,
setIsNodeRunning,
updateAllButtonPressed,
setUpdateAllButtonPressed,
} = useNodesContext();
interface IProps {
expanded: boolean;
}

const insertSpaces = (str: string, interval = 40) => {
let result = "";
for (let i = 0; i < str.length; i += interval) {
result += str.slice(i, i + interval) + " ";
}
return result.trim();
export const RunningJob: React.FC<IProps> = ({ expanded }) => {
const ParametersAndStateExpanded: React.FC = () => {
return (
<>
<div className={styles.parameterColumnWrapper}>
<RunningJobParameters />
</div>
<div className={styles.statesColumnWrapper} data-testid="states-column-wrapper">
<StateUpdates />
</div>
</>
);
};

const handleStopClick = () => {
SnapshotsApi.stopNodeRunning().then((res) => {
if (res.isOk) {
setIsNodeRunning(!res.result);
}
});
const ParametersStateCollapsedComponent: React.FC<{
cssClassName?: string;
title: string;
el: React.JSX.Element;
}> = ({ cssClassName, title, el }) => {
const [showTooltip, setShowTooltip] = useState(false);
const handleOnMouseOver = (e: React.MouseEvent<HTMLDivElement>) => {
e.stopPropagation();
setShowTooltip(true);
};
const handleOnMouseLeave = (e: React.MouseEvent<HTMLDivElement>) => {
e.stopPropagation();
setShowTooltip(false);
};
return (
<>
<div className={classNames(styles.parametersStateCollapsedComponent, cssClassName)}>
<div className={styles.collapsedTitleWrapper}>{title}</div>
<div onMouseOver={handleOnMouseOver} onMouseLeave={handleOnMouseLeave}>
<div className={styles.collapsedIconWrapper}>
<CollapsedComponentIcon />
</div>
</div>
<div className={classNames(styles.tooltipElement, !showTooltip ? styles.show : styles.hide)}>{el}</div>
</div>
</>
);
};

const ParametersAndStateUpdatesCollapsedComponentWrapper: React.FC = () => {
const parameterElement = (
<div className={styles.parameterColumnWrapper}>
<RunningJobParameters />
</div>
);
const stateUpdatesElement = (
<div className={styles.parameterColumnWrapper}>
<StateUpdatesTooltip />
</div>
);
return (
<>
<div className={styles.parameterColumnWrapper}>
<ParametersStateCollapsedComponent title={"Parameters"} el={parameterElement} />
</div>
<div className={styles.statesColumnWrapper}>
<ParametersStateCollapsedComponent title={"State updates"} el={stateUpdatesElement} />
</div>
</>
);
};
return (
<div className={styles.wrapper} data-testid="running-job-wrapper">
<div className={styles.title} data-testid="running-job-title">
<div className={styles.dot} data-testid="running-job-dot"></div>
<div className={styles.runningJobWrapper} data-testid="running-job-name-wrapper">
<div className={styles.runningJobNameWrapper}>
<div>Running job{runningNode?.name ? ":" : ""}</div>
<div className={styles.runningJobName} data-testid="running-job-name">&nbsp;&nbsp;{runningNode?.name ? insertSpaces(runningNode?.name) : ""}</div>
</div>
</div>
{isNodeRunning && (
<div className={styles.stopButtonWrapper}>
<div onClick={handleStopClick} data-testid="stop-button">
<StopIcon />
</div>
</div>
)}
</div>
{runningNodeInfo && <RunningJobInfoSection />}
<RunningJobTitleRow />
<RunningJobInfoSection />
<div className={styles.parameterStatesWrapper}>
<div className={styles.parameterColumnWrapper}>{runningNodeInfo && <RunningJobParameters />}</div>
<div className={styles.statesColumnWrapper} data-testid="states-column-wrapper">
<StateUpdates
runningNodeInfo={runningNodeInfo}
setRunningNodeInfo={setRunningNodeInfo}
updateAllButtonPressed={updateAllButtonPressed}
setUpdateAllButtonPressed={setUpdateAllButtonPressed}
/>
</div>
{!expanded && <ParametersAndStateExpanded />}
{expanded && <ParametersAndStateUpdatesCollapsedComponentWrapper />}
</div>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,41 +7,51 @@ export const RunningJobInfoSection: React.FC = () => {
const { runningNodeInfo } = useNodesContext();

return (
<div className={styles.runInfoWrapper} data-testid="run-info-wrapper">
<div className={styles.runInfoColumn}>
{runningNodeInfo?.lastRunNodeName && (
<div className={styles.runInfoRow}>
<div className={styles.jobInfoKey}>Last run node:&nbsp;&nbsp;</div>
<div className={styles.jobInfoValue}>{runningNodeInfo?.lastRunNodeName}</div>
</div>
)}
{runningNodeInfo?.timestampOfRun && (
<div className={styles.runInfoRow}>
<div className={styles.jobInfoKey}>Run start:&nbsp;&nbsp;</div>
<div className={styles.jobInfoValue} data-testid="run-info-value-timestamp">{runningNodeInfo?.timestampOfRun}</div>
</div>
)}
{runningNodeInfo?.runDuration && (
<div className={styles.runInfoRow}>
<div className={styles.jobInfoKey}>Run duration:&nbsp;&nbsp;</div>
<div className={styles.jobInfoValue} data-testid="run-info-value-duration">{runningNodeInfo?.runDuration}&nbsp;s</div>
</div>
)}
runningNodeInfo && (
<div className={styles.runInfoWrapper} data-testid="run-info-wrapper">
<div className={styles.runInfoColumn}>
{runningNodeInfo?.lastRunNodeName && (
<div className={styles.runInfoRow}>
<div className={styles.jobInfoKey}>Last run node:&nbsp;&nbsp;</div>
<div className={styles.jobInfoValue}>{runningNodeInfo?.lastRunNodeName}</div>
</div>
)}
{runningNodeInfo?.timestampOfRun && (
<div className={styles.runInfoRow}>
<div className={styles.jobInfoKey}>Run start:&nbsp;&nbsp;</div>
<div className={styles.jobInfoValue} data-testid="run-info-value-timestamp">
{runningNodeInfo?.timestampOfRun}
</div>
</div>
)}
{runningNodeInfo?.runDuration && (
<div className={styles.runInfoRow}>
<div className={styles.jobInfoKey}>Run duration:&nbsp;&nbsp;</div>
<div className={styles.jobInfoValue} data-testid="run-info-value-duration">
{runningNodeInfo?.runDuration}&nbsp;s
</div>
</div>
)}
</div>
<div className={styles.runInfoColumn}>
{runningNodeInfo?.status && (
<div className={styles.runInfoRow}>
<div className={styles.jobInfoKeySecondColumn}>Status:&nbsp;&nbsp;</div>
<div className={styles.jobInfoValue} data-testid="run-info-value-status">
{runningNodeInfo?.status}
</div>
</div>
)}
{runningNodeInfo?.idx && (
<div className={styles.runInfoRow}>
<div className={styles.jobInfoKeySecondColumn}>idx:&nbsp;&nbsp;</div>
<div className={styles.jobInfoValue} data-testid="run-info-value-idx">
{runningNodeInfo?.idx}
</div>
</div>
)}
</div>
</div>
<div className={styles.runInfoColumn}>
{runningNodeInfo?.status && (
<div className={styles.runInfoRow}>
<div className={styles.jobInfoKeySecondColumn}>Status:&nbsp;&nbsp;</div>
<div className={styles.jobInfoValue} data-testid="run-info-value-status">{runningNodeInfo?.status}</div>
</div>
)}
{runningNodeInfo?.idx && (
<div className={styles.runInfoRow}>
<div className={styles.jobInfoKeySecondColumn}>idx:&nbsp;&nbsp;</div>
<div className={styles.jobInfoValue} data-testid="run-info-value-idx">{runningNodeInfo?.idx}</div>
</div>
)}
</div>
</div>
)
);
};
Loading