From cd6a765683322bb82e3d6a4fb730ad78e0930422 Mon Sep 17 00:00:00 2001 From: Adrien Delannoy Date: Mon, 26 Aug 2024 19:48:10 +0200 Subject: [PATCH] feat: make Linkify component reusable Signed-off-by: Adrien Delannoy --- .../app/shared/components/linkified-text.tsx | 37 ++++++++++++++++++ .../workflow-node-info/workflow-node-info.tsx | 38 ++----------------- 2 files changed, 41 insertions(+), 34 deletions(-) create mode 100644 ui/src/app/shared/components/linkified-text.tsx 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}) => (
{attr.title}
-
{linkifyText(attr.value)}
+
{typeof attr.value === 'string' ? : attr.value}
); -const AttributeRows = (props: {attributes: {title: string; value: any}[]}) => ( +const AttributeRows = (props: {attributes: {title: string; value: string | React.JSX.Element}[]}) => (
{props.attributes.map(attr => (