diff --git a/ui/src/app/shared/components/linkified-text.tsx b/ui/src/app/shared/components/linkified-text.tsx
new file mode 100644
index 000000000000..233bbd6ba5a7
--- /dev/null
+++ b/ui/src/app/shared/components/linkified-text.tsx
@@ -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({text.slice(lastIndex, match.index)});
+ }
+ parts.push(
+
+ {match.text}
+
+ );
+ lastIndex = match.lastIndex;
+ });
+
+ if (lastIndex < text.length) {
+ parts.push({text.slice(lastIndex)});
+ }
+
+ return <>{parts}>;
+}
diff --git a/ui/src/app/workflows/components/workflow-node-info/workflow-node-info.tsx b/ui/src/app/workflows/components/workflow-node-info/workflow-node-info.tsx
index 3622b4e460da..b9525d56c382 100644
--- a/ui/src/app/workflows/components/workflow-node-info/workflow-node-info.tsx
+++ b/ui/src/app/workflows/components/workflow-node-info/workflow-node-info.tsx
@@ -5,7 +5,6 @@ import {Tooltip} from 'argo-ui/src/components/tooltip/tooltip';
import moment from 'moment';
import * as React from 'react';
import {useState} from 'react';
-import LinkifyIt from 'linkify-it';
import * as models from '../../../../models';
import {Artifact, NodeStatus, Workflow} from '../../../../models';
@@ -22,6 +21,7 @@ import {services} from '../../../shared/services';
import {getResolvedTemplates} from '../../../shared/template-resolution';
import './workflow-node-info.scss';
+import LinkifiedText from '../../../shared/components/linkified-text';
function nodeDuration(node: models.NodeStatus, now: moment.Moment) {
const endTime = node.finishedAt ? moment(node.finishedAt) : now;
@@ -69,43 +69,13 @@ interface Props {
onResume?: () => void;
}
-const linkify = new LinkifyIt();
-
-function linkifyText(text: string) {
- const matches = linkify.match(text);
- if (!matches) {
- return text;
- }
-
- const parts = [];
- let lastIndex = 0;
-
- matches.forEach(match => {
- if (match.index > lastIndex) {
- parts.push({text.slice(lastIndex, match.index)});
- }
- parts.push(
-
- {match.text}
-
- );
- lastIndex = match.lastIndex;
- });
-
- if (lastIndex < text.length) {
- parts.push({text.slice(lastIndex)});
- }
-
- return parts;
-}
-
-const AttributeRow = (attr: {title: string; value: any}) => (
+const AttributeRow = (attr: {title: string; value: string | React.JSX.Element}) => (