Skip to content
This repository has been archived by the owner on Dec 13, 2023. It is now read-only.

3.3.3 UI fixes #2536

Merged
merged 1 commit into from
Oct 25, 2021
Merged
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
24 changes: 4 additions & 20 deletions ui/src/components/DateRangePicker.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import React from "react";
import { FormControl, InputLabel } from "@material-ui/core";
import { Input, ButtonGroup } from "./";
import { Input } from "./";
import { makeStyles } from "@material-ui/styles";
import { subHours, format } from "date-fns";

const useStyles = makeStyles({
wrapper: {
Expand All @@ -23,15 +21,9 @@ export default function DateRangePicker({
onToChange,
to,
label,
disabled
}) {
const classes = useStyles();
const quickRange = (hours) => {
const to = new Date();
const from = subHours(to, hours);

onFromChange(format(from, "yyyy-MM-dd'T'HH:mm"));
onToChange("");
};

return (
<div className={classes.wrapper}>
Expand All @@ -43,6 +35,7 @@ export default function DateRangePicker({
type="datetime-local"
fullWidth
clearable
disabled={disabled}
/>
<Input
className={classes.input}
Expand All @@ -52,17 +45,8 @@ export default function DateRangePicker({
type="datetime-local"
fullWidth
clearable
disabled={disabled}
/>
<FormControl className={classes.quick}>
<InputLabel>Quick Range</InputLabel>
<ButtonGroup
options={[
{ label: "3H", onClick: () => quickRange(3) },
{ label: "1D", onClick: () => quickRange(24) },
{ label: "7D", onClick: () => quickRange(168) },
]}
/>
</FormControl>
</div>
);
}
2 changes: 1 addition & 1 deletion ui/src/components/Input.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export default function ({ label, clearable, onBlur, onChange, ...props }) {
InputProps={{
endAdornment: clearable && (
<InputAdornment position="end" style={{ marginRight: -8 }}>
<IconButton size="small" onClick={handleClear}>
<IconButton size="small" onClick={handleClear} disabled={props.disabled}>
<ClearIcon />
</IconButton>
</InputAdornment>
Expand Down
44 changes: 27 additions & 17 deletions ui/src/components/KeyValueTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ import { makeStyles } from "@material-ui/core/styles";
import List from "@material-ui/core/List";
import ListItem from "@material-ui/core/ListItem";
import ListItemText from "@material-ui/core/ListItemText";
import { timestampRenderer, durationRenderer } from "../utils/helpers";
import _ from "lodash";

import { useEnv } from "../plugins/env";
import { timestampRenderer, durationRenderer } from "../utils/helpers";
import { customTypeRenderers } from "../plugins/customTypeRenderers";

const useStyles = makeStyles((theme) => ({
value: {
flex: 0.7,
Expand All @@ -21,25 +24,32 @@ const useStyles = makeStyles((theme) => ({

export default function KeyValueTable({ data }) {
const classes = useStyles();
const env = useEnv();
return (
<List>
{data.map((item, index) => {
let value;
switch (item.type) {
case "date":
value =
!isNaN(item.value) && item.value > 0
? timestampRenderer(item.value)
: "N/A";
break;
case "duration":
value =
!isNaN(item.value) && item.value > 0
? durationRenderer(item.value)
: "N/A";
break;
default:
value = !_.isNil(item.value) ? item.value : "N/A";
let displayValue;
const renderer = item.type ? customTypeRenderers[item.type] : null;
if(renderer){
displayValue = renderer(item.value, env)
}
else {
switch (item.type) {
case "date":
displayValue =
!isNaN(item.value) && item.value > 0
? timestampRenderer(item.value)
: "N/A";
break;
case "duration":
displayValue =
!isNaN(item.value) && item.value > 0
? durationRenderer(item.value)
: "N/A";
break;
default:
displayValue = !_.isNil(item.value) ? item.value : "N/A";
}
}

return (
Expand Down
17 changes: 16 additions & 1 deletion ui/src/components/NavLink.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from "react";
import { Link as RouterLink } from "react-router-dom";
import { Link as RouterLink, useHistory } from "react-router-dom";
import { Link } from "@material-ui/core";
import LaunchIcon from "@material-ui/icons/Launch";
import Url from "url-parse";
Expand All @@ -16,6 +16,7 @@ export default React.forwardRef((props, ref) => {
if (stack !== defaultStack) {
url.query.stack = stack;
}

if (!newTab) {
return (
<Link ref={ref} component={RouterLink} to={url.toString()} {...rest}>
Expand All @@ -32,3 +33,17 @@ export default React.forwardRef((props, ref) => {
);
}
});

export function usePushHistory(){
const history = useHistory();
const { stack, defaultStack } = useEnv();

return (path) => {
const url = new Url(path, {}, true);
if (stack !== defaultStack) {
url.query.stack = stack;
}

history.push(url.toString());
}
}
60 changes: 47 additions & 13 deletions ui/src/pages/execution/ActionModule.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import { PrimaryButton, DropdownButton } from "../../components";

import StopIcon from "@material-ui/icons/Stop";
import PauseIcon from "@material-ui/icons/Pause";
import RewindIcon from "@material-ui/icons/FastRewind";
import RestartIcon from "@material-ui/icons/SettingsBackupRestore";
import ReplayIcon from "@material-ui/icons/Replay";
import ResumeIcon from "@material-ui/icons/PlayArrow";
import FlareIcon from "@material-ui/icons/Flare";

import { useAction } from "../../utils/query";

const useStyles = makeStyles({
Expand All @@ -25,6 +27,11 @@ export default function ActionModule({ execution, triggerReload }) {
"post",
onSuccess
);
const restartLatestAction = useAction(
`/workflow/${workflowId}/restart?useLatestDefinitions=true`,
"post",
onSuccess
);
const retryAction = useAction(
`/workflow/${workflowId}/retry?resumeSubworkflowTasks=false`,
"post",
Expand Down Expand Up @@ -54,20 +61,37 @@ export default function ActionModule({ execution, triggerReload }) {
const { restartable } = workflowDefinition;

function onSuccess(data, variables, context) {
console.log(data, variables, context);
triggerReload();
}

if (execution.status === "COMPLETED") {
return (
<PrimaryButton
onClick={() => restartAction.mutate()}
className={classes.menuIcon}
>
<RewindIcon fontSize="small" /> Restart
</PrimaryButton>
);
} else if (execution.status === "RUNNING") {

const options = [];
if (restartable) {
options.push({
label: (
<>
<RestartIcon className={classes.menuIcon} fontSize="small" />
Restart with Current Definitions
</>
),
handler: () => restartAction.mutate(),
});

options.push({
label: (
<>
<FlareIcon className={classes.menuIcon} fontSize="small" />
Restart with Latest Definitions
</>
),
handler: () => restartLatestAction.mutate(),
});
}

return <DropdownButton options={options}>Actions</DropdownButton>;
}
else if (execution.status === "RUNNING") {
return (
<DropdownButton
options={[
Expand Down Expand Up @@ -112,12 +136,22 @@ export default function ActionModule({ execution, triggerReload }) {
options.push({
label: (
<>
<RewindIcon className={classes.menuIcon} fontSize="small" />
Restart workflow
<RestartIcon className={classes.menuIcon} fontSize="small" />
Restart with Current Definitions
</>
),
handler: () => restartAction.mutate(),
});

options.push({
label: (
<>
<FlareIcon className={classes.menuIcon} fontSize="small" />
Restart with Latest Definitions
</>
),
handler: () => restartLatestAction.mutate(),
});
}

options.push({
Expand Down
30 changes: 26 additions & 4 deletions ui/src/pages/execution/Execution.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { useState, useMemo } from "react";
import { useQueryState } from "react-router-use-location-state";
import { Drawer, Divider } from "@material-ui/core";

import {
Expand Down Expand Up @@ -118,8 +119,29 @@ export default function Execution() {

const { data: execution, isFetching, refetch: refresh } = useFetch(url);

const [tabIndex, setTabIndex] = useState(0);
const [tabIndex, setTabIndex] = useQueryState("tabIndex", 0);
const [selectedTask, setSelectedTask] = useState(null);

const handleSelectedTask = (task) => {
if(task){
const { taskToDomain } = execution;
let domain;
if(taskToDomain['*']){
domain = taskToDomain['*'];
}
else if(task.taskType){
domain = taskToDomain[task.taskType];
}

setSelectedTask({
...task,
domain: domain
});
}
else {
setSelectedTask(null);
}
}

const dag = useMemo(
() => (execution ? new WorkflowDAG(execution) : null),
Expand Down Expand Up @@ -178,7 +200,7 @@ export default function Execution() {
<TaskDetails
dag={dag}
execution={execution}
setSelectedTask={setSelectedTask}
setSelectedTask={handleSelectedTask}
selectedTask={selectedTask}
/>
)}
Expand All @@ -200,7 +222,7 @@ export default function Execution() {
}}
>
<div className={classes.drawerHeader}>
<IconButton onClick={() => setSelectedTask(null)}>
<IconButton onClick={() => handleSelectedTask(null)}>
<CloseIcon />
</IconButton>
</div>
Expand All @@ -209,7 +231,7 @@ export default function Execution() {
className={classes.drawerContent}
selectedTask={selectedTask}
dag={dag}
onTaskChange={setSelectedTask}
onTaskChange={handleSelectedTask}
/>
</Drawer>
</div>
Expand Down
1 change: 0 additions & 1 deletion ui/src/pages/execution/RightPanel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ export default function RightPanel({
label="Retried Task - Select an instance"
disableClearable
onChange={(e, v) => {
console.log(v);
onTaskChange({
ref: taskResult.referenceTaskName,
taskId: v.taskId,
Expand Down
5 changes: 5 additions & 0 deletions ui/src/pages/execution/TaskSummary.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,14 @@ export default function TaskSummary({ taskResult }) {
},
];

if (taskResult.domain) {
data.push({ label: "Domain", value: taskResult.domain });
}

if (taskResult.taskId) {
data.push({ label: "Task Execution ID", value: taskResult.taskId });
}

if (_.isFinite(taskResult.retryCount)) {
data.push({ label: "Retry Count", value: taskResult.retryCount });
}
Expand Down
1 change: 0 additions & 1 deletion ui/src/pages/execution/Timeline.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ export default function TimelineComponent({
}

const { items, groups } = useMemo(() => {
console.log("contructing timeline data");
const groupMap = new Map();
for (const task of tasks) {
groupMap.set(task.referenceTaskName, {
Expand Down
2 changes: 1 addition & 1 deletion ui/src/pages/executions/BulkActionModule.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export default function BulkActionModule({ selectedRows }) {
const { mutate: restartCurrentAction, isLoading: restartCurrentLoading } =
useAction(`/workflow/bulk/restart`, "post", { onSuccess });
const { mutate: restartLatestAction, isLoading: restartLatestLoading } =
useAction(`/workflow/bulk/restart?useLatestDefinition=true`, "post", {
useAction(`/workflow/bulk/restart?useLatestDefinitions=true`, "post", {
onSuccess,
});
const { mutate: retryAction, isLoading: retryLoading } = useAction(
Expand Down
1 change: 0 additions & 1 deletion ui/src/pages/executions/ResultsTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ export default function ResultsTable({
keyField="workflowId"
paginationServer
paginationTotalRows={totalHits}
pagination
paginationDefaultPage={page}
paginationPerPage={rowsPerPage}
onChangeRowsPerPage={(rowsPerPage) => setRowsPerPage(rowsPerPage)}
Expand Down
Loading