Skip to content

Commit

Permalink
feat(ui): Make URLs clickable in workflow node info (argoproj#13494)
Browse files Browse the repository at this point in the history
Signed-off-by: Adrien Delannoy <[email protected]>
  • Loading branch information
Adrien-D authored Oct 21, 2024
1 parent 8905a0e commit 6fa5365
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 4 deletions.
2 changes: 2 additions & 0 deletions ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"cronstrue": "^2.50.0",
"dagre": "^0.8.5",
"history": "^4.10.1",
"linkify-it": "^5.0.0",
"moment": "^2.30.1",
"monaco-editor": "^0.45.0",
"prop-types": "^15.8.1",
Expand All @@ -48,6 +49,7 @@
"@types/dagre": "^0.7.52",
"@types/history": "^4.6.2",
"@types/jest": "^26.0.15",
"@types/linkify-it": "^5.0.0",
"@types/prop-types": "^15.7.11",
"@types/react": "^16.8.5",
"@types/react-autocomplete": "^1.8.10",
Expand Down
37 changes: 37 additions & 0 deletions ui/src/app/shared/components/linkified-text.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import LinkifyIt from 'linkify-it';
import React from 'react';

interface Props {
text: string;
}

const linkify = new LinkifyIt();

export default function LinkifiedText({text}: Props) {
const matches = linkify.match(text);

if (!matches) {
return <>{text}</>;
}

const parts = [];
let lastIndex = 0;

matches.forEach(match => {
if (match.index > lastIndex) {
parts.push(<span key={`text-${lastIndex}`}>{text.slice(lastIndex, match.index)}</span>);
}
parts.push(
<a key={`link-${match.index}-${match.text}`} href={match.url} target='_blank' rel='noopener noreferrer' className='underline'>
{match.text}
</a>
);
lastIndex = match.lastIndex;
});

if (lastIndex < text.length) {
parts.push(<span key={'text-end'}>{text.slice(lastIndex)}</span>);
}

return <>{parts}</>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,17 @@ import {Button} from '../../../shared/components/button';
import {ClipboardText} from '../../../shared/components/clipboard-text';
import {DurationPanel} from '../../../shared/components/duration-panel';
import {InlineTable} from '../../../shared/components/inline-table/inline-table';
import LinkifiedText from '../../../shared/components/linkified-text';
import {Links} from '../../../shared/components/links';
import {Phase} from '../../../shared/components/phase';
import {Timestamp} from '../../../shared/components/timestamp';
import {getPodName} from '../../../shared/pod-name';
import {ResourcesDuration} from '../../../shared/resources-duration';
import {services} from '../../../shared/services';
import {getResolvedTemplates} from '../../../shared/template-resolution';
import {TIMESTAMP_KEYS} from '../../../shared/use-timestamp';

import './workflow-node-info.scss';
import {TIMESTAMP_KEYS} from '../../../shared/use-timestamp';

function nodeDuration(node: models.NodeStatus, now: moment.Moment) {
const endTime = node.finishedAt ? moment(node.finishedAt) : now;
Expand Down Expand Up @@ -70,13 +71,13 @@ interface Props {
onRetryNode?: () => void;
}

const AttributeRow = (attr: {title: string; value: any}) => (
const AttributeRow = (attr: {title: string; value: string | React.JSX.Element}) => (
<React.Fragment key={attr.title}>
<div>{attr.title}</div>
<div>{attr.value}</div>
<div>{typeof attr.value === 'string' ? <LinkifiedText text={attr.value} /> : attr.value}</div>
</React.Fragment>
);
const AttributeRows = (props: {attributes: {title: string; value: any}[]}) => (
const AttributeRows = (props: {attributes: {title: string; value: string | React.JSX.Element}[]}) => (
<div className='workflow-details__attribute-grid'>
{props.attributes.map(attr => (
<AttributeRow key={attr.title} {...attr} />
Expand Down
17 changes: 17 additions & 0 deletions ui/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2085,6 +2085,11 @@
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==

"@types/linkify-it@^5.0.0":
version "5.0.0"
resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-5.0.0.tgz#21413001973106cda1c3a9b91eedd4ccd5469d76"
integrity sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==

"@types/mdast@^3.0.0":
version "3.0.15"
resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.15.tgz#49c524a263f30ffa28b71ae282f813ed000ab9f5"
Expand Down Expand Up @@ -6514,6 +6519,13 @@ lines-and-columns@^1.1.6:
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==

linkify-it@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-5.0.0.tgz#9ef238bfa6dc70bd8e7f9572b52d369af569b421"
integrity sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==
dependencies:
uc.micro "^2.0.0"

loader-runner@^4.2.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1"
Expand Down Expand Up @@ -9712,6 +9724,11 @@ typescript@^4.6.4, typescript@^4.9.5:
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a"
integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==

uc.micro@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-2.1.0.tgz#f8d3f7d0ec4c3dea35a7e3c8efa4cb8b45c9e7ee"
integrity sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==

unbox-primitive@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e"
Expand Down

0 comments on commit 6fa5365

Please sign in to comment.