Skip to content

Commit

Permalink
feat: make Linkify component reusable
Browse files Browse the repository at this point in the history
Signed-off-by: Adrien Delannoy <[email protected]>
  • Loading branch information
Adrien-D committed Oct 18, 2024
1 parent 35aea63 commit 511acae
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 35 deletions.
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 @@ -5,24 +5,24 @@ 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';
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 @@ -71,43 +71,13 @@ interface Props {
onRetryNode?: () => 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(<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;
}

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>{linkifyText(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

0 comments on commit 511acae

Please sign in to comment.