Skip to content

Commit

Permalink
fix(ui): improve markdown styles for workflow-row, workflow-templates…
Browse files Browse the repository at this point in the history
…, cluster-workflow-templates, and cron-workflows (argoproj#13930)

Signed-off-by: stevenbjohnson <[email protected]>
  • Loading branch information
stevenbjohnson authored Dec 10, 2024
1 parent b8c54ad commit 231d548
Show file tree
Hide file tree
Showing 22 changed files with 182 additions and 48 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/assets/title-and-description-markdown-complex-workflow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/assets/title-and-description-markdown-cron-workflow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/assets/title-and-description-markdown-workflow-template.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
39 changes: 21 additions & 18 deletions docs/title-and-description.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,7 @@ metadata:
annotations:
workflows.argoproj.io/description: '`SuperDuperProject` PR #6529: Implement frobbing (aff39ee)'

# 5. markdown title, multi-line markdown description with URL converted into an anchor link
metadata:
annotations:
workflows.argoproj.io/title: '**Test Title**'
workflows.argoproj.io/description: |
`This is a simple hello world example.`
You can also run it in Python: https://couler-proj.github.io/couler/examples/#hello-world
# 6. markdown title, markdown description with a markdown link
# 5. markdown title, markdown description with a markdown link
metadata:
annotations:
workflows.argoproj.io/title: '**Build and test**'
Expand All @@ -78,6 +70,23 @@ metadata:
The above examples will render as rows like the below image:
![More Markdown Examples](assets/title-and-description-markdown-complex-workflow.png)
The `title` and `description` annotations also support multi-line values. Longer values will be truncated in the workflow list view, but can be seen in the `DESCRIPTION` section when the workflow row is expanded to display the workflow drawer.

Below is an example:

```yaml
# markdown title, multi-line markdown description with URL converted into an anchor link
metadata:
annotations:
workflows.argoproj.io/title: '**Test Title**'
workflows.argoproj.io/description: |
`This is a simple hello world example.`
You can also run it in Python: https://couler-proj.github.io/couler/examples/#hello-world
```
The above example will render an expanded row like the below image:
![Workflow Drawer Markdown Examples](assets/title-and-description-markdown-workflow-drawer.png)
### For `ClusterWorkflowTemplates`

> v3.7 and after
Expand All @@ -91,9 +100,7 @@ metadata:
name: my-cluster-workflow-template
annotations:
workflows.argoproj.io/title: '**Test Title**'
workflows.argoproj.io/description: |
`This is a simple hello world example.`
You can also run it in Python: https://couler-proj.github.io/couler/examples/#hello-world
workflows.argoproj.io/description: `This is a simple hello world example.`
```

The above manifest will render as a row like the below image:
Expand All @@ -112,9 +119,7 @@ metadata:
name: my-cron-workflow
annotations:
workflows.argoproj.io/title: '**Test Title**'
workflows.argoproj.io/description: |
`This is a simple hello world example.`
You can also run it in Python: https://couler-proj.github.io/couler/examples/#hello-world
workflows.argoproj.io/description: `This is a simple hello world example.`
```
The above manifest will render as a row like the below image:
Expand All @@ -133,9 +138,7 @@ metadata:
name: my-workflow-template
annotations:
workflows.argoproj.io/title: '**Test Title**'
workflows.argoproj.io/description: |
`This is a simple hello world example.`
You can also run it in Python: https://couler-proj.github.io/couler/examples/#hello-world
workflows.argoproj.io/description: `This is a simple hello world example.`
```

The above manifest will render as a row like the below image:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
color: $argo-color-teal-5;
}
}

.row {
min-width: 0;
}
}

.row.pt-60 {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
@import 'node_modules/argo-ui/src/styles/config';

.wf-rows-name {
line-height: 1.5em;
display: inline-block;
vertical-align: middle;
line-height: 2.5em;
white-space: pre-line;
text-wrap: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding: 0.25em 0;

& > * {
overflow: hidden;
text-overflow: ellipsis;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import * as React from 'react';
import {ANNOTATION_DESCRIPTION, ANNOTATION_TITLE} from '../shared/annotations';
import {SuspenseReactMarkdownGfm} from '../shared/components/suspense-react-markdown-gfm';
import {ClusterWorkflowTemplate} from '../shared/models';
import {escapeInvalidMarkdown} from '../workflows/utils';

require('./cluster-workflow-template-markdown.scss');

Expand All @@ -13,10 +14,13 @@ interface ClusterWorkflowTemplateMarkdownProps {
export function ClusterWorkflowTemplateMarkdown(props: ClusterWorkflowTemplateMarkdownProps) {
const wf = props.workflow;
// title + description vars
const title = wf.metadata.annotations?.[ANNOTATION_TITLE] ?? wf.metadata.name;
const description = (wf.metadata.annotations?.[ANNOTATION_DESCRIPTION] && `\n${wf.metadata.annotations[ANNOTATION_DESCRIPTION]}`) || '';
const hasAnnotation = title !== wf.metadata.name || description !== '';
const title = (wf.metadata.annotations?.[ANNOTATION_TITLE] && `${escapeInvalidMarkdown(wf.metadata.annotations[ANNOTATION_TITLE])}`) ?? wf.metadata.name;
const description = (wf.metadata.annotations?.[ANNOTATION_DESCRIPTION] && `\n${escapeInvalidMarkdown(wf.metadata.annotations[ANNOTATION_DESCRIPTION])}`) || '';
const markdown = `${title}${description}`;

return <div className='wf-rows-name'>{hasAnnotation ? <SuspenseReactMarkdownGfm markdown={markdown} /> : markdown}</div>;
return (
<div className={description.length ? 'wf-rows-name' : ''} aria-valuetext={markdown}>
<SuspenseReactMarkdownGfm markdown={markdown} />
</div>
);
}
4 changes: 4 additions & 0 deletions ui/src/cron-workflows/cron-workflow-list.scss
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
color: $argo-color-teal-5;
}
}

.row {
min-width: 0;
}
}

.row.pt-60 {
Expand Down
13 changes: 10 additions & 3 deletions ui/src/cron-workflows/cron-workflow-row.scss
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
@import 'node_modules/argo-ui/src/styles/config';

.wf-rows-name {
line-height: 1.5em;
display: inline-block;
vertical-align: middle;
line-height: 2.5em;
white-space: pre-line;
text-wrap: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding: 0.25em 0;

& > * {
overflow: hidden;
text-overflow: ellipsis;
}
}
10 changes: 6 additions & 4 deletions ui/src/cron-workflows/cron-workflow-row.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {SuspenseReactMarkdownGfm} from '../shared/components/suspense-react-mark
import {Timestamp} from '../shared/components/timestamp';
import {getNextScheduledTime} from '../shared/cron';
import {CronWorkflow, CronWorkflowSpec} from '../shared/models';
import {escapeInvalidMarkdown} from '../workflows/utils';
import {PrettySchedule} from './pretty-schedule';

require('./cron-workflow-row.scss');
Expand All @@ -21,17 +22,18 @@ interface CronWorkflowRowProps {
export function CronWorkflowRow(props: CronWorkflowRowProps) {
const wf = props.workflow;
// title + description vars
const title = wf.metadata.annotations?.[ANNOTATION_TITLE] ?? wf.metadata.name;
const description = (wf.metadata.annotations?.[ANNOTATION_DESCRIPTION] && `\n${wf.metadata.annotations[ANNOTATION_DESCRIPTION]}`) || '';
const hasAnnotation = title !== wf.metadata.name || description !== '';
const title = (wf.metadata.annotations?.[ANNOTATION_TITLE] && `${escapeInvalidMarkdown(wf.metadata.annotations[ANNOTATION_TITLE])}`) ?? wf.metadata.name;
const description = (wf.metadata.annotations?.[ANNOTATION_DESCRIPTION] && `\n${escapeInvalidMarkdown(wf.metadata.annotations[ANNOTATION_DESCRIPTION])}`) || '';
const markdown = `${title}${description}`;

return (
<div className='cron-workflows-list__row-container'>
<div className='row argo-table-list__row'>
<div className='columns small-1'>{wf.spec.suspend ? <i className='fa fa-pause' /> : <i className='fa fa-clock' />}</div>
<Link to={{pathname: uiUrl(`cron-workflows/${wf.metadata.namespace}/${wf.metadata.name}`)}} className='columns small-2'>
<div className='wf-rows-name'>{hasAnnotation ? <SuspenseReactMarkdownGfm markdown={markdown} /> : markdown}</div>
<div className={description.length ? 'wf-rows-name' : ''} aria-valuetext={markdown}>
<SuspenseReactMarkdownGfm markdown={markdown} />
</div>
</Link>
<div className='columns small-2'>{wf.metadata.namespace}</div>
<div className='columns small-1'>{wf.spec.timezone}</div>
Expand Down
18 changes: 18 additions & 0 deletions ui/src/shared/components/workflows-utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {escapeInvalidMarkdown} from '../../workflows/utils';

describe('escapeInvalidMarkdown', () => {
it('escapes markdown', () => {
expect(escapeInvalidMarkdown('**bold**')).toBe('**bold**');
expect(escapeInvalidMarkdown('_italic_')).toBe('_italic_');
expect(escapeInvalidMarkdown('~strikethrough~')).toBe('~strikethrough~');
expect(escapeInvalidMarkdown('`code`')).toBe('`code`');
expect(escapeInvalidMarkdown('[argo](https://github.com/argoproj/argo-workflows')).toBe('[argo](https://github.com/argoproj/argo-workflows');
expect(escapeInvalidMarkdown('__underline__')).toBe('__underline__');
expect(escapeInvalidMarkdown('```code block```')).toBe('code block');
expect(escapeInvalidMarkdown('> quote')).toBe('quote');
expect(escapeInvalidMarkdown('# header')).toBe('header');
expect(escapeInvalidMarkdown('-# subheader')).toBe('subheader');
expect(escapeInvalidMarkdown('\nthis\nis\ntext\nwith\nline\nbreaks\n')).toBe('this is text with line breaks');
expect(escapeInvalidMarkdown('- list item\n* list item\n1. list item')).toBe('\\- list item \\* list item 1\\. list item');
});
});
4 changes: 4 additions & 0 deletions ui/src/workflow-templates/workflow-template-list.scss
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
color: $argo-color-teal-5;
}
}

.row {
min-width: 0;
}
}

.row.pt-60 {
Expand Down
13 changes: 10 additions & 3 deletions ui/src/workflow-templates/workflow-template-row.scss
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
@import 'node_modules/argo-ui/src/styles/config';

.wf-rows-name {
line-height: 1.5em;
display: inline-block;
vertical-align: middle;
line-height: 2.5em;
white-space: pre-line;
text-wrap: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding: 0.25em 0;

& > * {
overflow: hidden;
text-overflow: ellipsis;
}
}
10 changes: 6 additions & 4 deletions ui/src/workflow-templates/workflow-template-row.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {uiUrl} from '../shared/base';
import {SuspenseReactMarkdownGfm} from '../shared/components/suspense-react-markdown-gfm';
import {Timestamp} from '../shared/components/timestamp';
import {WorkflowTemplate} from '../shared/models';
import {escapeInvalidMarkdown} from '../workflows/utils';

require('./workflow-template-row.scss');

Expand All @@ -17,9 +18,8 @@ interface WorkflowTemplateRowProps {
export function WorkflowTemplateRow(props: WorkflowTemplateRowProps) {
const wf = props.workflow;
// title + description vars
const title = wf.metadata.annotations?.[ANNOTATION_TITLE] ?? wf.metadata.name;
const description = (wf.metadata.annotations?.[ANNOTATION_DESCRIPTION] && `\n${wf.metadata.annotations[ANNOTATION_DESCRIPTION]}`) || '';
const hasAnnotation = title !== wf.metadata.name || description !== '';
const title = (wf.metadata.annotations?.[ANNOTATION_TITLE] && `${escapeInvalidMarkdown(wf.metadata.annotations[ANNOTATION_TITLE])}`) ?? wf.metadata.name;
const description = (wf.metadata.annotations?.[ANNOTATION_DESCRIPTION] && `\n${escapeInvalidMarkdown(wf.metadata.annotations[ANNOTATION_DESCRIPTION])}`) || '';
const markdown = `${title}${description}`;

return (
Expand All @@ -29,7 +29,9 @@ export function WorkflowTemplateRow(props: WorkflowTemplateRowProps) {
<i className='fa fa-clone' />
</div>
<Link to={{pathname: uiUrl(`workflow-templates/${wf.metadata.namespace}/${wf.metadata.name}`)}} className='columns small-5'>
<div className='wf-rows-name'>{hasAnnotation ? <SuspenseReactMarkdownGfm markdown={markdown} /> : markdown}</div>
<div className={description.length ? 'wf-rows-name' : ''} aria-valuetext={markdown}>
<SuspenseReactMarkdownGfm markdown={markdown} />
</div>
</Link>
<div className='columns small-3'>{wf.metadata.namespace}</div>
<div className='columns small-3'>
Expand Down
20 changes: 20 additions & 0 deletions ui/src/workflows/components/workflow-drawer/workflow-drawer.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
.workflow-drawer {
font-size: 13px;
background-color: $argo-color-gray-1;
margin: 0 15px;
padding: 1.5em 15px;
border-radius: 0 0 3px 3px;
line-height: 30px;
Expand Down Expand Up @@ -84,6 +85,25 @@
}
}

&__description {
margin-top: 16px;
max-width: 75%;
white-space: pre-line;

&--content {
blockquote {
line-height: normal;
padding: 0.25rem 1rem 0 1.25rem;
margin: 0;
}

ul, ol {
line-height: normal;
margin: 0 0 -1.5rem 1.25rem;
}
}
}

&__resourcesDuration {
&--value {
font-weight: 600;
Expand Down
15 changes: 15 additions & 0 deletions ui/src/workflows/components/workflow-drawer/workflow-drawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {useEffect, useState} from 'react';

import {InlineTable} from '../../../shared/components/inline-table/inline-table';
import {Loading} from '../../../shared/components/loading';
import {SuspenseReactMarkdownGfm} from '../../../shared/components/suspense-react-markdown-gfm';
import {ConditionsPanel} from '../../../shared/conditions-panel';
import {formatDuration} from '../../../shared/duration';
import {Workflow} from '../../../shared/models';
Expand All @@ -14,8 +15,11 @@ import {WorkflowLabels} from '../workflow-labels/workflow-labels';
import './workflow-drawer.scss';

interface WorkflowDrawerProps {
description: string;
hasAnnotation: boolean;
name: string;
namespace: string;
title: string;
onChange: (key: string) => void;
}

Expand Down Expand Up @@ -44,6 +48,17 @@ export function WorkflowDrawer(props: WorkflowDrawerProps) {
<div className='workflow-drawer__section'>
<div className='workflow-drawer__title'>NAME</div>
<div className='workflow-drawer__labels'>{wf.metadata.name}</div>
{!props.hasAnnotation ? null : (
<div className='workflow-drawer__section'>
<div className='workflow-drawer__title'>DESCRIPTION</div>
<div className='workflow-drawer__description'>
<SuspenseReactMarkdownGfm markdown={props.title} aria-valuetext={props.title} />
<div className='workflow-drawer__description--content'>
<SuspenseReactMarkdownGfm markdown={props.description} aria-valuetext={props.description} />
</div>
</div>
</div>
)}
</div>
{!wf.status || !wf.status.conditions ? null : (
<div className='workflow-drawer__section'>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
a:hover {
color: $argo-color-teal-5;
}

.row {
min-width: 0;
}
}

&__status {
Expand Down
13 changes: 10 additions & 3 deletions ui/src/workflows/components/workflows-row/workflows-row.scss
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
@import 'node_modules/argo-ui/src/styles/config';

.wf-rows-name {
line-height: 1.5em;
display: inline-block;
vertical-align: middle;
line-height: 2.5em;
white-space: pre-line;
text-wrap: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding: 0.25em 0;

& > * {
overflow: hidden;
text-overflow: ellipsis;
}
}
Loading

0 comments on commit 231d548

Please sign in to comment.