From 77361f4b573a0a9ba73fe52eb08a4be9c03f711a Mon Sep 17 00:00:00 2001 From: Eugene Jahn Date: Thu, 19 May 2022 02:16:49 -0700 Subject: [PATCH 1/8] feat: task rerun done Signed-off-by: Eugene Jahn --- .../ExecutionDetailsActions.tsx | 37 +++++++++++ .../NodeExecutionDetailsPanelContent.tsx | 9 +++ .../Executions/ExecutionDetails/strings.tsx | 8 +++ .../Tables/NodeExecutionActions.tsx | 63 +++++++++++++++++++ .../Tables/nodeExecutionColumns.tsx | 7 ++- .../Launch/LaunchForm/LaunchFormDialog.tsx | 38 +++++++++++ 6 files changed, 159 insertions(+), 3 deletions(-) create mode 100644 packages/zapp/console/src/components/Executions/ExecutionDetails/ExecutionDetailsActions.tsx create mode 100644 packages/zapp/console/src/components/Executions/ExecutionDetails/strings.tsx create mode 100644 packages/zapp/console/src/components/Executions/Tables/NodeExecutionActions.tsx create mode 100644 packages/zapp/console/src/components/Launch/LaunchForm/LaunchFormDialog.tsx diff --git a/packages/zapp/console/src/components/Executions/ExecutionDetails/ExecutionDetailsActions.tsx b/packages/zapp/console/src/components/Executions/ExecutionDetails/ExecutionDetailsActions.tsx new file mode 100644 index 000000000..747c0edb1 --- /dev/null +++ b/packages/zapp/console/src/components/Executions/ExecutionDetails/ExecutionDetailsActions.tsx @@ -0,0 +1,37 @@ +import { Button } from '@material-ui/core'; +import * as React from 'react'; +import { ResourceIdentifier } from 'models/Common/types'; +import { LaunchFormDialog } from 'components/Launch/LaunchForm/LaunchFormDialog'; +import { NodeExecutionDetails } from '../types'; +import t from './strings'; + +export const ExecutionDetailsActions: React.FC<{ + className?: string; + details: NodeExecutionDetails; +}> = ({ className, details }) => { + const [showLaunchForm, setShowLaunchForm] = React.useState(false); + + const id = details.taskTemplate?.id as ResourceIdentifier | undefined; + + const rerunOnClick = (e: React.MouseEvent) => { + e.stopPropagation(); + setShowLaunchForm(true); + }; + + return ( + <> +
+ +
+ {id && ( + + )} + + ); +}; diff --git a/packages/zapp/console/src/components/Executions/ExecutionDetails/NodeExecutionDetailsPanelContent.tsx b/packages/zapp/console/src/components/Executions/ExecutionDetails/NodeExecutionDetailsPanelContent.tsx index f0575986b..b1643c22b 100644 --- a/packages/zapp/console/src/components/Executions/ExecutionDetails/NodeExecutionDetailsPanelContent.tsx +++ b/packages/zapp/console/src/components/Executions/ExecutionDetails/NodeExecutionDetailsPanelContent.tsx @@ -41,6 +41,7 @@ import { getTaskExecutionDetailReasons } from './utils'; import { ExpandableMonospaceText } from '../../common/ExpandableMonospaceText'; import { fetchWorkflowExecution } from '../useWorkflowExecution'; import { NodeExecutionTabs } from './NodeExecutionTabs'; +import { ExecutionDetailsActions } from './ExecutionDetailsActions'; const useStyles = makeStyles((theme: Theme) => { const paddingVertical = `${theme.spacing(2)}px`; @@ -93,6 +94,11 @@ const useStyles = makeStyles((theme: Theme) => { marginTop: theme.spacing(2), paddingTop: theme.spacing(2), }, + actionsContainer: { + borderTop: `1px solid ${theme.palette.divider}`, + marginTop: theme.spacing(2), + paddingTop: theme.spacing(2), + }, nodeTypeContent: { minWidth: theme.spacing(9), }, @@ -395,6 +401,9 @@ export const NodeExecutionDetailsPanelContent: React.FC {statusContent} {!dag && detailsContent} + {details && ( + + )} {dag ? : tabsContent} diff --git a/packages/zapp/console/src/components/Executions/ExecutionDetails/strings.tsx b/packages/zapp/console/src/components/Executions/ExecutionDetails/strings.tsx new file mode 100644 index 000000000..4595ae70e --- /dev/null +++ b/packages/zapp/console/src/components/Executions/ExecutionDetails/strings.tsx @@ -0,0 +1,8 @@ +import { createLocalizedString } from '@flyteconsole/locale'; + +const str = { + rerun: 'RERUN', +}; + +export { patternKey } from '@flyteconsole/locale'; +export default createLocalizedString(str); diff --git a/packages/zapp/console/src/components/Executions/Tables/NodeExecutionActions.tsx b/packages/zapp/console/src/components/Executions/Tables/NodeExecutionActions.tsx new file mode 100644 index 000000000..62c2062b2 --- /dev/null +++ b/packages/zapp/console/src/components/Executions/Tables/NodeExecutionActions.tsx @@ -0,0 +1,63 @@ +import { IconButton } from '@material-ui/core'; +import { NodeExecution } from 'models/Execution/types'; +import * as React from 'react'; +import InputsAndOutputsIcon from '@material-ui/icons/Tv'; +import RerunIcon from '@material-ui/icons/Autorenew'; +import { ResourceIdentifier } from 'models/Common/types'; +import { LaunchFormDialog } from 'components/Launch/LaunchForm/LaunchFormDialog'; +import { NodeExecutionsTableState } from './types'; +import { useNodeExecutionContext } from '../contextProvider/NodeExecutionDetails'; +import { NodeExecutionDetails } from '../types'; + +export const NodeExecutionActions: React.FC<{ + className?: string; + execution: NodeExecution; + state: NodeExecutionsTableState; +}> = ({ className, execution, state }) => { + const detailsContext = useNodeExecutionContext(); + const [showLaunchForm, setShowLaunchForm] = React.useState(false); + const [nodeExecutionDetails, setNodeExecutionDetails] = React.useState< + NodeExecutionDetails | undefined + >(); + + // open the side panel for selected execution's detail + const inputsAndOutputsIconOnClick = (e: React.MouseEvent) => { + // prevent the parent row body onClick event trigger + e.stopPropagation(); + // use null in case if there is no execution provided - when it is null will close panel + state.setSelectedExecution(execution?.id ?? null); + }; + + const rerunIconOnClick = (e: React.MouseEvent) => { + e.stopPropagation(); + setShowLaunchForm(true); + }; + + React.useEffect(() => { + detailsContext.getNodeExecutionDetails(execution).then((res) => { + setNodeExecutionDetails(res); + }); + }); + + const id = nodeExecutionDetails?.taskTemplate?.id as ResourceIdentifier | undefined; + + return ( + <> +
+ + + + + + +
+ {id && ( + + )} + + ); +}; diff --git a/packages/zapp/console/src/components/Executions/Tables/nodeExecutionColumns.tsx b/packages/zapp/console/src/components/Executions/Tables/nodeExecutionColumns.tsx index e03d00d47..5a9925b62 100644 --- a/packages/zapp/console/src/components/Executions/Tables/nodeExecutionColumns.tsx +++ b/packages/zapp/console/src/components/Executions/Tables/nodeExecutionColumns.tsx @@ -10,6 +10,7 @@ import { useNodeExecutionContext } from '../contextProvider/NodeExecutionDetails import { ExecutionStatusBadge } from '../ExecutionStatusBadge'; import { NodeExecutionCacheStatus } from '../NodeExecutionCacheStatus'; import { getNodeExecutionTimingMS } from '../utils'; +import { NodeExecutionActions } from './NodeExecutionActions'; import { SelectNodeExecutionLink } from './SelectNodeExecutionLink'; import { useColumnStyles } from './styles'; import { NodeExecutionCellRendererData, NodeExecutionColumnDefinition } from './types'; @@ -201,11 +202,11 @@ export function generateColumns( }, { cellRenderer: ({ execution, state }) => ( - + ), className: styles.columnLogs, - key: 'logs', - label: 'logs', + key: 'actions', + label: '', }, ]; } diff --git a/packages/zapp/console/src/components/Launch/LaunchForm/LaunchFormDialog.tsx b/packages/zapp/console/src/components/Launch/LaunchForm/LaunchFormDialog.tsx new file mode 100644 index 000000000..cbcb1b7df --- /dev/null +++ b/packages/zapp/console/src/components/Launch/LaunchForm/LaunchFormDialog.tsx @@ -0,0 +1,38 @@ +import { Dialog } from '@material-ui/core'; +import * as React from 'react'; +import { LaunchForm } from 'components/Launch/LaunchForm/LaunchForm'; +import { ResourceIdentifier, ResourceType } from 'models/Common/types'; + +function getLaunchProps(id: ResourceIdentifier) { + if (id.resourceType === ResourceType.TASK) { + return { taskId: id }; + } + + return { workflowId: id }; +} + +export const LaunchFormDialog: React.FC<{ + className?: string; + id: ResourceIdentifier; + showLaunchForm: boolean; + setShowLaunchForm: React.Dispatch>; +}> = ({ className, id, showLaunchForm, setShowLaunchForm }) => { + const onCancelLaunch = () => setShowLaunchForm(false); + + // prevent child onclick event in the dialog triggers parent onclick event + const dialogOnClick = (e: React.MouseEvent) => { + e.stopPropagation(); + }; + + return ( + + + + ); +}; From 5665732268a60f8489b5d5f78e32646a3bcb12ca Mon Sep 17 00:00:00 2001 From: Eugene Jahn Date: Fri, 20 May 2022 13:47:05 -0700 Subject: [PATCH 2/8] feat: fix initialParameters Signed-off-by: Eugene Jahn --- .../ExecutionDetailsActions.tsx | 18 ++++- .../NodeExecutionDetailsPanelContent.tsx | 6 +- .../Tables/NodeExecutionActions.tsx | 35 +++++++--- .../components/Executions/Tables/strings.tsx | 9 +++ .../Launch/LaunchForm/LaunchFormDialog.tsx | 13 +++- .../src/components/Launch/LaunchForm/utils.ts | 67 ++++++++++++++++++- .../src/components/common/Icons/RerunIcon.tsx | 20 ++++++ .../zapp/console/src/models/Common/types.ts | 2 + 8 files changed, 155 insertions(+), 15 deletions(-) create mode 100644 packages/zapp/console/src/components/Executions/Tables/strings.tsx create mode 100644 packages/zapp/console/src/components/common/Icons/RerunIcon.tsx diff --git a/packages/zapp/console/src/components/Executions/ExecutionDetails/ExecutionDetailsActions.tsx b/packages/zapp/console/src/components/Executions/ExecutionDetails/ExecutionDetailsActions.tsx index 747c0edb1..74eab4d58 100644 --- a/packages/zapp/console/src/components/Executions/ExecutionDetails/ExecutionDetailsActions.tsx +++ b/packages/zapp/console/src/components/Executions/ExecutionDetails/ExecutionDetailsActions.tsx @@ -1,18 +1,31 @@ import { Button } from '@material-ui/core'; import * as React from 'react'; -import { ResourceIdentifier } from 'models/Common/types'; +import { ResourceIdentifier, Identifier } from 'models/Common/types'; import { LaunchFormDialog } from 'components/Launch/LaunchForm/LaunchFormDialog'; +import { NodeExecutionIdentifier } from 'models/Execution/types'; +import { useNodeExecutionData } from 'components/hooks/useNodeExecution'; +import { literalsToLiteralValueMap } from 'components/Launch/LaunchForm/utils'; +import { TaskInitialLaunchParameters } from 'components/Launch/LaunchForm/types'; import { NodeExecutionDetails } from '../types'; import t from './strings'; export const ExecutionDetailsActions: React.FC<{ className?: string; details: NodeExecutionDetails; -}> = ({ className, details }) => { + nodeExecutionId: NodeExecutionIdentifier; +}> = ({ className, details, nodeExecutionId }) => { const [showLaunchForm, setShowLaunchForm] = React.useState(false); + const executionData = useNodeExecutionData(nodeExecutionId); const id = details.taskTemplate?.id as ResourceIdentifier | undefined; + const literals = executionData.value.fullInputs?.literals; + + const initialParameters: TaskInitialLaunchParameters = { + values: literals && literalsToLiteralValueMap(literals), + taskId: id as Identifier | undefined, + }; + const rerunOnClick = (e: React.MouseEvent) => { e.stopPropagation(); setShowLaunchForm(true); @@ -28,6 +41,7 @@ export const ExecutionDetailsActions: React.FC<{ {id && ( diff --git a/packages/zapp/console/src/components/Executions/ExecutionDetails/NodeExecutionDetailsPanelContent.tsx b/packages/zapp/console/src/components/Executions/ExecutionDetails/NodeExecutionDetailsPanelContent.tsx index b1643c22b..ee96d2c34 100644 --- a/packages/zapp/console/src/components/Executions/ExecutionDetails/NodeExecutionDetailsPanelContent.tsx +++ b/packages/zapp/console/src/components/Executions/ExecutionDetails/NodeExecutionDetailsPanelContent.tsx @@ -402,7 +402,11 @@ export const NodeExecutionDetailsPanelContent: React.FC + )} diff --git a/packages/zapp/console/src/components/Executions/Tables/NodeExecutionActions.tsx b/packages/zapp/console/src/components/Executions/Tables/NodeExecutionActions.tsx index 62c2062b2..d28b92ae8 100644 --- a/packages/zapp/console/src/components/Executions/Tables/NodeExecutionActions.tsx +++ b/packages/zapp/console/src/components/Executions/Tables/NodeExecutionActions.tsx @@ -1,13 +1,17 @@ -import { IconButton } from '@material-ui/core'; +import { IconButton, Tooltip } from '@material-ui/core'; import { NodeExecution } from 'models/Execution/types'; import * as React from 'react'; import InputsAndOutputsIcon from '@material-ui/icons/Tv'; -import RerunIcon from '@material-ui/icons/Autorenew'; -import { ResourceIdentifier } from 'models/Common/types'; +import { RerunIcon } from 'components/common/Icons/RerunIcon'; +import { Identifier, ResourceIdentifier } from 'models/Common/types'; import { LaunchFormDialog } from 'components/Launch/LaunchForm/LaunchFormDialog'; +import { useNodeExecutionData } from 'components/hooks/useNodeExecution'; +import { TaskInitialLaunchParameters } from 'components/Launch/LaunchForm/types'; +import { literalsToLiteralValueMap } from 'components/Launch/LaunchForm/utils'; import { NodeExecutionsTableState } from './types'; import { useNodeExecutionContext } from '../contextProvider/NodeExecutionDetails'; import { NodeExecutionDetails } from '../types'; +import t from './strings'; export const NodeExecutionActions: React.FC<{ className?: string; @@ -20,6 +24,8 @@ export const NodeExecutionActions: React.FC<{ NodeExecutionDetails | undefined >(); + const executionData = useNodeExecutionData(execution.id); + // open the side panel for selected execution's detail const inputsAndOutputsIconOnClick = (e: React.MouseEvent) => { // prevent the parent row body onClick event trigger @@ -39,21 +45,32 @@ export const NodeExecutionActions: React.FC<{ }); }); + const literals = executionData.value.fullInputs?.literals; const id = nodeExecutionDetails?.taskTemplate?.id as ResourceIdentifier | undefined; + const initialParameters: TaskInitialLaunchParameters = { + values: literals && literalsToLiteralValueMap(literals), + taskId: id as Identifier | undefined, + }; + return ( <>
- - - - - - + + + + + + + + + +
{id && ( diff --git a/packages/zapp/console/src/components/Executions/Tables/strings.tsx b/packages/zapp/console/src/components/Executions/Tables/strings.tsx new file mode 100644 index 000000000..402c312c7 --- /dev/null +++ b/packages/zapp/console/src/components/Executions/Tables/strings.tsx @@ -0,0 +1,9 @@ +import { createLocalizedString } from '@flyteconsole/locale'; + +const str = { + inputsAndOutputsTooltip: 'View Inputs & Outpus', + rerunTooltip: 'Rerun', +}; + +export { patternKey } from '@flyteconsole/locale'; +export default createLocalizedString(str); diff --git a/packages/zapp/console/src/components/Launch/LaunchForm/LaunchFormDialog.tsx b/packages/zapp/console/src/components/Launch/LaunchForm/LaunchFormDialog.tsx index cbcb1b7df..1b3c0074e 100644 --- a/packages/zapp/console/src/components/Launch/LaunchForm/LaunchFormDialog.tsx +++ b/packages/zapp/console/src/components/Launch/LaunchForm/LaunchFormDialog.tsx @@ -2,6 +2,10 @@ import { Dialog } from '@material-ui/core'; import * as React from 'react'; import { LaunchForm } from 'components/Launch/LaunchForm/LaunchForm'; import { ResourceIdentifier, ResourceType } from 'models/Common/types'; +import { + TaskInitialLaunchParameters, + WorkflowInitialLaunchParameters, +} from 'components/Launch/LaunchForm/types'; function getLaunchProps(id: ResourceIdentifier) { if (id.resourceType === ResourceType.TASK) { @@ -14,9 +18,10 @@ function getLaunchProps(id: ResourceIdentifier) { export const LaunchFormDialog: React.FC<{ className?: string; id: ResourceIdentifier; + initialParameters: TaskInitialLaunchParameters | WorkflowInitialLaunchParameters; showLaunchForm: boolean; setShowLaunchForm: React.Dispatch>; -}> = ({ className, id, showLaunchForm, setShowLaunchForm }) => { +}> = ({ className, id, initialParameters, showLaunchForm, setShowLaunchForm }) => { const onCancelLaunch = () => setShowLaunchForm(false); // prevent child onclick event in the dialog triggers parent onclick event @@ -32,7 +37,11 @@ export const LaunchFormDialog: React.FC<{ open={showLaunchForm} onClick={dialogOnClick} > - + ); }; diff --git a/packages/zapp/console/src/components/Launch/LaunchForm/utils.ts b/packages/zapp/console/src/components/Launch/LaunchForm/utils.ts index 2b8befe5d..ed54fb694 100644 --- a/packages/zapp/console/src/components/Launch/LaunchForm/utils.ts +++ b/packages/zapp/console/src/components/Launch/LaunchForm/utils.ts @@ -1,11 +1,12 @@ import { timestampToDate } from 'common/utils'; import { Core } from 'flyteidl'; import { isObject } from 'lodash'; -import { Identifier, LiteralType, Variable } from 'models/Common/types'; +import { Identifier, LiteralType, Scalar, Variable } from 'models/Common/types'; import { LaunchPlan } from 'models/Launch/types'; import { Task } from 'models/Task/types'; import { Workflow } from 'models/Workflow/types'; import * as moment from 'moment'; +import { LiteralValueMap } from 'components/Launch/LaunchForm/types'; import { simpleTypeToInputType, typeLabels } from './constants'; import { inputToLiteral } from './inputHelpers/inputHelpers'; import { typeIsSupported } from './inputHelpers/utils'; @@ -155,6 +156,12 @@ export function getInputDefintionForLiteralType(literalType: LiteralType): Input result.type = simpleTypeToInputType[literalType.simple]; } else if (literalType.enumType) { result.type = InputType.Enum; + } else if (literalType.primitive) { + if (literalType.primitive.stringValue) { + result.type = InputType.String; + } else if (literalType.primitive.integer) { + result.type = InputType.Integer; + } } return result; } @@ -190,3 +197,61 @@ export function isEnterInputsState(state: BaseInterpretedLaunchState): boolean { LaunchState.SUBMIT_SUCCEEDED, ].some(state.matches); } + +export function literalsToLiteralValueMap(literals: { + [k: string]: Core.ILiteral; +}): LiteralValueMap { + const literalValueMap: LiteralValueMap = new Map(); + if (literals) { + for (var i = 0; i < Object.keys(literals).length; i++) { + const name = Object.keys(literals)[i]; + const value = literals[name]; + let typeDefinition: InputTypeDefinition | undefined; + if (value?.scalar) { + typeDefinition = getInputDefintionForScalar(value.scalar); + } else if (value?.collection) { + typeDefinition = { + literalType: value.collection, + type: InputType.Collection, + } as InputTypeDefinition; + } + if (typeDefinition) { + const inputKey = createInputCacheKey(name, typeDefinition); + literalValueMap.set(inputKey, literals[Object.keys(literals)[i]]); + } + } + } + return literalValueMap; +} + +/** Converts a `Scalar` to an `InputTypeDefintion` to assist with rendering + * a type annotation and converting input values. + */ +export function getInputDefintionForScalar(scalar: Core.IScalar): InputTypeDefinition { + const result: InputTypeDefinition = { + literalType: scalar as LiteralType, + type: InputType.Unknown, + }; + + if (scalar.binary) { + result.type = InputType.Binary; + } else if (scalar.blob) { + result.type = InputType.Blob; + } else if (scalar.error) { + result.type = InputType.Error; + } else if (scalar.noneType) { + result.type = InputType.None; + } else if (scalar.primitive) { + if (scalar.primitive.stringValue) { + result.type = InputType.String; + } else if (scalar.primitive.floatValue) { + result.type = InputType.Float; + } else if (scalar.primitive.integer) { + result.type = InputType.Integer; + } else if (scalar.primitive.boolean) { + result.type = InputType.Boolean; + } + } + + return result; +} diff --git a/packages/zapp/console/src/components/common/Icons/RerunIcon.tsx b/packages/zapp/console/src/components/common/Icons/RerunIcon.tsx new file mode 100644 index 000000000..8afaba945 --- /dev/null +++ b/packages/zapp/console/src/components/common/Icons/RerunIcon.tsx @@ -0,0 +1,20 @@ +import * as React from 'react'; +import { IconProps } from './interface'; + +export const RerunIcon: React.FC = ({ size = 18, className, onClick }) => { + return ( + + + + ); +}; diff --git a/packages/zapp/console/src/models/Common/types.ts b/packages/zapp/console/src/models/Common/types.ts index e93e63c22..c2336dc02 100644 --- a/packages/zapp/console/src/models/Common/types.ts +++ b/packages/zapp/console/src/models/Common/types.ts @@ -1,3 +1,4 @@ +import { PrimitiveType } from 'components/Launch/LaunchForm/inputHelpers/struct'; import { Admin, Core, Protobuf } from 'flyteidl'; /* --- BEGIN flyteidl type aliases --- */ @@ -150,6 +151,7 @@ export interface LiteralType extends Core.ILiteralType { schema?: SchemaType; simple?: SimpleType; enumType?: EnumType; + primitive?: Primitive; } export interface Variable extends Core.IVariable { From d205ea4a85e6e00dba5f07559d8e8b7f477bf6e9 Mon Sep 17 00:00:00 2001 From: Eugene Jahn Date: Fri, 20 May 2022 13:51:36 -0700 Subject: [PATCH 3/8] fix: remove a file Signed-off-by: Eugene Jahn --- .../console/src/components/Launch/LaunchForm/utils.ts | 8 +------- packages/zapp/console/src/models/Common/types.ts | 2 -- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/packages/zapp/console/src/components/Launch/LaunchForm/utils.ts b/packages/zapp/console/src/components/Launch/LaunchForm/utils.ts index ed54fb694..0200a6222 100644 --- a/packages/zapp/console/src/components/Launch/LaunchForm/utils.ts +++ b/packages/zapp/console/src/components/Launch/LaunchForm/utils.ts @@ -1,7 +1,7 @@ import { timestampToDate } from 'common/utils'; import { Core } from 'flyteidl'; import { isObject } from 'lodash'; -import { Identifier, LiteralType, Scalar, Variable } from 'models/Common/types'; +import { Identifier, LiteralType, Variable } from 'models/Common/types'; import { LaunchPlan } from 'models/Launch/types'; import { Task } from 'models/Task/types'; import { Workflow } from 'models/Workflow/types'; @@ -156,12 +156,6 @@ export function getInputDefintionForLiteralType(literalType: LiteralType): Input result.type = simpleTypeToInputType[literalType.simple]; } else if (literalType.enumType) { result.type = InputType.Enum; - } else if (literalType.primitive) { - if (literalType.primitive.stringValue) { - result.type = InputType.String; - } else if (literalType.primitive.integer) { - result.type = InputType.Integer; - } } return result; } diff --git a/packages/zapp/console/src/models/Common/types.ts b/packages/zapp/console/src/models/Common/types.ts index c2336dc02..e93e63c22 100644 --- a/packages/zapp/console/src/models/Common/types.ts +++ b/packages/zapp/console/src/models/Common/types.ts @@ -1,4 +1,3 @@ -import { PrimitiveType } from 'components/Launch/LaunchForm/inputHelpers/struct'; import { Admin, Core, Protobuf } from 'flyteidl'; /* --- BEGIN flyteidl type aliases --- */ @@ -151,7 +150,6 @@ export interface LiteralType extends Core.ILiteralType { schema?: SchemaType; simple?: SimpleType; enumType?: EnumType; - primitive?: Primitive; } export interface Variable extends Core.IVariable { From 4ed2d094600f933d0e3751c1e002c1c92c4e7a1f Mon Sep 17 00:00:00 2001 From: Eugene Jahn Date: Fri, 20 May 2022 15:14:40 -0700 Subject: [PATCH 4/8] feat: rerun task done Signed-off-by: Eugene Jahn --- .../ExecutionDetailsActions.tsx | 18 ++++---- .../Tables/NodeExecutionActions.tsx | 42 ++++++++++++------- .../Launch/LaunchForm/LaunchFormDialog.tsx | 5 ++- 3 files changed, 39 insertions(+), 26 deletions(-) diff --git a/packages/zapp/console/src/components/Executions/ExecutionDetails/ExecutionDetailsActions.tsx b/packages/zapp/console/src/components/Executions/ExecutionDetails/ExecutionDetailsActions.tsx index 74eab4d58..2ffe60b1f 100644 --- a/packages/zapp/console/src/components/Executions/ExecutionDetails/ExecutionDetailsActions.tsx +++ b/packages/zapp/console/src/components/Executions/ExecutionDetails/ExecutionDetailsActions.tsx @@ -19,6 +19,10 @@ export const ExecutionDetailsActions: React.FC<{ const id = details.taskTemplate?.id as ResourceIdentifier | undefined; + if (!id) { + return <>; + } + const literals = executionData.value.fullInputs?.literals; const initialParameters: TaskInitialLaunchParameters = { @@ -38,14 +42,12 @@ export const ExecutionDetailsActions: React.FC<{ {t('rerun')} - {id && ( - - )} + ); }; diff --git a/packages/zapp/console/src/components/Executions/Tables/NodeExecutionActions.tsx b/packages/zapp/console/src/components/Executions/Tables/NodeExecutionActions.tsx index d28b92ae8..3637f9884 100644 --- a/packages/zapp/console/src/components/Executions/Tables/NodeExecutionActions.tsx +++ b/packages/zapp/console/src/components/Executions/Tables/NodeExecutionActions.tsx @@ -46,35 +46,45 @@ export const NodeExecutionActions: React.FC<{ }); const literals = executionData.value.fullInputs?.literals; - const id = nodeExecutionDetails?.taskTemplate?.id as ResourceIdentifier | undefined; - const initialParameters: TaskInitialLaunchParameters = { - values: literals && literalsToLiteralValueMap(literals), - taskId: id as Identifier | undefined, - }; + const renderRerunAction = () => { + const id = nodeExecutionDetails?.taskTemplate?.id as ResourceIdentifier; - return ( - <> -
- - - - - + if (!id) { + return <>; + } + + const initialParameters: TaskInitialLaunchParameters = { + values: literals && literalsToLiteralValueMap(literals), + taskId: id as Identifier | undefined, + }; + return ( + <> -
- {id && ( - )} + + ); + }; + + return ( + <> +
+ + + + + + {renderRerunAction()} +
); }; diff --git a/packages/zapp/console/src/components/Launch/LaunchForm/LaunchFormDialog.tsx b/packages/zapp/console/src/components/Launch/LaunchForm/LaunchFormDialog.tsx index 1b3c0074e..0ae0177a3 100644 --- a/packages/zapp/console/src/components/Launch/LaunchForm/LaunchFormDialog.tsx +++ b/packages/zapp/console/src/components/Launch/LaunchForm/LaunchFormDialog.tsx @@ -10,9 +10,10 @@ import { function getLaunchProps(id: ResourceIdentifier) { if (id.resourceType === ResourceType.TASK) { return { taskId: id }; + } else if (id.resourceType === ResourceType.WORKFLOW) { + return { workflowId: id }; } - - return { workflowId: id }; + throw new Error('Unknown Resource Type'); } export const LaunchFormDialog: React.FC<{ From 5a70205cbc8da50438d6468e679b44a8c5aa5b98 Mon Sep 17 00:00:00 2001 From: Eugene Jahn Date: Thu, 26 May 2022 11:51:34 -0700 Subject: [PATCH 5/8] feat: rerun fix literal type Signed-off-by: Eugene Jahn --- .../ui-atoms/src/Icons/RerunIcon/index.tsx} | 10 +++- .../composites/ui-atoms/src/Icons/index.tsx | 1 + .../ExecutionDetailsActions.tsx | 25 +++++++-- .../Tables/NodeExecutionActions.tsx | 49 ++++++++++------- .../Launch/LaunchForm/LaunchFormDialog.tsx | 17 +++--- .../src/components/Launch/LaunchForm/utils.ts | 55 ++++--------------- 6 files changed, 80 insertions(+), 77 deletions(-) rename packages/{zapp/console/src/components/common/Icons/RerunIcon.tsx => composites/ui-atoms/src/Icons/RerunIcon/index.tsx} (67%) diff --git a/packages/zapp/console/src/components/common/Icons/RerunIcon.tsx b/packages/composites/ui-atoms/src/Icons/RerunIcon/index.tsx similarity index 67% rename from packages/zapp/console/src/components/common/Icons/RerunIcon.tsx rename to packages/composites/ui-atoms/src/Icons/RerunIcon/index.tsx index 8afaba945..048345443 100644 --- a/packages/zapp/console/src/components/common/Icons/RerunIcon.tsx +++ b/packages/composites/ui-atoms/src/Icons/RerunIcon/index.tsx @@ -1,7 +1,13 @@ import * as React from 'react'; -import { IconProps } from './interface'; -export const RerunIcon: React.FC = ({ size = 18, className, onClick }) => { +interface IconProps { + size?: number; + className?: string; + onClick?: () => void; +} + +export const RerunIcon = (props: IconProps): JSX.Element => { + const { size = 18, className, onClick } = props; return ( = ({ className, details, nodeExecutionId }) => { +} + +export const ExecutionDetailsActions = (props: ExecutionDetailsActionsProps): JSX.Element => { + const { className, details, nodeExecutionId } = props; + const [showLaunchForm, setShowLaunchForm] = React.useState(false); + const [taskInputsTypes, setTaskInputsTypes] = React.useState< + Record | undefined + >(); + const executionData = useNodeExecutionData(nodeExecutionId); const id = details.taskTemplate?.id as ResourceIdentifier | undefined; @@ -23,10 +32,18 @@ export const ExecutionDetailsActions: React.FC<{ return <>; } + React.useEffect(() => { + const fetchTask = async () => { + const task = await getTask(id as Identifier); + setTaskInputsTypes(task.closure.compiledTask.template?.interface?.inputs?.variables); + }; + fetchTask(); + }, [id]); + const literals = executionData.value.fullInputs?.literals; const initialParameters: TaskInitialLaunchParameters = { - values: literals && literalsToLiteralValueMap(literals), + values: literals && taskInputsTypes && literalsToLiteralValueMap(literals, taskInputsTypes), taskId: id as Identifier | undefined, }; diff --git a/packages/zapp/console/src/components/Executions/Tables/NodeExecutionActions.tsx b/packages/zapp/console/src/components/Executions/Tables/NodeExecutionActions.tsx index 3637f9884..bcaf53058 100644 --- a/packages/zapp/console/src/components/Executions/Tables/NodeExecutionActions.tsx +++ b/packages/zapp/console/src/components/Executions/Tables/NodeExecutionActions.tsx @@ -2,9 +2,10 @@ import { IconButton, Tooltip } from '@material-ui/core'; import { NodeExecution } from 'models/Execution/types'; import * as React from 'react'; import InputsAndOutputsIcon from '@material-ui/icons/Tv'; -import { RerunIcon } from 'components/common/Icons/RerunIcon'; -import { Identifier, ResourceIdentifier } from 'models/Common/types'; +import { RerunIcon } from '@flyteconsole/ui-atoms'; +import { Identifier, ResourceIdentifier, Variable } from 'models/Common/types'; import { LaunchFormDialog } from 'components/Launch/LaunchForm/LaunchFormDialog'; +import { getTask } from 'models/Task/api'; import { useNodeExecutionData } from 'components/hooks/useNodeExecution'; import { TaskInitialLaunchParameters } from 'components/Launch/LaunchForm/types'; import { literalsToLiteralValueMap } from 'components/Launch/LaunchForm/utils'; @@ -13,18 +14,26 @@ import { useNodeExecutionContext } from '../contextProvider/NodeExecutionDetails import { NodeExecutionDetails } from '../types'; import t from './strings'; -export const NodeExecutionActions: React.FC<{ - className?: string; +interface NodeExecutionActionsProps { execution: NodeExecution; state: NodeExecutionsTableState; -}> = ({ className, execution, state }) => { +} + +export const NodeExecutionActions = (props: NodeExecutionActionsProps): JSX.Element => { + const { execution, state } = props; + const detailsContext = useNodeExecutionContext(); const [showLaunchForm, setShowLaunchForm] = React.useState(false); const [nodeExecutionDetails, setNodeExecutionDetails] = React.useState< NodeExecutionDetails | undefined >(); + const [taskInputsTypes, setTaskInputsTypes] = React.useState< + Record | undefined + >(); const executionData = useNodeExecutionData(execution.id); + const literals = executionData.value.fullInputs?.literals; + const id = nodeExecutionDetails?.taskTemplate?.id as ResourceIdentifier; // open the side panel for selected execution's detail const inputsAndOutputsIconOnClick = (e: React.MouseEvent) => { @@ -45,17 +54,21 @@ export const NodeExecutionActions: React.FC<{ }); }); - const literals = executionData.value.fullInputs?.literals; + React.useEffect(() => { + const fetchTask = async () => { + const task = await getTask(id as Identifier); + setTaskInputsTypes(task.closure.compiledTask.template?.interface?.inputs?.variables); + }; + if (id) fetchTask(); + }, [id]); const renderRerunAction = () => { - const id = nodeExecutionDetails?.taskTemplate?.id as ResourceIdentifier; - if (!id) { return <>; } const initialParameters: TaskInitialLaunchParameters = { - values: literals && literalsToLiteralValueMap(literals), + values: literals && taskInputsTypes && literalsToLiteralValueMap(literals, taskInputsTypes), taskId: id as Identifier | undefined, }; return ( @@ -76,15 +89,13 @@ export const NodeExecutionActions: React.FC<{ }; return ( - <> -
- - - - - - {renderRerunAction()} -
- +
+ + + + + + {renderRerunAction()} +
); }; diff --git a/packages/zapp/console/src/components/Launch/LaunchForm/LaunchFormDialog.tsx b/packages/zapp/console/src/components/Launch/LaunchForm/LaunchFormDialog.tsx index 0ae0177a3..1c3a25716 100644 --- a/packages/zapp/console/src/components/Launch/LaunchForm/LaunchFormDialog.tsx +++ b/packages/zapp/console/src/components/Launch/LaunchForm/LaunchFormDialog.tsx @@ -7,6 +7,13 @@ import { WorkflowInitialLaunchParameters, } from 'components/Launch/LaunchForm/types'; +interface LaunchFormDialogProps { + id: ResourceIdentifier; + initialParameters: TaskInitialLaunchParameters | WorkflowInitialLaunchParameters; + showLaunchForm: boolean; + setShowLaunchForm: React.Dispatch>; +} + function getLaunchProps(id: ResourceIdentifier) { if (id.resourceType === ResourceType.TASK) { return { taskId: id }; @@ -16,13 +23,9 @@ function getLaunchProps(id: ResourceIdentifier) { throw new Error('Unknown Resource Type'); } -export const LaunchFormDialog: React.FC<{ - className?: string; - id: ResourceIdentifier; - initialParameters: TaskInitialLaunchParameters | WorkflowInitialLaunchParameters; - showLaunchForm: boolean; - setShowLaunchForm: React.Dispatch>; -}> = ({ className, id, initialParameters, showLaunchForm, setShowLaunchForm }) => { +export const LaunchFormDialog = (props: LaunchFormDialogProps): JSX.Element => { + const { id, initialParameters, showLaunchForm, setShowLaunchForm } = props; + const onCancelLaunch = () => setShowLaunchForm(false); // prevent child onclick event in the dialog triggers parent onclick event diff --git a/packages/zapp/console/src/components/Launch/LaunchForm/utils.ts b/packages/zapp/console/src/components/Launch/LaunchForm/utils.ts index 0200a6222..5c7f52aa0 100644 --- a/packages/zapp/console/src/components/Launch/LaunchForm/utils.ts +++ b/packages/zapp/console/src/components/Launch/LaunchForm/utils.ts @@ -192,60 +192,25 @@ export function isEnterInputsState(state: BaseInterpretedLaunchState): boolean { ].some(state.matches); } -export function literalsToLiteralValueMap(literals: { - [k: string]: Core.ILiteral; -}): LiteralValueMap { +export function literalsToLiteralValueMap( + literals: { + [k: string]: Core.ILiteral; + }, + types: Record, +): LiteralValueMap { const literalValueMap: LiteralValueMap = new Map(); if (literals) { for (var i = 0; i < Object.keys(literals).length; i++) { const name = Object.keys(literals)[i]; - const value = literals[name]; - let typeDefinition: InputTypeDefinition | undefined; - if (value?.scalar) { - typeDefinition = getInputDefintionForScalar(value.scalar); - } else if (value?.collection) { - typeDefinition = { - literalType: value.collection, - type: InputType.Collection, - } as InputTypeDefinition; - } + const type = types[name].type; + const typeDefinition = getInputDefintionForLiteralType(type); + if (typeDefinition) { const inputKey = createInputCacheKey(name, typeDefinition); literalValueMap.set(inputKey, literals[Object.keys(literals)[i]]); } } } - return literalValueMap; -} - -/** Converts a `Scalar` to an `InputTypeDefintion` to assist with rendering - * a type annotation and converting input values. - */ -export function getInputDefintionForScalar(scalar: Core.IScalar): InputTypeDefinition { - const result: InputTypeDefinition = { - literalType: scalar as LiteralType, - type: InputType.Unknown, - }; - - if (scalar.binary) { - result.type = InputType.Binary; - } else if (scalar.blob) { - result.type = InputType.Blob; - } else if (scalar.error) { - result.type = InputType.Error; - } else if (scalar.noneType) { - result.type = InputType.None; - } else if (scalar.primitive) { - if (scalar.primitive.stringValue) { - result.type = InputType.String; - } else if (scalar.primitive.floatValue) { - result.type = InputType.Float; - } else if (scalar.primitive.integer) { - result.type = InputType.Integer; - } else if (scalar.primitive.boolean) { - result.type = InputType.Boolean; - } - } - return result; + return literalValueMap; } From 4293e7e6b01eaf4f1e0ca4da652f2c022203059d Mon Sep 17 00:00:00 2001 From: Eugene Jahn Date: Thu, 26 May 2022 11:54:56 -0700 Subject: [PATCH 6/8] feat: small typo fixed Signed-off-by: Eugene Jahn --- .../console/src/components/Launch/LaunchForm/utils.ts | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/packages/zapp/console/src/components/Launch/LaunchForm/utils.ts b/packages/zapp/console/src/components/Launch/LaunchForm/utils.ts index 5c7f52aa0..ba1500275 100644 --- a/packages/zapp/console/src/components/Launch/LaunchForm/utils.ts +++ b/packages/zapp/console/src/components/Launch/LaunchForm/utils.ts @@ -196,19 +196,16 @@ export function literalsToLiteralValueMap( literals: { [k: string]: Core.ILiteral; }, - types: Record, + nameToTypeMap: Record, ): LiteralValueMap { const literalValueMap: LiteralValueMap = new Map(); if (literals) { for (var i = 0; i < Object.keys(literals).length; i++) { const name = Object.keys(literals)[i]; - const type = types[name].type; + const type = nameToTypeMap[name].type; const typeDefinition = getInputDefintionForLiteralType(type); - - if (typeDefinition) { - const inputKey = createInputCacheKey(name, typeDefinition); - literalValueMap.set(inputKey, literals[Object.keys(literals)[i]]); - } + const inputKey = createInputCacheKey(name, typeDefinition); + literalValueMap.set(inputKey, literals[Object.keys(literals)[i]]); } } From d86e0d13e8d76746b27f76635c7f592f3f609dbb Mon Sep 17 00:00:00 2001 From: Eugene Jahn Date: Thu, 26 May 2022 12:00:25 -0700 Subject: [PATCH 7/8] feat: small typo fixed Signed-off-by: Eugene Jahn --- .../src/components/Launch/LaunchForm/utils.ts | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/packages/zapp/console/src/components/Launch/LaunchForm/utils.ts b/packages/zapp/console/src/components/Launch/LaunchForm/utils.ts index ba1500275..fa59ec600 100644 --- a/packages/zapp/console/src/components/Launch/LaunchForm/utils.ts +++ b/packages/zapp/console/src/components/Launch/LaunchForm/utils.ts @@ -199,14 +199,13 @@ export function literalsToLiteralValueMap( nameToTypeMap: Record, ): LiteralValueMap { const literalValueMap: LiteralValueMap = new Map(); - if (literals) { - for (var i = 0; i < Object.keys(literals).length; i++) { - const name = Object.keys(literals)[i]; - const type = nameToTypeMap[name].type; - const typeDefinition = getInputDefintionForLiteralType(type); - const inputKey = createInputCacheKey(name, typeDefinition); - literalValueMap.set(inputKey, literals[Object.keys(literals)[i]]); - } + + for (var i = 0; i < Object.keys(literals).length; i++) { + const name = Object.keys(literals)[i]; + const type = nameToTypeMap[name].type; + const typeDefinition = getInputDefintionForLiteralType(type); + const inputKey = createInputCacheKey(name, typeDefinition); + literalValueMap.set(inputKey, literals[Object.keys(literals)[i]]); } return literalValueMap; From db02ef5666efaeffce406be1a37c59fbe837a7e9 Mon Sep 17 00:00:00 2001 From: Eugene Jahn Date: Thu, 26 May 2022 12:39:08 -0700 Subject: [PATCH 8/8] feat: fix test coverage Signed-off-by: Eugene Jahn --- .../ExecutionDetailsActions.tsx | 10 +++---- .../Tables/NodeExecutionActions.tsx | 26 +++++++++---------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/packages/zapp/console/src/components/Executions/ExecutionDetails/ExecutionDetailsActions.tsx b/packages/zapp/console/src/components/Executions/ExecutionDetails/ExecutionDetailsActions.tsx index 2f69277dc..e5251378f 100644 --- a/packages/zapp/console/src/components/Executions/ExecutionDetails/ExecutionDetailsActions.tsx +++ b/packages/zapp/console/src/components/Executions/ExecutionDetails/ExecutionDetailsActions.tsx @@ -28,18 +28,18 @@ export const ExecutionDetailsActions = (props: ExecutionDetailsActionsProps): JS const id = details.taskTemplate?.id as ResourceIdentifier | undefined; - if (!id) { - return <>; - } - React.useEffect(() => { const fetchTask = async () => { const task = await getTask(id as Identifier); setTaskInputsTypes(task.closure.compiledTask.template?.interface?.inputs?.variables); }; - fetchTask(); + if (id) fetchTask(); }, [id]); + if (!id) { + return <>; + } + const literals = executionData.value.fullInputs?.literals; const initialParameters: TaskInitialLaunchParameters = { diff --git a/packages/zapp/console/src/components/Executions/Tables/NodeExecutionActions.tsx b/packages/zapp/console/src/components/Executions/Tables/NodeExecutionActions.tsx index bcaf53058..62ef88c35 100644 --- a/packages/zapp/console/src/components/Executions/Tables/NodeExecutionActions.tsx +++ b/packages/zapp/console/src/components/Executions/Tables/NodeExecutionActions.tsx @@ -35,19 +35,6 @@ export const NodeExecutionActions = (props: NodeExecutionActionsProps): JSX.Elem const literals = executionData.value.fullInputs?.literals; const id = nodeExecutionDetails?.taskTemplate?.id as ResourceIdentifier; - // open the side panel for selected execution's detail - const inputsAndOutputsIconOnClick = (e: React.MouseEvent) => { - // prevent the parent row body onClick event trigger - e.stopPropagation(); - // use null in case if there is no execution provided - when it is null will close panel - state.setSelectedExecution(execution?.id ?? null); - }; - - const rerunIconOnClick = (e: React.MouseEvent) => { - e.stopPropagation(); - setShowLaunchForm(true); - }; - React.useEffect(() => { detailsContext.getNodeExecutionDetails(execution).then((res) => { setNodeExecutionDetails(res); @@ -62,6 +49,19 @@ export const NodeExecutionActions = (props: NodeExecutionActionsProps): JSX.Elem if (id) fetchTask(); }, [id]); + // open the side panel for selected execution's detail + const inputsAndOutputsIconOnClick = (e: React.MouseEvent) => { + // prevent the parent row body onClick event trigger + e.stopPropagation(); + // use null in case if there is no execution provided - when it is null will close panel + state.setSelectedExecution(execution?.id ?? null); + }; + + const rerunIconOnClick = (e: React.MouseEvent) => { + e.stopPropagation(); + setShowLaunchForm(true); + }; + const renderRerunAction = () => { if (!id) { return <>;