diff --git a/ui/src/app/shared/components/error-panel.tsx b/ui/src/app/shared/components/error-panel.tsx
index d1cb2f62db5f..b03e44f3234d 100644
--- a/ui/src/app/shared/components/error-panel.tsx
+++ b/ui/src/app/shared/components/error-panel.tsx
@@ -6,46 +6,40 @@ interface Props {
errorInfo?: ErrorInfo;
}
-export class ErrorPanel extends React.Component {
- constructor(props: Props) {
- super(props);
- }
-
- public render() {
- return (
-
-
- {this.props.error.message}
-
-
- Reload this page to try again.
-
- {this.props.error.response && (
- <>
- {this.props.error.response.req && (
- <>
-
Request
-
- {this.props.error.response.req.method} {this.props.error.response.req.url}
-
- >
- )}
+export function ErrorPanel(props: Props) {
+ return (
+
+
+ {props.error.message}
+
+
+ Reload this page to try again.
+
+ {props.error.response && (
+ <>
+ {props.error.response.req && (
<>
-
Response
-
HTTP {this.props.error.response.status}
- {this.props.error.response.body &&
{JSON.stringify(this.props.error.response.body, null, 2)}
}
+
Request
+
+ {props.error.response.req.method} {props.error.response.req.url}
+
>
- >
- )}
-
Stack Trace
-
{this.props.error.stack}
- {this.props.errorInfo && (
+ )}
<>
-
Component Stack
-
{this.props.errorInfo.componentStack}
+
Response
+
HTTP {props.error.response.status}
+ {props.error.response.body &&
{JSON.stringify(props.error.response.body, null, 2)}
}
>
- )}
-
- );
- }
+ >
+ )}
+
Stack Trace
+
{props.error.stack}
+ {props.errorInfo && (
+ <>
+
Component Stack
+
{props.errorInfo.componentStack}
+ >
+ )}
+
+ );
}
diff --git a/ui/src/app/shared/components/inline-table/inline-table.tsx b/ui/src/app/shared/components/inline-table/inline-table.tsx
index be075827d453..b0da9340faa4 100644
--- a/ui/src/app/shared/components/inline-table/inline-table.tsx
+++ b/ui/src/app/shared/components/inline-table/inline-table.tsx
@@ -11,19 +11,17 @@ interface Row {
right: ReactChild;
}
-export class InlineTable extends React.Component {
- public render() {
- return (
-
- {this.props.rows.map((row, i) => {
- return (
-
-
{row.left}
-
{row.right}
-
- );
- })}
-
- );
- }
+export function InlineTable(props: TableProps) {
+ return (
+
+ {props.rows.map((row, i) => {
+ return (
+
+
{row.left}
+
{row.right}
+
+ );
+ })}
+
+ );
}
diff --git a/ui/src/app/shared/components/nudge.tsx b/ui/src/app/shared/components/nudge.tsx
index c40be0800e40..9ae47df31314 100644
--- a/ui/src/app/shared/components/nudge.tsx
+++ b/ui/src/app/shared/components/nudge.tsx
@@ -1,29 +1,24 @@
import * as React from 'react';
+import {useState} from 'react';
import {Notice} from './notice';
-export class Nudge extends React.Component<{key: string}, {closed: boolean}> {
- constructor(props: Readonly<{key: string}>) {
- super(props);
- this.state = {closed: localStorage.getItem(props.key) !== null};
+export function Nudge(props: React.PropsWithChildren<{key: string}>) {
+ const [closed, setClosed] = useState(localStorage.getItem(props.key) !== null);
+ function close() {
+ setClosed(true);
+ localStorage.setItem(props.key, '{}');
}
- public render() {
- return (
- !this.state.closed && (
-
- {this.props.children}
-
- this.close()}>
-
- {' '}
-
-
- )
- );
- }
-
- private close() {
- this.setState({closed: true});
- localStorage.setItem(this.props.key, '{}');
- }
+ return (
+ !closed && (
+
+ {props.children}
+
+ close()}>
+
+ {' '}
+
+
+ )
+ );
}
diff --git a/ui/src/app/shared/components/pagination-panel.tsx b/ui/src/app/shared/components/pagination-panel.tsx
index 552654ce3ae8..da1906a02b52 100644
--- a/ui/src/app/shared/components/pagination-panel.tsx
+++ b/ui/src/app/shared/components/pagination-panel.tsx
@@ -2,61 +2,56 @@ import * as React from 'react';
import {Pagination, parseLimit} from '../pagination';
import {WarningIcon} from './fa-icons';
-export class PaginationPanel extends React.Component<{pagination: Pagination; onChange: (pagination: Pagination) => void; numRecords: number}> {
- public render() {
- return (
-
-
-
- {this.props.pagination.limit > 0 && this.props.pagination.limit <= this.props.numRecords ? (
- <>
- Workflows cannot be globally sorted when paginated
- >
- ) : (
-
- )}
-
- {' '}
+ results per page
+
+
+ );
}
diff --git a/ui/src/app/shared/conditions-panel.tsx b/ui/src/app/shared/conditions-panel.tsx
index 44b17f86819a..15689982e860 100644
--- a/ui/src/app/shared/conditions-panel.tsx
+++ b/ui/src/app/shared/conditions-panel.tsx
@@ -48,21 +48,19 @@ function getConditionIcon(condition: ConditionType): JSX.Element {
}
}
-export class ConditionsPanel extends React.Component {
- public render() {
- return (
- <>
- {this.props.conditions &&
- Object.entries(this.props.conditions).map(([_, condition]) => {
- return (
-
- {getConditionIcon(condition.type)}
- {condition.type}
- {': ' + (condition.message || condition.status)}
-
- );
- })}
- >
- );
- }
+export function ConditionsPanel(props: Props) {
+ return (
+ <>
+ {props.conditions &&
+ Object.entries(props.conditions).map(([_, condition]) => {
+ return (
+
+ {getConditionIcon(condition.type)}
+ {condition.type}
+ {': ' + (condition.message || condition.status)}
+
+ );
+ })}
+ >
+ );
}
diff --git a/ui/src/app/shared/resources-duration.tsx b/ui/src/app/shared/resources-duration.tsx
index 152a742af6a6..b3ca1b73e7b6 100644
--- a/ui/src/app/shared/resources-duration.tsx
+++ b/ui/src/app/shared/resources-duration.tsx
@@ -5,18 +5,16 @@ interface Props {
resourcesDuration: {[resource: string]: number};
}
-export class ResourcesDuration extends React.Component {
- public render() {
- return (
- <>
- {this.props.resourcesDuration &&
- Object.entries(this.props.resourcesDuration)
- .map(([resource, duration]) => formatDuration(duration, 1) + '*(' + denominator(resource) + ' ' + resource + ')')
- .join(',')}{' '}
-
-
-
- >
- );
- }
+export function ResourcesDuration(props: Props) {
+ return (
+ <>
+ {props.resourcesDuration &&
+ Object.entries(props.resourcesDuration)
+ .map(([resource, duration]) => formatDuration(duration, 1) + '*(' + denominator(resource) + ' ' + resource + ')')
+ .join(',')}{' '}
+
+
+
+ >
+ );
}
diff --git a/ui/src/app/workflow-templates/components/workflow-template-creator.tsx b/ui/src/app/workflow-templates/components/workflow-template-creator.tsx
index 58e6982b85d9..5b768e217761 100644
--- a/ui/src/app/workflow-templates/components/workflow-template-creator.tsx
+++ b/ui/src/app/workflow-templates/components/workflow-template-creator.tsx
@@ -10,7 +10,7 @@ import {services} from '../../shared/services';
import {Utils} from '../../shared/utils';
import {WorkflowTemplateEditor} from './workflow-template-editor';
-export const WorkflowTemplateCreator = ({namespace, onCreate}: {namespace: string; onCreate: (workflow: WorkflowTemplate) => void}) => {
+export function WorkflowTemplateCreator({namespace, onCreate}: {namespace: string; onCreate: (workflow: WorkflowTemplate) => void}) {
const [template, setTemplate] = useState(exampleWorkflowTemplate(Utils.getNamespaceWithDefault(namespace)));
const [error, setError] = useState();
return (
@@ -35,4 +35,4 @@ export const WorkflowTemplateCreator = ({namespace, onCreate}: {namespace: strin
>
);
-};
+}
diff --git a/ui/src/app/workflow-templates/components/workflow-template-details/workflow-template-details.tsx b/ui/src/app/workflow-templates/components/workflow-template-details/workflow-template-details.tsx
index d2a6dd7dbeb7..dbcc104c2c45 100644
--- a/ui/src/app/workflow-templates/components/workflow-template-details/workflow-template-details.tsx
+++ b/ui/src/app/workflow-templates/components/workflow-template-details/workflow-template-details.tsx
@@ -16,7 +16,7 @@ import {WidgetGallery} from '../../../widgets/widget-gallery';
import {SubmitWorkflowPanel} from '../../../workflows/components/submit-workflow-panel';
import {WorkflowTemplateEditor} from '../workflow-template-editor';
-export const WorkflowTemplateDetails = ({history, location, match}: RouteComponentProps) => {
+export function WorkflowTemplateDetails({history, location, match}: RouteComponentProps) {
// boiler-plate
const {notifications, navigation, popup} = useContext(Context);
const queryParams = new URLSearchParams(location.search);
@@ -139,4 +139,4 @@ export const WorkflowTemplateDetails = ({history, location, match}: RouteCompone
)}
);
-};
+}
diff --git a/ui/src/app/workflow-templates/components/workflow-template-editor.tsx b/ui/src/app/workflow-templates/components/workflow-template-editor.tsx
index 76059a783a22..5607c446e498 100644
--- a/ui/src/app/workflow-templates/components/workflow-template-editor.tsx
+++ b/ui/src/app/workflow-templates/components/workflow-template-editor.tsx
@@ -7,7 +7,7 @@ import {MetadataEditor} from '../../shared/components/editors/metadata-editor';
import {WorkflowParametersEditor} from '../../shared/components/editors/workflow-parameters-editor';
import {ObjectEditor} from '../../shared/components/object-editor/object-editor';
-export const WorkflowTemplateEditor = ({
+export function WorkflowTemplateEditor({
onChange,
onError,
onTabSelected,
@@ -19,7 +19,7 @@ export const WorkflowTemplateEditor = ({
onError: (error: Error) => void;
onTabSelected?: (tab: string) => void;
selectedTabKey?: string;
-}) => {
+}) {
return (
);
-};
+}
diff --git a/ui/src/app/workflow-templates/components/workflow-template-filters/workflow-template-filters.tsx b/ui/src/app/workflow-templates/components/workflow-template-filters/workflow-template-filters.tsx
index 602f6aa19e12..a4e5d484829c 100644
--- a/ui/src/app/workflow-templates/components/workflow-template-filters/workflow-template-filters.tsx
+++ b/ui/src/app/workflow-templates/components/workflow-template-filters/workflow-template-filters.tsx
@@ -13,7 +13,7 @@ interface WorkflowFilterProps {
onChange: (namespace: string, labels: string[]) => void;
}
-export const WorkflowTemplateFilters = ({templates, namespace, labels, onChange}: WorkflowFilterProps) => {
+export function WorkflowTemplateFilters({templates, namespace, labels, onChange}: WorkflowFilterProps) {
const [labelSuggestion, setLabelSuggestion] = useState([]);
useEffect(() => {
@@ -58,4 +58,4 @@ export const WorkflowTemplateFilters = ({templates, namespace, labels, onChange}
);
-};
+}
diff --git a/ui/src/app/workflow-templates/components/workflow-template-list/workflow-template-list.tsx b/ui/src/app/workflow-templates/components/workflow-template-list/workflow-template-list.tsx
index 950d5686c88a..201f3206435a 100644
--- a/ui/src/app/workflow-templates/components/workflow-template-list/workflow-template-list.tsx
+++ b/ui/src/app/workflow-templates/components/workflow-template-list/workflow-template-list.tsx
@@ -27,7 +27,7 @@ require('./workflow-template-list.scss');
const learnMore = Learn more;
-export const WorkflowTemplateList = ({match, location, history}: RouteComponentProps) => {
+export function WorkflowTemplateList({match, location, history}: RouteComponentProps) {
// boiler-plate
const queryParams = new URLSearchParams(location.search);
const {navigation} = useContext(Context);
@@ -163,4 +163,4 @@ export const WorkflowTemplateList = ({match, location, history}: RouteComponentP
);
-};
+}
diff --git a/ui/src/app/workflows/components/events-panel.tsx b/ui/src/app/workflows/components/events-panel.tsx
index 9cb20b792c9c..b49027b7e951 100644
--- a/ui/src/app/workflows/components/events-panel.tsx
+++ b/ui/src/app/workflows/components/events-panel.tsx
@@ -10,7 +10,7 @@ import debounce from '../../shared/debounce';
import {ListWatch} from '../../shared/list-watch';
import {services} from '../../shared/services';
-export const EventsPanel = ({namespace, name, kind}: {namespace: string; name: string; kind: string}) => {
+export function EventsPanel({namespace, name, kind}: {namespace: string; name: string; kind: string}) {
const [showAll, setShowAll] = useState(false);
const [hideNormal, setHideNormal] = useState(false);
const [events, setEvents] = useState();
@@ -53,7 +53,7 @@ export const EventsPanel = ({namespace, name, kind}: {namespace: string; name: s
const tableRef = useRef(null);
useEffect(() => {
- const calculateTooltips = () => {
+ function calculateTooltips() {
const table = tableRef.current;
if (table) {
@@ -75,7 +75,7 @@ export const EventsPanel = ({namespace, name, kind}: {namespace: string; name: s
}
}
}
- };
+ }
const [debouncedCalculateTooltips, cleanup] = debounce(calculateTooltips, 1000);
@@ -134,4 +134,4 @@ export const EventsPanel = ({namespace, name, kind}: {namespace: string; name: s
)}
>
);
-};
+}
diff --git a/ui/src/app/workflows/components/workflow-artifacts.tsx b/ui/src/app/workflows/components/workflow-artifacts.tsx
index 8ae8dbb67bc0..9b700ec8998b 100644
--- a/ui/src/app/workflows/components/workflow-artifacts.tsx
+++ b/ui/src/app/workflows/components/workflow-artifacts.tsx
@@ -9,7 +9,7 @@ interface Props {
archived: boolean;
}
-export const WorkflowArtifacts = (props: Props) => {
+export function WorkflowArtifacts(props: Props) {
const workflowStatusNodes = (props.workflow.status && props.workflow.status.nodes) || {};
const artifacts =
Object.keys(workflowStatusNodes)
@@ -60,4 +60,4 @@ export const WorkflowArtifacts = (props: Props) => {
);
-};
+}
diff --git a/ui/src/app/workflows/components/workflow-creator-info/workflow-creator-info.tsx b/ui/src/app/workflows/components/workflow-creator-info/workflow-creator-info.tsx
index 011750e5ed21..3edf8101d542 100644
--- a/ui/src/app/workflows/components/workflow-creator-info/workflow-creator-info.tsx
+++ b/ui/src/app/workflows/components/workflow-creator-info/workflow-creator-info.tsx
@@ -9,41 +9,35 @@ interface WorkflowCreatorInfoProps {
onChange: (key: string, value: string) => void;
}
-export class WorkflowCreatorInfo extends React.Component {
- constructor(props: WorkflowCreatorInfoProps) {
- super(props);
- }
-
- public render() {
- const w = this.props.workflow;
- const creatorLabels = [];
- if (w.metadata.labels) {
- const creatorInfoMap = new Map([
- ['Name', [labels.creator, w.metadata.labels[labels.creator]]],
- ['Email', [labels.creatorEmail, w.metadata.labels[labels.creatorEmail]]],
- ['Preferred username', [labels.creatorPreferredUsername, w.metadata.labels[labels.creatorPreferredUsername]]]
- ]);
- creatorInfoMap.forEach((value: [string, string], key: string) => {
- const [searchKey, searchValue] = value;
- if (searchValue !== '' && searchValue !== undefined) {
- creatorLabels.push(
- {
- e.preventDefault();
- this.props.onChange(searchKey, searchValue);
- }}>
-
{key}
-
{searchValue}
-
- );
- }
- });
- } else {
- creatorLabels.push( No creator information
);
- }
- return {creatorLabels}
;
+export function WorkflowCreatorInfo(props: WorkflowCreatorInfoProps) {
+ const w = props.workflow;
+ const creatorLabels = [];
+ if (w.metadata.labels) {
+ const creatorInfoMap = new Map([
+ ['Name', [labels.creator, w.metadata.labels[labels.creator]]],
+ ['Email', [labels.creatorEmail, w.metadata.labels[labels.creatorEmail]]],
+ ['Preferred username', [labels.creatorPreferredUsername, w.metadata.labels[labels.creatorPreferredUsername]]]
+ ]);
+ creatorInfoMap.forEach((value: [string, string], key: string) => {
+ const [searchKey, searchValue] = value;
+ if (searchValue !== '' && searchValue !== undefined) {
+ creatorLabels.push(
+ {
+ e.preventDefault();
+ props.onChange(searchKey, searchValue);
+ }}>
+
{key}
+
{searchValue}
+
+ );
+ }
+ });
+ } else {
+ creatorLabels.push( No creator information
);
}
+ return {creatorLabels}
;
}
diff --git a/ui/src/app/workflows/components/workflow-creator.tsx b/ui/src/app/workflows/components/workflow-creator.tsx
index c423150cf0ec..0146abe15f45 100644
--- a/ui/src/app/workflows/components/workflow-creator.tsx
+++ b/ui/src/app/workflows/components/workflow-creator.tsx
@@ -14,7 +14,7 @@ import {WorkflowEditor} from './workflow-editor';
type Stage = 'choose-method' | 'submit-workflow' | 'full-editor';
-export const WorkflowCreator = ({namespace, onCreate}: {namespace: string; onCreate: (workflow: Workflow) => void}) => {
+export function WorkflowCreator({namespace, onCreate}: {namespace: string; onCreate: (workflow: Workflow) => void}) {
const [workflowTemplates, setWorkflowTemplates] = useState();
const [workflowTemplate, setWorkflowTemplate] = useState();
const [stage, setStage] = useState('choose-method');
@@ -123,4 +123,4 @@ export const WorkflowCreator = ({namespace, onCreate}: {namespace: string; onCre
)}
>
);
-};
+}
diff --git a/ui/src/app/workflows/components/workflow-dag/workflow-dag-render-options-panel.tsx b/ui/src/app/workflows/components/workflow-dag/workflow-dag-render-options-panel.tsx
index d577cce7dfeb..6607a3b058b1 100644
--- a/ui/src/app/workflows/components/workflow-dag/workflow-dag-render-options-panel.tsx
+++ b/ui/src/app/workflows/components/workflow-dag/workflow-dag-render-options-panel.tsx
@@ -1,46 +1,44 @@
import * as React from 'react';
import {WorkflowDagRenderOptions} from './workflow-dag';
-export class WorkflowDagRenderOptionsPanel extends React.Component void}> {
- private get workflowDagRenderOptions() {
- return this.props as WorkflowDagRenderOptions;
+export function WorkflowDagRenderOptionsPanel(props: WorkflowDagRenderOptions & {onChange: (changed: WorkflowDagRenderOptions) => void}) {
+ function workflowDagRenderOptions() {
+ return props as WorkflowDagRenderOptions;
}
- public render() {
- return (
- <>
-
- this.props.onChange({
- ...this.workflowDagRenderOptions,
- showArtifacts: !this.workflowDagRenderOptions.showArtifacts
- })
- }
- className={this.workflowDagRenderOptions.showArtifacts ? 'active' : ''}
- title='Toggle artifacts'>
-
-
-
- this.props.onChange({
- ...this.workflowDagRenderOptions,
- expandNodes: new Set()
- })
- }
- title='Collapse all nodes'>
-
-
-
- this.props.onChange({
- ...this.workflowDagRenderOptions,
- expandNodes: new Set(['*'])
- })
- }
- title='Expand all nodes'>
-
-
- >
- );
- }
+ return (
+ <>
+
+ props.onChange({
+ ...workflowDagRenderOptions(),
+ showArtifacts: !workflowDagRenderOptions().showArtifacts
+ })
+ }
+ className={workflowDagRenderOptions().showArtifacts ? 'active' : ''}
+ title='Toggle artifacts'>
+
+
+
+ props.onChange({
+ ...workflowDagRenderOptions(),
+ expandNodes: new Set()
+ })
+ }
+ title='Collapse all nodes'>
+
+
+
+ props.onChange({
+ ...workflowDagRenderOptions(),
+ expandNodes: new Set(['*'])
+ })
+ }
+ title='Expand all nodes'>
+
+
+ >
+ );
}
diff --git a/ui/src/app/workflows/components/workflow-editor.tsx b/ui/src/app/workflows/components/workflow-editor.tsx
index e0ed3cbd58a1..184fcbb249c3 100644
--- a/ui/src/app/workflows/components/workflow-editor.tsx
+++ b/ui/src/app/workflows/components/workflow-editor.tsx
@@ -6,7 +6,7 @@ import {MetadataEditor} from '../../shared/components/editors/metadata-editor';
import {WorkflowParametersEditor} from '../../shared/components/editors/workflow-parameters-editor';
import {ObjectEditor} from '../../shared/components/object-editor/object-editor';
-export const WorkflowEditor = ({
+export function WorkflowEditor({
selectedTabKey,
onTabSelected,
onError,
@@ -18,7 +18,7 @@ export const WorkflowEditor = ({
onError: (error: Error) => void;
onTabSelected?: (tab: string) => void;
selectedTabKey?: string;
-}) => {
+}) {
return (
);
-};
+}
diff --git a/ui/src/app/workflows/components/workflow-from.tsx b/ui/src/app/workflows/components/workflow-from.tsx
index 69e3e4a7a51f..c99f546f075b 100644
--- a/ui/src/app/workflows/components/workflow-from.tsx
+++ b/ui/src/app/workflows/components/workflow-from.tsx
@@ -4,7 +4,7 @@ import {ClusterWorkflowTemplateLink} from '../../cluster-workflow-templates/comp
import {CronWorkflowLink} from '../../cron-workflows/components/cron-workflow-link';
import {WorkflowTemplateLink} from '../../workflow-templates/components/workflow-template-link';
-export const WorkflowFrom = (props: {namespace: string; labels: {[name: string]: string}}) => {
+export function WorkflowFrom(props: {namespace: string; labels: {[name: string]: string}}) {
const workflowTemplate = props.labels[labels.workflowTemplate];
const clusterWorkflowTemplate = props.labels[labels.clusterWorkflowTemplate];
const cronWorkflow = props.labels[labels.cronWorkflow];
@@ -16,4 +16,4 @@ export const WorkflowFrom = (props: {namespace: string; labels: {[name: string]:
{!workflowTemplate && !clusterWorkflowTemplate && !cronWorkflow && '-'}
>
);
-};
+}
diff --git a/ui/src/app/workflows/components/workflow-labels/workflow-labels.tsx b/ui/src/app/workflows/components/workflow-labels/workflow-labels.tsx
index 2b064cb5f539..f98c067ecaa6 100644
--- a/ui/src/app/workflows/components/workflow-labels/workflow-labels.tsx
+++ b/ui/src/app/workflows/components/workflow-labels/workflow-labels.tsx
@@ -8,34 +8,28 @@ interface WorkflowLabelsProps {
onChange: (key: string, value: string) => void;
}
-export class WorkflowLabels extends React.Component {
- constructor(props: WorkflowLabelsProps) {
- super(props);
+export function WorkflowLabels(props: WorkflowLabelsProps) {
+ const labels = [];
+ const w = props.workflow;
+ if (w.metadata.labels) {
+ labels.push(
+ Object.entries(w.metadata.labels).map(([key, value]) => (
+ {
+ e.preventDefault();
+ props.onChange(key, value);
+ }}>
+
{key}
+
{value}
+
+ ))
+ );
+ } else {
+ labels.push( No labels
);
}
- public render() {
- const labels = [];
- const w = this.props.workflow;
- if (w.metadata.labels) {
- labels.push(
- Object.entries(w.metadata.labels).map(([key, value]) => (
- {
- e.preventDefault();
- this.props.onChange(key, value);
- }}>
-
{key}
-
{value}
-
- ))
- );
- } else {
- labels.push( No labels
);
- }
-
- return {labels}
;
- }
+ return {labels}
;
}
diff --git a/ui/src/app/workflows/components/workflow-logs-viewer/full-height-logs-viewer.tsx b/ui/src/app/workflows/components/workflow-logs-viewer/full-height-logs-viewer.tsx
index 4e351237122d..a7b5d14394c2 100644
--- a/ui/src/app/workflows/components/workflow-logs-viewer/full-height-logs-viewer.tsx
+++ b/ui/src/app/workflows/components/workflow-logs-viewer/full-height-logs-viewer.tsx
@@ -5,7 +5,7 @@ import {LogsViewerProps} from 'argo-ui/src/components/logs-viewer/logs-viewer';
require('./workflow-logs-viewer.scss');
-export const FullHeightLogsViewer = (props: LogsViewerProps) => {
+export function FullHeightLogsViewer(props: LogsViewerProps) {
const ref = React.useRef(null);
const [height, setHeight] = React.useState(null);
const {source} = props;
@@ -20,4 +20,4 @@ export const FullHeightLogsViewer = (props: LogsViewerProps) => {
{height && }
);
-};
+}
diff --git a/ui/src/app/workflows/components/workflow-logs-viewer/json-logs-field-selector.tsx b/ui/src/app/workflows/components/workflow-logs-viewer/json-logs-field-selector.tsx
index 0079f7663b12..07a3898e1889 100644
--- a/ui/src/app/workflows/components/workflow-logs-viewer/json-logs-field-selector.tsx
+++ b/ui/src/app/workflows/components/workflow-logs-viewer/json-logs-field-selector.tsx
@@ -5,7 +5,7 @@ export interface SelectedJsonFields {
values: string[];
}
-export const JsonLogsFieldSelector = ({fields, onChange}: {fields: SelectedJsonFields; onChange: (v: string[]) => void}) => {
+export function JsonLogsFieldSelector({fields, onChange}: {fields: SelectedJsonFields; onChange: (v: string[]) => void}) {
const [inputFields, setInputFields] = React.useState(fields);
const [key, setKey] = React.useState('');
const deleteItem = (k: string) => {
@@ -61,7 +61,7 @@ export const JsonLogsFieldSelector = ({fields, onChange}: {fields: SelectedJsonF
>
);
-};
+}
export const extractJsonValue = (obj: any, jsonpath: string): string | null => {
const fields = jsonpath.split('.');
diff --git a/ui/src/app/workflows/components/workflow-logs-viewer/workflow-logs-viewer.tsx b/ui/src/app/workflows/components/workflow-logs-viewer/workflow-logs-viewer.tsx
index 14579c606170..b2c94abd83ff 100644
--- a/ui/src/app/workflows/components/workflow-logs-viewer/workflow-logs-viewer.tsx
+++ b/ui/src/app/workflows/components/workflow-logs-viewer/workflow-logs-viewer.tsx
@@ -48,16 +48,16 @@ interface ParsedTime {
fullstring: string;
}
// extract the time field from a string
-const parseTime = (formattedString: string): undefined | ParsedTime => {
+function parseTime(formattedString: string): undefined | ParsedTime {
const re = new RegExp('time="(.*?)"');
const table = re.exec(formattedString);
if (table === null || table.length !== 2) {
return undefined;
}
return {quoted: table[1], fullstring: table[0]};
-};
+}
-const parseAndTransform = (formattedString: string, timezone: string) => {
+function parseAndTransform(formattedString: string, timezone: string) {
const maybeTime = parseTime(formattedString);
if (maybeTime === undefined) {
return formattedString;
@@ -71,9 +71,9 @@ const parseAndTransform = (formattedString: string, timezone: string) => {
} catch {
return formattedString;
}
-};
+}
-export const WorkflowLogsViewer = ({workflow, nodeId, initialPodName, container, archived}: WorkflowLogsViewerProps) => {
+export function WorkflowLogsViewer({workflow, nodeId, initialPodName, container, archived}: WorkflowLogsViewerProps) {
const storage = new ScopedLocalStorage('workflow-logs-viewer');
const storedJsonFields = storage.getItem('jsonFields', {
values: []
@@ -202,7 +202,7 @@ export const WorkflowLogsViewer = ({workflow, nodeId, initialPodName, container,
const [candidateContainer, setCandidateContainer] = useState(container);
const filteredTimezones = timezones.filter(tz => tz.startsWith(uiTimezone) || uiTimezone === '');
- const popupJsonFieldSelector = async () => {
+ async function popupJsonFieldSelector() {
const fields = {...selectedJsonFields};
const updated = await popup.confirm('Select Json Fields', () => (
@@ -333,4 +333,4 @@ export const WorkflowLogsViewer = ({workflow, nodeId, initialPodName, container,
);
-};
+}
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 6a4fd98af42d..87b505991d2a 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
@@ -1,6 +1,7 @@
import {Tabs, Ticker, Tooltip} from 'argo-ui';
import moment from 'moment';
import * as React from 'react';
+import {useState} from 'react';
import * as models from '../../../../models';
import {Artifact, NodeStatus, Workflow} from '../../../../models';
@@ -377,49 +378,39 @@ const WorkflowNodeContainer = (props: {
);
};
-class WorkflowNodeContainers extends React.Component {
- constructor(props: Props) {
- super(props);
- this.state = {selectedSidecar: null};
- }
-
- public render() {
- const template = getResolvedTemplates(this.props.workflow, this.props.node);
- if (!template || (!template.container && !template.containerSet && !template.script)) {
- return (
-
- );
- }
- const containers = (template.containerSet ? template.containerSet.containers : []).concat(template.sidecars || []);
-
- const container = (this.state.selectedSidecar && containers.find(item => item.name === this.state.selectedSidecar)) || template.container || template.script;
+function WorkflowNodeContainers(props: Props) {
+ const [selectedSidecar, setSelectedSidecar] = useState(null);
+ const template = getResolvedTemplates(props.workflow, props.node);
+ if (!template || (!template.container && !template.containerSet && !template.script)) {
return (
-
- {this.state.selectedSidecar &&
this.setState({selectedSidecar: null})} />}
-
- {!this.state.selectedSidecar && (
-
-
SIDECARS:
- {containers.map(sidecar => (
-
this.setState({selectedSidecar: sidecar.name})}>
- {sidecar.name}
-
- ))}
-
- )}
+
);
}
+
+ const containers = (template.containerSet ? template.containerSet.containers : []).concat(template.sidecars || []);
+ const container = (selectedSidecar && containers.find(item => item.name === selectedSidecar)) || template.container || template.script;
+
+ return (
+
+ {selectedSidecar &&
setSelectedSidecar(null)} />}
+
+ {!selectedSidecar && (
+
+
SIDECARS:
+ {containers.map(sidecar => (
+
setSelectedSidecar(sidecar.name)}>
+ {sidecar.name}
+
+ ))}
+
+ )}
+
+ );
}
const WorkflowNodeArtifacts = (props: {workflow: Workflow; node: NodeStatus; archived: boolean; isInput: boolean; artifacts: Artifact[]}) => {
diff --git a/ui/src/app/workflows/components/workflow-panel/workflow-panel.tsx b/ui/src/app/workflows/components/workflow-panel/workflow-panel.tsx
index 523163e7b90c..a84df7d13766 100644
--- a/ui/src/app/workflows/components/workflow-panel/workflow-panel.tsx
+++ b/ui/src/app/workflows/components/workflow-panel/workflow-panel.tsx
@@ -12,26 +12,24 @@ interface Props {
nodeClicked: (nodeId: string) => void;
}
-export class WorkflowPanel extends React.Component {
- public render() {
- if (!this.props.workflowStatus.nodes && this.props.workflowStatus.phase) {
- return (
-
-
- : {this.props.workflowStatus.message}
-
-
- );
- }
-
+export function WorkflowPanel(props: Props) {
+ if (!props.workflowStatus.nodes && props.workflowStatus.phase) {
return (
-
+
+
+ : {props.workflowStatus.message}
+
+
);
}
+
+ return (
+
+ );
}
diff --git a/ui/src/app/workflows/components/workflow-yaml-viewer/workflow-yaml-viewer.tsx b/ui/src/app/workflows/components/workflow-yaml-viewer/workflow-yaml-viewer.tsx
index 1202f5cc369f..d4376c58e068 100644
--- a/ui/src/app/workflows/components/workflow-yaml-viewer/workflow-yaml-viewer.tsx
+++ b/ui/src/app/workflows/components/workflow-yaml-viewer/workflow-yaml-viewer.tsx
@@ -10,59 +10,60 @@ interface WorkflowYamlViewerProps {
selectedNode: models.NodeStatus;
}
-export class WorkflowYamlViewer extends React.Component {
- public render() {
- const contents: JSX.Element[] = [];
- contents.push(Node
);
- if (this.props.selectedNode) {
- const parentNode = this.props.workflow.status.nodes[this.props.selectedNode.boundaryID];
- if (parentNode) {
- contents.push(
-
-
{this.normalizeNodeName(this.props.selectedNode.displayName || this.props.selectedNode.name)}
-
-
- );
- }
+function normalizeNodeName(name: string) {
+ const parts = name.replace(/([(][^)]*[)])/g, '').split('.');
+ return parts[parts.length - 1];
+}
- const currentNodeTemplate = getResolvedTemplates(this.props.workflow, this.props.selectedNode);
- if (currentNodeTemplate) {
- contents.push(
-
-
{this.props.selectedNode.name}
-
-
- );
- }
- }
- const templates = this.props.workflow.spec.templates;
- if (templates && Object.keys(templates).length) {
+export function WorkflowYamlViewer(props: WorkflowYamlViewerProps) {
+ const contents: JSX.Element[] = [];
+ contents.push(Node
);
+
+ if (props.selectedNode) {
+ const parentNode = props.workflow.status.nodes[props.selectedNode.boundaryID];
+ if (parentNode) {
contents.push(
- }
- className='workflow-yaml-section'
- />
+
+
{normalizeNodeName(props.selectedNode.displayName || props.selectedNode.name)}
+
+
);
}
- const storedTemplates = this.props.workflow.status.storedTemplates;
- if (storedTemplates && Object.keys(storedTemplates).length) {
+
+ const currentNodeTemplate = getResolvedTemplates(props.workflow, props.selectedNode);
+ if (currentNodeTemplate) {
contents.push(
- }
- className='workflow-yaml-section'
- />
+
+
{props.selectedNode.name}
+
+
);
}
+ }
- return {contents}
;
+ const templates = props.workflow.spec.templates;
+ if (templates && Object.keys(templates).length) {
+ contents.push(
+ }
+ className='workflow-yaml-section'
+ />
+ );
}
- private normalizeNodeName(name: string) {
- const parts = name.replace(/([(][^)]*[)])/g, '').split('.');
- return parts[parts.length - 1];
+ const storedTemplates = props.workflow.status.storedTemplates;
+ if (storedTemplates && Object.keys(storedTemplates).length) {
+ contents.push(
+ }
+ className='workflow-yaml-section'
+ />
+ );
}
+
+ return {contents}
;
}
diff --git a/ui/src/app/workflows/components/workflows-row/workflows-row.tsx b/ui/src/app/workflows/components/workflows-row/workflows-row.tsx
index 9b428205d38c..6a3f3dad2d16 100644
--- a/ui/src/app/workflows/components/workflows-row/workflows-row.tsx
+++ b/ui/src/app/workflows/components/workflows-row/workflows-row.tsx
@@ -1,5 +1,6 @@
import {Ticker} from 'argo-ui/src/index';
import * as React from 'react';
+import {useState} from 'react';
import {Link} from 'react-router-dom';
import * as models from '../../../../models';
import {isArchivedWorkflow, Workflow} from '../../../../models';
@@ -19,103 +20,92 @@ interface WorkflowsRowProps {
columns: models.Column[];
}
-interface WorkflowRowState {
- hideDrawer: boolean;
-}
-
-export class WorkflowsRow extends React.Component {
- constructor(props: WorkflowsRowProps) {
- super(props);
- this.state = {
- hideDrawer: true
- };
- }
+export function WorkflowsRow(props: WorkflowsRowProps) {
+ const [hideDrawer, setHideDrawer] = useState(true);
+ const wf = props.workflow;
- public render() {
- const wf = this.props.workflow;
- return (
-
-
-
-
{
- e.stopPropagation();
- }}
- onChange={e => {
- this.props.select(this.props.workflow);
- }}
- />
-
-
-
+
+
+
{
+ e.stopPropagation();
}}
- className='small-11 row'>
-
- {(wf.metadata.annotations && wf.metadata.annotations[ANNOTATION_TITLE]) || wf.metadata.name}
- {wf.metadata.annotations && wf.metadata.annotations[ANNOTATION_DESCRIPTION] ?
{wf.metadata.annotations[ANNOTATION_DESCRIPTION]}
: null}
-
-
{wf.metadata.namespace}
-
-
-
-
-
-
-
- {() => }
-
-
{wf.status.progress || '-'}
-
{wf.status.message || '-'}
-
-
-
{
- e.preventDefault();
- this.setState({hideDrawer: !this.state.hideDrawer});
- }}
- className={`workflows-row__action workflows-row__action--${this.state.hideDrawer ? 'show' : 'hide'}`}>
- {this.state.hideDrawer ? (
-
- SHOW {' '}
-
- ) : (
-
- HIDE
-
- )}
-
+ onChange={e => {
+ props.select(props.workflow);
+ }}
+ />
+
+
+
+
+ {(wf.metadata.annotations && wf.metadata.annotations[ANNOTATION_TITLE]) || wf.metadata.name}
+ {wf.metadata.annotations && wf.metadata.annotations[ANNOTATION_DESCRIPTION] ?
{wf.metadata.annotations[ANNOTATION_DESCRIPTION]}
: null}
+
+
{wf.metadata.namespace}
+
+
+
+
+
+
+
+ {() => }
+
+
{wf.status.progress || '-'}
+
{wf.status.message || '-'}
+
+
+
{
+ e.preventDefault();
+ setHideDrawer(!hideDrawer);
+ }}
+ className={`workflows-row__action workflows-row__action--${hideDrawer ? 'show' : 'hide'}`}>
+ {hideDrawer ? (
+
+ SHOW {' '}
+
+ ) : (
+
+ HIDE
+
+ )}
-
{isArchivedWorkflow(wf) ? 'true' : 'false'}
- {(this.props.columns || []).map(column => {
- // best not to make any assumptions and wait until this data is filled
- const value = wf?.metadata?.labels?.[column.key] ?? 'unknown';
- return (
-
- {value}
-
- );
- })}
- {this.state.hideDrawer ? (
-
- ) : (
-
{
- this.props.onChange(key);
- }}
- />
- )}
-
-
+
+
{isArchivedWorkflow(wf) ? 'true' : 'false'}
+ {(props.columns || []).map(column => {
+ // best not to make any assumptions and wait until this data is filled
+ const value = wf?.metadata?.labels?.[column.key] ?? 'unknown';
+ return (
+
+ {value}
+
+ );
+ })}
+ {hideDrawer ? (
+
+ ) : (
+
{
+ props.onChange(key);
+ }}
+ />
+ )}
+
- );
- }
+
+ );
}
diff --git a/ui/src/app/workflows/components/workflows-summary-container/workflows-summary-container.tsx b/ui/src/app/workflows/components/workflows-summary-container/workflows-summary-container.tsx
index 03d5fdeea115..c47796f2899c 100644
--- a/ui/src/app/workflows/components/workflows-summary-container/workflows-summary-container.tsx
+++ b/ui/src/app/workflows/components/workflows-summary-container/workflows-summary-container.tsx
@@ -7,7 +7,7 @@ require('./workflows-summary-container.scss');
type ReduceReturnType = Record
;
-export const WorkflowsSummaryContainer = (props: {workflows: Workflow[]}) => {
+export function WorkflowsSummaryContainer(props: {workflows: Workflow[]}) {
const [wfSummary, setWfSummary] = useState(null);
useEffect(() => {
if (props.workflows) {
@@ -54,4 +54,4 @@ export const WorkflowsSummaryContainer = (props: {workflows: Workflow[]}) => {
);
-};
+}