diff --git a/package.json b/package.json index 8c91395c6..dbce7d901 100644 --- a/package.json +++ b/package.json @@ -106,6 +106,7 @@ "prettier": "^2.8.3", "react": "^16.13.1", "react-dom": "^16.13.1", + "react-syntax-highlighter": "^15.5.0", "semantic-release": "^21.0.7", "serve-static": "^1.12.3", "source-map-loader": "^4.0.1", diff --git a/packages/console/src/components/Executions/ExecutionDetails/ExecutionNodeURL.tsx b/packages/console/src/components/Executions/ExecutionDetails/ExecutionNodeURL.tsx new file mode 100644 index 000000000..c0ac37bc0 --- /dev/null +++ b/packages/console/src/components/Executions/ExecutionDetails/ExecutionNodeURL.tsx @@ -0,0 +1,186 @@ +import * as React from 'react'; +import { Box, Button, SvgIconTypeMap, Typography } from '@material-ui/core'; +import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; +import { docco } from 'react-syntax-highlighter/dist/esm/styles/hljs/docco'; +import FileCopyIcon from '@material-ui/icons/FileCopy'; +import { DefaultComponentProps } from '@material-ui/core/OverridableComponent'; +import copyToClipboard from 'copy-to-clipboard'; +import { Theme, makeStyles } from '@material-ui/core/styles'; +import { Core } from '@flyteorg/flyteidl-types'; +import { + primaryHighlightColor, + separatorColor, + errorBackgroundColor, + listhoverColor, +} from 'components/Theme/constants'; +import classNames from 'classnames'; +import { RowExpander } from '../Tables/RowExpander'; + +const useStyles = makeStyles((theme: Theme) => ({ + container: { + marginLeft: '-10px', + }, + codeWrapper: { + overflow: 'hidden', + border: `1px solid ${separatorColor}`, + borderRadius: 4, + marginLeft: '16px', + }, + + hoverWrapper: { + position: 'relative', + + '& .textButton': { + color: theme.palette.primary.main, + border: 'none', + right: '2px', + top: 0, + }, + + '& .copyButton': { + backgroundColor: theme.palette.common.white, + border: `1px solid ${primaryHighlightColor}`, + borderRadius: theme.spacing(1), + color: theme.palette.text.secondary, + height: theme.spacing(4), + minWidth: 0, + padding: 0, + position: 'absolute', + right: theme.spacing(2), + top: theme.spacing(1), + width: theme.spacing(4), + display: 'none', + + '&:hover': { + backgroundColor: listhoverColor, + }, + }, + '&:hover': { + '& .copyButton': { + display: 'flex', + }, + }, + + '& pre': { + margin: '0 !important', + }, + }, +})); + +const CopyButton: React.FC< + DefaultComponentProps> & { + onCopyClick: React.MouseEventHandler; + buttonVariant?: 'text' | 'button'; + } +> = ({ onCopyClick, buttonVariant, children, ...props }) => { + return ( + + ); +}; + +/** Fetches and renders the deck data for a given `nodeExecutionId` */ +export const ExecutionNodeURL: React.FC<{ + nodeExecutionId: Core.NodeExecutionIdentifier; + dataSourceURI: string; + copyUrlText: string; +}> = ({ nodeExecutionId, dataSourceURI, copyUrlText }) => { + const styles = useStyles(); + const [expanded, setExpanded] = React.useState(false); + + const project = nodeExecutionId.executionId?.project; + const domain = nodeExecutionId.executionId?.domain; + + const code = `from flytekit.remote.remote import FlyteRemote +from flytekit.configuration import Config +remote = FlyteRemote( + Config.for_endpoint(endpoint="${window.location.host}"), + default_project="${project}", + default_domain="${domain}" +) +remote.get("${dataSourceURI}")`; + + const toggleExpanded = () => { + setExpanded(!expanded); + }; + + return ( + + + { + event.preventDefault(); + + copyToClipboard(dataSourceURI); + }} + > + + {copyUrlText} + + + + + + + FlyteRemote Usage + + + + + + {code} + + + { + event.preventDefault(); + + copyToClipboard(code); + }} + /> + + + + ); +}; diff --git a/packages/console/src/components/Executions/ExecutionDetails/NodeExecutionDetailsPanelContent.tsx b/packages/console/src/components/Executions/ExecutionDetails/NodeExecutionDetailsPanelContent.tsx index a5e42bf49..9cb04ef71 100644 --- a/packages/console/src/components/Executions/ExecutionDetails/NodeExecutionDetailsPanelContent.tsx +++ b/packages/console/src/components/Executions/ExecutionDetails/NodeExecutionDetailsPanelContent.tsx @@ -412,33 +412,16 @@ export const NodeExecutionDetailsPanelContent: React.FC< return computedPhase; }, [nodeExecution, isGateNode]); - const isRunningPhase = useMemo( - () => - frontendPhase === NodeExecutionPhase.QUEUED || - frontendPhase === NodeExecutionPhase.RUNNING, - [frontendPhase], - ); - - const handleReasonsVisibility = () => { - setReasonsVisible(!isReasonsVisible); - }; - const statusContent = nodeExecution ? (
- {isRunningPhase && ( - - )}
- {isRunningPhase && isReasonsVisible && ( + {reasons?.length ? (
- )} + ) : null}
) : (
NOT RUN
diff --git a/packages/console/src/components/Executions/ExecutionDetails/NodeExecutionTabs/NodeExecutionInputs.tsx b/packages/console/src/components/Executions/ExecutionDetails/NodeExecutionTabs/NodeExecutionInputs.tsx index 02c92329f..07b3025c2 100644 --- a/packages/console/src/components/Executions/ExecutionDetails/NodeExecutionTabs/NodeExecutionInputs.tsx +++ b/packages/console/src/components/Executions/ExecutionDetails/NodeExecutionTabs/NodeExecutionInputs.tsx @@ -4,6 +4,7 @@ import { useNodeExecutionData } from 'components/hooks/useNodeExecution'; import { LiteralMapViewer } from 'components/Literals/LiteralMapViewer'; import { NodeExecution } from 'models/Execution/types'; import * as React from 'react'; +import { ExecutionNodeURL } from '../ExecutionNodeURL'; /** Fetches and renders the input data for a given `NodeExecution` */ export const NodeExecutionInputs: React.FC<{ @@ -11,9 +12,17 @@ export const NodeExecutionInputs: React.FC<{ taskIndex?: number; }> = ({ execution, taskIndex }) => { const executionData = useNodeExecutionData(execution.id); + return ( + {executionData.value?.flyteUrls?.inputs ? ( + + ) : null} = ({ execution, taskIndex }) => { const executionData = useNodeExecutionData(execution.id); + return ( + {executionData.value?.flyteUrls?.outputs ? ( + + ) : null} !!r); - - if (finalReasons) { + if ( + finalReasons && + finalReasons.some(eachReason => eachReason?.message?.trim() !== '') + ) { reasons = reasons.concat( finalReasons.map( reason => (reason.occurredAt - ? formatDateUTC(timestampToDate(reason.occurredAt)) + ' ' + ? `${formatDateUTC(timestampToDate(reason.occurredAt))} ` : '') + reason.message, ), ); diff --git a/packages/console/src/models/Execution/types.ts b/packages/console/src/models/Execution/types.ts index ddc691838..611dc6fce 100644 --- a/packages/console/src/models/Execution/types.ts +++ b/packages/console/src/models/Execution/types.ts @@ -149,4 +149,8 @@ export interface ExecutionData { fullOutputs: LiteralMap | null; deckUri?: string; dynamicWorkflow?: CompiledWorkflow; + flyteUrls?: { + inputs?: string; + outputs?: string; + }; } diff --git a/packages/flyteidl-types/package.json b/packages/flyteidl-types/package.json index 11c034c60..d842d690c 100644 --- a/packages/flyteidl-types/package.json +++ b/packages/flyteidl-types/package.json @@ -46,6 +46,6 @@ "protobufjs": "~6.11.3" }, "dependencies": { - "@flyteorg/flyteidl": "1.3.18" + "@flyteorg/flyteidl": "^1.5.21" } } diff --git a/yarn.lock b/yarn.lock index bd8c9ef3c..d5b908d51 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2179,16 +2179,16 @@ __metadata: version: 0.0.0-use.local resolution: "@flyteorg/flyteidl-types@workspace:packages/flyteidl-types" dependencies: - "@flyteorg/flyteidl": 1.3.18 + "@flyteorg/flyteidl": ^1.5.21 peerDependencies: protobufjs: ~6.11.3 languageName: unknown linkType: soft -"@flyteorg/flyteidl@npm:1.3.18": - version: 1.3.18 - resolution: "@flyteorg/flyteidl@npm:1.3.18" - checksum: f0c16a8f0eb3f1ab79ca9e4c1c871bf5a8c848a81d021bd3ec9d4daf7869e99d09f94a2feb266da0e2b7694c9d97a9386604df630b9fe5a76ba0c15a00099a6f +"@flyteorg/flyteidl@npm:^1.5.21": + version: 1.5.21 + resolution: "@flyteorg/flyteidl@npm:1.5.21" + checksum: 803520a3d9571c460d29c47ec5e59bd34eff3b460827eaa6fda7f360839e7445b53af07edecacc911e8010b04936d4b089bb65e7194d9d6855b520f847275abb languageName: node linkType: hard @@ -12070,6 +12070,15 @@ __metadata: languageName: node linkType: hard +"fault@npm:^1.0.0": + version: 1.0.4 + resolution: "fault@npm:1.0.4" + dependencies: + format: ^0.2.0 + checksum: 5ac610d8b09424e0f2fa8cf913064372f2ee7140a203a79957f73ed557c0e79b1a3d096064d7f40bde8132a69204c1fe25ec23634c05c6da2da2039cff26c4e7 + languageName: node + linkType: hard + "faye-websocket@npm:^0.11.3": version: 0.11.4 resolution: "faye-websocket@npm:0.11.4" @@ -12477,6 +12486,7 @@ __metadata: prettier: ^2.8.3 react: ^16.13.1 react-dom: ^16.13.1 + react-syntax-highlighter: ^15.5.0 semantic-release: ^21.0.7 serve-static: ^1.12.3 source-map-loader: ^4.0.1 @@ -12647,6 +12657,13 @@ __metadata: languageName: node linkType: hard +"format@npm:^0.2.0": + version: 0.2.2 + resolution: "format@npm:0.2.2" + checksum: 646a60e1336250d802509cf24fb801e43bd4a70a07510c816fa133aa42cdbc9c21e66e9cc0801bb183c5b031c9d68be62e7fbb6877756e52357850f92aa28799 + languageName: node + linkType: hard + "forwarded@npm:0.2.0": version: 0.2.0 resolution: "forwarded@npm:0.2.0" @@ -13507,6 +13524,13 @@ __metadata: languageName: node linkType: hard +"highlight.js@npm:^10.4.1, highlight.js@npm:~10.7.0": + version: 10.7.3 + resolution: "highlight.js@npm:10.7.3" + checksum: defeafcd546b535d710d8efb8e650af9e3b369ef53e28c3dc7893eacfe263200bba4c5fcf43524ae66d5c0c296b1af0870523ceae3e3104d24b7abf6374a4fea + languageName: node + linkType: hard + "history@npm:^4.9.0": version: 4.10.1 resolution: "history@npm:4.10.1" @@ -16544,6 +16568,16 @@ __metadata: languageName: node linkType: hard +"lowlight@npm:^1.17.0": + version: 1.20.0 + resolution: "lowlight@npm:1.20.0" + dependencies: + fault: ^1.0.0 + highlight.js: ~10.7.0 + checksum: 14a1815d6bae202ddee313fc60f06d46e5235c02fa483a77950b401d85b4c1e12290145ccd17a716b07f9328bd5864aa2d402b6a819ff3be7c833d9748ff8ba7 + languageName: node + linkType: hard + "lru-cache@npm:^5.1.1": version: 5.1.1 resolution: "lru-cache@npm:5.1.1" @@ -19439,6 +19473,20 @@ __metadata: languageName: node linkType: hard +"prismjs@npm:^1.27.0": + version: 1.29.0 + resolution: "prismjs@npm:1.29.0" + checksum: 007a8869d4456ff8049dc59404e32d5666a07d99c3b0e30a18bd3b7676dfa07d1daae9d0f407f20983865fd8da56de91d09cb08e6aa61f5bc420a27c0beeaf93 + languageName: node + linkType: hard + +"prismjs@npm:~1.27.0": + version: 1.27.0 + resolution: "prismjs@npm:1.27.0" + checksum: 85c7f4a3e999073502cc9e1882af01e3709706369ec254b60bff1149eda701f40d02512acab956012dc7e61cfd61743a3a34c1bd0737e8dbacd79141e5698bbc + languageName: node + linkType: hard + "proc-log@npm:^3.0.0": version: 3.0.0 resolution: "proc-log@npm:3.0.0" @@ -20162,6 +20210,21 @@ __metadata: languageName: node linkType: hard +"react-syntax-highlighter@npm:^15.5.0": + version: 15.5.0 + resolution: "react-syntax-highlighter@npm:15.5.0" + dependencies: + "@babel/runtime": ^7.3.1 + highlight.js: ^10.4.1 + lowlight: ^1.17.0 + prismjs: ^1.27.0 + refractor: ^3.6.0 + peerDependencies: + react: ">= 0.14.0" + checksum: c082b48f30f8ba8d0c55ed1d761910630860077c7ff5793c4c912adcb5760df06436ed0ad62be0de28113aac9ad2af55eccd995f8eee98df53382e4ced2072fb + languageName: node + linkType: hard + "react-textarea-autosize@npm:^8.3.2": version: 8.5.2 resolution: "react-textarea-autosize@npm:8.5.2" @@ -20432,6 +20495,17 @@ __metadata: languageName: node linkType: hard +"refractor@npm:^3.6.0": + version: 3.6.0 + resolution: "refractor@npm:3.6.0" + dependencies: + hastscript: ^6.0.0 + parse-entities: ^2.0.0 + prismjs: ~1.27.0 + checksum: 39b01c4168c77c5c8486f9bf8907bbb05f257f15026057ba5728535815a2d90eed620468a4bfbb2b8ceefbb3ce3931a1be8b17152dbdbc8b0eef92450ff750a2 + languageName: node + linkType: hard + "regenerate-unicode-properties@npm:^10.1.0": version: 10.1.0 resolution: "regenerate-unicode-properties@npm:10.1.0"