From 9bccb2615922ec72758c261f89edc8038ecc4f83 Mon Sep 17 00:00:00 2001 From: Alan Greene Date: Wed, 17 Nov 2021 19:35:14 +0000 Subject: [PATCH] Surface details of step onError continue in lists and details Update the step and Task display in the UI to show indicators when a non-zero exit code was ignored. Propagate the indicator all the way up to the PipelineRuns and TaskRuns list pages, using the base 'success' icon. When a step is selected, display the non-zero exit code in the step details header so the user can easily identify why the status is displayed differently. We have a similar message in the log trailer but this may be below the fold depending on log length, window size, etc. --- .../components/DetailsHeader/DetailsHeader.js | 27 +++- .../DetailsHeader/DetailsHeader.scss | 6 + .../DetailsHeader/DetailsHeader.stories.js | 15 ++- .../PipelineRun/PipelineRun.stories.js | 118 ++++++++---------- .../components/PipelineRuns/PipelineRuns.js | 16 ++- .../components/PipelineRuns/PipelineRuns.scss | 6 + .../PipelineRuns/PipelineRuns.stories.js | 47 ++++++- .../src/components/StatusIcon/StatusIcon.js | 27 ++-- .../src/components/StatusIcon/StatusIcon.scss | 14 +++ .../StatusIcon/StatusIcon.stories.js | 7 +- .../components/src/components/Step/Step.js | 23 ++-- .../src/components/Step/Step.stories.js | 8 +- .../src/components/Step/Step.test.js | 9 +- .../src/components/StepDetails/StepDetails.js | 4 +- .../StepDetails/StepDetails.stories.js | 34 +++-- .../components/src/components/Task/Task.js | 59 +++++++-- .../components/src/components/Task/Task.scss | 7 ++ .../src/components/Task/Task.stories.js | 13 +- .../TaskRunDetails/TaskRunDetails.js | 88 +++++++------ .../TaskRunDetails/TaskRunDetails.stories.js | 34 +++++ .../src/components/TaskRuns/TaskRuns.js | 10 +- packages/utils/src/utils/index.js | 13 ++ packages/utils/src/utils/index.test.js | 44 +++++++ src/nls/messages_de.json | 1 + src/nls/messages_en.json | 1 + src/nls/messages_es.json | 1 + src/nls/messages_fr.json | 1 + src/nls/messages_it.json | 1 + src/nls/messages_ja.json | 1 + src/nls/messages_ko.json | 1 + src/nls/messages_pt.json | 1 + src/nls/messages_zh-Hans.json | 1 + src/nls/messages_zh-Hant.json | 1 + 33 files changed, 477 insertions(+), 162 deletions(-) diff --git a/packages/components/src/components/DetailsHeader/DetailsHeader.js b/packages/components/src/components/DetailsHeader/DetailsHeader.js index ceefd7b6c..46bec1004 100644 --- a/packages/components/src/components/DetailsHeader/DetailsHeader.js +++ b/packages/components/src/components/DetailsHeader/DetailsHeader.js @@ -53,7 +53,7 @@ class DetailsHeader extends Component { } statusLabel() { - const { intl, reason, status, taskRun } = this.props; + const { exitCode, hasWarning, intl, reason, status, taskRun } = this.props; const { reason: taskReason, status: taskStatus } = getStatus(taskRun); if ( @@ -75,10 +75,18 @@ class DetailsHeader extends Component { } if (status === 'terminated') { if (reason === 'Completed') { - return intl.formatMessage({ - id: 'dashboard.taskRun.status.succeeded', - defaultMessage: 'Completed' - }); + return hasWarning + ? intl.formatMessage( + { + id: 'dashboard.taskRun.status.succeeded.warning', + defaultMessage: 'Completed with exit code {exitCode}' + }, + { exitCode } + ) + : intl.formatMessage({ + id: 'dashboard.taskRun.status.succeeded', + defaultMessage: 'Completed' + }); } return intl.formatMessage({ id: 'dashboard.taskRun.status.failed', @@ -100,7 +108,13 @@ class DetailsHeader extends Component { } render() { - const { intl, displayName, taskRun, type = 'step' } = this.props; + const { + displayName, + hasWarning, + intl, + taskRun, + type = 'step' + } = this.props; let { reason, status } = this.props; let statusLabel; @@ -127,6 +141,7 @@ class DetailsHeader extends Component {

.tkn--status-label { diff --git a/packages/components/src/components/DetailsHeader/DetailsHeader.stories.js b/packages/components/src/components/DetailsHeader/DetailsHeader.stories.js index 96c55810e..372f2eec0 100644 --- a/packages/components/src/components/DetailsHeader/DetailsHeader.stories.js +++ b/packages/components/src/components/DetailsHeader/DetailsHeader.stories.js @@ -1,5 +1,5 @@ /* -Copyright 2019-2020 The Tekton Authors +Copyright 2019-2021 The Tekton Authors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at @@ -67,6 +67,19 @@ export const Completed = args => ( /> ); +export const CompletedWithWarning = args => ( + +); +CompletedWithWarning.storyName = 'Completed with warning'; + export const Failed = args => ( { pipelineRun={pipelineRun} selectedStepId={selectedStepId} selectedTaskId={selectedTaskId} - taskRuns={[taskRun]} + taskRuns={[taskRun, taskRunWithWarning]} tasks={[task]} /> ); diff --git a/packages/components/src/components/PipelineRuns/PipelineRuns.js b/packages/components/src/components/PipelineRuns/PipelineRuns.js index 98a7ae347..fb6503685 100644 --- a/packages/components/src/components/PipelineRuns/PipelineRuns.js +++ b/packages/components/src/components/PipelineRuns/PipelineRuns.js @@ -15,7 +15,7 @@ import React from 'react'; import { injectIntl } from 'react-intl'; import { Link } from 'react-router-dom'; import { StatusIcon, Table } from '@tektoncd/dashboard-components'; -import { getStatus, urls } from '@tektoncd/dashboard-utils'; +import { getStatus, taskRunHasWarning, urls } from '@tektoncd/dashboard-utils'; import { Pending24 as DefaultIcon } from '@carbon/icons-react'; import { Link as CarbonLink } from 'carbon-components-react'; @@ -40,8 +40,20 @@ const PipelineRuns = ({ }, getPipelineRunStatusIcon = pipelineRun => { const { reason, status } = getStatus(pipelineRun); + let hasWarning = false; + if (status === 'True' && reason === 'Succeeded') { + hasWarning = Object.values( + pipelineRun.status?.taskRuns || {} + ).some(taskRun => taskRunHasWarning(taskRun)); + } + return ( - + ); }, getPipelineRunStatusTooltip = (pipelineRun, intl) => { diff --git a/packages/components/src/components/PipelineRuns/PipelineRuns.scss b/packages/components/src/components/PipelineRuns/PipelineRuns.scss index ccdb5ee90..a13f65b91 100644 --- a/packages/components/src/components/PipelineRuns/PipelineRuns.scss +++ b/packages/components/src/components/PipelineRuns/PipelineRuns.scss @@ -18,5 +18,11 @@ limitations under the License. margin-right: 0.5em; vertical-align: sub; flex-shrink: 0; + + &.tkn--status-icon--warning { + width: 24px; + height: 24px; + margin-top: 1px; + } } } diff --git a/packages/components/src/components/PipelineRuns/PipelineRuns.stories.js b/packages/components/src/components/PipelineRuns/PipelineRuns.stories.js index 0767a25db..b573cbe5a 100644 --- a/packages/components/src/components/PipelineRuns/PipelineRuns.stories.js +++ b/packages/components/src/components/PipelineRuns/PipelineRuns.stories.js @@ -1,5 +1,5 @@ /* -Copyright 2019-2020 The Tekton Authors +Copyright 2019-2021 The Tekton Authors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at @@ -138,6 +138,51 @@ export const Base = () => ( } ] } + }, + { + metadata: { + name: 'pipeline-run-20211118145503', + namespace: 'cb4552a6-b2d7-45e2-9773-3d4ca33909ff', + uid: '90cde04b-ef64-4e3a-a74c-9cd7f78738d2', + creationTimestamp: '2021-11-18T14:55:00Z' + }, + spec: { + pipelineRef: { + name: 'pipeline' + } + }, + status: { + conditions: [ + { + lastTransitionTime: '2021-11-18T14:58:47Z', + message: 'All Tasks have completed executing', + reason: 'Succeeded', + status: 'True', + type: 'Succeeded' + } + ], + taskRuns: { + foo: { + status: { + conditions: [ + { + reason: 'Succeeded', + status: 'True', + type: 'Succeeded' + } + ], + steps: [ + { + terminated: { + exitCode: 1, + reason: 'Completed' + } + } + ] + } + } + } + } } ]} cancelPipelineRun={() => {}} diff --git a/packages/components/src/components/StatusIcon/StatusIcon.js b/packages/components/src/components/StatusIcon/StatusIcon.js index 046d34073..1c26cd80a 100644 --- a/packages/components/src/components/StatusIcon/StatusIcon.js +++ b/packages/components/src/components/StatusIcon/StatusIcon.js @@ -15,10 +15,12 @@ import React from 'react'; import classNames from 'classnames'; import { CheckmarkFilled20 as CheckmarkFilled, + CheckmarkFilledWarning20 as CheckmarkFilledWarning, CheckmarkOutline20 as CheckmarkOutline, CloseFilled20 as CloseFilled, CloseOutline20 as CloseOutline, - Time20 as Pending + Time20 as Pending, + WarningAltFilled20 as WarningFilled } from '@carbon/icons-react'; import { isRunning } from '@tektoncd/dashboard-utils'; @@ -30,23 +32,26 @@ const icons = { error: CloseFilled, pending: Pending, running: Spinner, - success: CheckmarkFilled + success: CheckmarkFilled, + warning: CheckmarkFilledWarning }, inverse: { cancelled: CloseOutline, error: CloseOutline, pending: Pending, running: Spinner, - success: CheckmarkOutline + success: CheckmarkOutline, + warning: WarningFilled } }; export default function StatusIcon({ DefaultIcon, - type = 'normal', + hasWarning, reason, status, - title + title, + type = 'normal' }) { let statusClass; if ( @@ -60,7 +65,7 @@ export default function StatusIcon({ status === 'True' || (status === 'terminated' && reason === 'Completed') ) { - statusClass = 'success'; + statusClass = hasWarning ? 'warning' : 'success'; } else if ( status === 'False' && (reason === 'PipelineRunCancelled' || reason === 'TaskRunCancelled') @@ -79,9 +84,13 @@ export default function StatusIcon({ return Icon ? ( {title && {title}} diff --git a/packages/components/src/components/StatusIcon/StatusIcon.scss b/packages/components/src/components/StatusIcon/StatusIcon.scss index f47e92bf0..12bb7f08a 100644 --- a/packages/components/src/components/StatusIcon/StatusIcon.scss +++ b/packages/components/src/components/StatusIcon/StatusIcon.scss @@ -31,4 +31,18 @@ limitations under the License. &--success { fill: $support-02; } + + &--warning { + &.tkn--status-icon--type-normal { + fill: $support-02; + + path:nth-child(2) { + fill: $support-03; + } + } + + &.tkn--status-icon--type-inverse { + fill: $support-03; + } + } } diff --git a/packages/components/src/components/StatusIcon/StatusIcon.stories.js b/packages/components/src/components/StatusIcon/StatusIcon.stories.js index 3a282f24b..edbba5d00 100644 --- a/packages/components/src/components/StatusIcon/StatusIcon.stories.js +++ b/packages/components/src/components/StatusIcon/StatusIcon.stories.js @@ -1,5 +1,5 @@ /* -Copyright 2020 The Tekton Authors +Copyright 2020-2021 The Tekton Authors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at @@ -46,4 +46,9 @@ export const Running = args => ( export const Succeeded = args => ; +export const SucceededWithWarning = args => ( + +); +SucceededWithWarning.storyName = 'Succeeded with warning'; + export const Failed = args => ; diff --git a/packages/components/src/components/Step/Step.js b/packages/components/src/components/Step/Step.js index e01e88df4..a597d0641 100644 --- a/packages/components/src/components/Step/Step.js +++ b/packages/components/src/components/Step/Step.js @@ -26,7 +26,7 @@ class Step extends Component { }; statusLabel() { - const { intl, reason, status } = this.props; + const { exitCode, intl, reason, status } = this.props; if ( status === 'cancelled' || @@ -48,10 +48,18 @@ class Step extends Component { if (status === 'terminated') { if (reason === 'Completed') { - return intl.formatMessage({ - id: 'dashboard.taskRun.status.succeeded', - defaultMessage: 'Completed' - }); + return exitCode !== 0 + ? intl.formatMessage( + { + id: 'dashboard.taskRun.status.succeeded.warning', + defaultMessage: 'Completed with exit code {exitCode}' + }, + { exitCode } + ) + : intl.formatMessage({ + id: 'dashboard.taskRun.status.succeeded', + defaultMessage: 'Completed' + }); } return intl.formatMessage({ id: 'dashboard.taskRun.status.failed', @@ -73,7 +81,7 @@ class Step extends Component { } render() { - const { reason, selected, status, stepName } = this.props; + const { exitCode, reason, selected, status, stepName } = this.props; const statusLabel = this.statusLabel(); return ( @@ -91,10 +99,11 @@ class Step extends Component { > {stepName} diff --git a/packages/components/src/components/Step/Step.stories.js b/packages/components/src/components/Step/Step.stories.js index b895f5ebe..6cd273c9d 100644 --- a/packages/components/src/components/Step/Step.stories.js +++ b/packages/components/src/components/Step/Step.stories.js @@ -1,5 +1,5 @@ /* -Copyright 2019-2020 The Tekton Authors +Copyright 2019-2021 The Tekton Authors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at @@ -17,6 +17,7 @@ import { action } from '@storybook/addon-actions'; import Step from './Step'; const props = { + exitCode: 0, onSelect: action('selected'), stepName: 'build' }; @@ -43,6 +44,11 @@ export const Completed = () => ( ); +export const CompletedWithWarning = () => ( + +); +CompletedWithWarning.storyName = 'Completed with warning'; + export const Error = () => ( ); diff --git a/packages/components/src/components/Step/Step.test.js b/packages/components/src/components/Step/Step.test.js index b15e7b2a5..035057ec7 100644 --- a/packages/components/src/components/Step/Step.test.js +++ b/packages/components/src/components/Step/Step.test.js @@ -63,11 +63,18 @@ it('Step renders cancelled state for TaskRunTimeout', () => { it('Step renders completed state', () => { const { queryByText } = render( - + ); expect(queryByText(/Completed/i)).toBeTruthy(); }); +it('Step renders completed with warning state', () => { + const { queryByText } = render( + + ); + expect(queryByText(/Completed with exit code 1/i)).toBeTruthy(); +}); + it('Step renders error state', () => { const { queryByText } = render(); expect(queryByText(/Failed/i)).toBeTruthy(); diff --git a/packages/components/src/components/StepDetails/StepDetails.js b/packages/components/src/components/StepDetails/StepDetails.js index e5cbfb104..4283ed377 100644 --- a/packages/components/src/components/StepDetails/StepDetails.js +++ b/packages/components/src/components/StepDetails/StepDetails.js @@ -31,7 +31,7 @@ const StepDetails = props => { taskRun, view } = props; - const { reason, status } = getStepStatusReason(stepStatus); + const { exitCode, reason, status } = getStepStatusReason(stepStatus); const statusValue = getStatus(taskRun).reason === 'TaskRunCancelled' && status !== 'terminated' ? 'cancelled' @@ -46,6 +46,8 @@ const StepDetails = props => {
ansiLog} - stepStatus={{ terminated: { reason: 'Completed' } }} - /> -); +function getLogContainer({ exitCode = 0 } = {}) { + return ( + ansiLog} stepStatus={getStepStatus({ exitCode })} /> + ); +} export default { component: StepDetails, @@ -39,9 +42,22 @@ export default { export const Base = () => ( ); + +export const WithWarning = () => { + const exitCode = 1; + return ( + + ); +}; diff --git a/packages/components/src/components/Task/Task.js b/packages/components/src/components/Task/Task.js index c18583572..b00601044 100644 --- a/packages/components/src/components/Task/Task.js +++ b/packages/components/src/components/Task/Task.js @@ -23,10 +23,47 @@ import { } from '@tektoncd/dashboard-utils'; class Task extends Component { - state = { selectedStepId: null }; + state = { hasWarning: false, selectedStepId: null }; componentDidMount() { this.selectDefaultStep(); + this.getStepData({ propagateWarning: true }); + } + + componentDidUpdate(prevProps) { + const { reason } = this.props; + if (prevProps.reason !== reason && reason === 'Succeeded') { + this.getStepData({ propagateWarning: true }); + } + } + + getStepData({ propagateWarning = false } = {}) { + const { reason, selectedStepId, steps } = this.props; + let hasWarning = false; + const stepData = updateUnexecutedSteps(steps).map(step => { + const { name } = step; + const { exitCode, status, reason: stepReason } = getStepStatusReason( + step + ); + + if (stepReason === 'Completed') { + hasWarning = hasWarning || exitCode !== 0; + } + + const selected = selectedStepId === name; + const stepStatus = + reason === 'TaskRunCancelled' && status !== 'terminated' + ? 'cancelled' + : status; + + return { exitCode, name, selected, stepReason, stepStatus }; + }); + + if (propagateWarning) { + this.setState({ hasWarning }); + } + + return stepData; } handleClick = () => { @@ -68,9 +105,9 @@ class Task extends Component { displayName, reason, selectedStepId, - steps, succeeded } = this.props; + const { hasWarning } = this.state; const expandIcon = expanded ? null : ( @@ -79,10 +116,11 @@ class Task extends Component { return (
  • @@ -100,17 +139,11 @@ class Task extends Component { {expanded && (
      - {updateUnexecutedSteps(steps).map(step => { - const { name } = step; - const { status, reason: stepReason } = getStepStatusReason(step); - - const selected = selectedStepId === name; - const stepStatus = - reason === 'TaskRunCancelled' && status !== 'terminated' - ? 'cancelled' - : status; + {this.getStepData().map(step => { + const { exitCode, name, selected, stepReason, stepStatus } = step; return ( .tkn--status-icon { margin-right: 0.75rem; + + &.tkn--status-icon--warning { + width: 24px; + height: 24px; + margin-top: 2px; + margin-right: 0.5rem; + } } &:focus, &:hover { diff --git a/packages/components/src/components/Task/Task.stories.js b/packages/components/src/components/Task/Task.stories.js index 7a5f7aa7f..246a66a29 100644 --- a/packages/components/src/components/Task/Task.stories.js +++ b/packages/components/src/components/Task/Task.stories.js @@ -22,8 +22,8 @@ const props = { }; const steps = [ - { name: 'lint', terminated: { reason: 'Completed' } }, - { name: 'test', terminated: { reason: 'Completed' } }, + { name: 'lint', terminated: { exitCode: 0, reason: 'Completed' } }, + { name: 'test', terminated: { exitCode: 1, reason: 'Completed' } }, { name: 'build', running: {} }, { name: 'deploy', running: {} } ]; @@ -42,6 +42,15 @@ export default { export const Succeeded = () => ; +export const SucceededWithWarning = () => ( + +); +SucceededWithWarning.storyName = 'Succeeded with warning'; + export const Failed = () => ; export const Unknown = () => ; diff --git a/packages/components/src/components/TaskRunDetails/TaskRunDetails.js b/packages/components/src/components/TaskRunDetails/TaskRunDetails.js index b1f40c5e5..f3c057734 100644 --- a/packages/components/src/components/TaskRunDetails/TaskRunDetails.js +++ b/packages/components/src/components/TaskRunDetails/TaskRunDetails.js @@ -15,7 +15,12 @@ import React, { useEffect, useState } from 'react'; import { Link } from 'react-router-dom'; import PropTypes from 'prop-types'; import { injectIntl } from 'react-intl'; -import { getParams, getResources, urls } from '@tektoncd/dashboard-utils'; +import { + getParams, + getResources, + taskRunHasWarning, + urls +} from '@tektoncd/dashboard-utils'; import { Link as CarbonLink, ContentSwitcher, @@ -39,45 +44,47 @@ function getDescriptions(array = []) { }, {}); } -const resourceTable = (title, namespace, resources, intl) => ( - ({ - id: name, - name, - value: - resourceRef && resourceRef.name ? ( - - {resourceRef.name} - - ) : ( - - ) - }))} - headers={[ - { - key: 'name', - header: intl.formatMessage({ - id: 'dashboard.tableHeader.name', - defaultMessage: 'Name' - }) - }, - { - key: 'value', - header: intl.formatMessage({ - id: 'dashboard.tableHeader.value', - defaultMessage: 'Value' - }) - } - ]} - /> -); +function resourceTable(title, namespace, resources, intl) { + return ( + ({ + id: name, + name, + value: + resourceRef && resourceRef.name ? ( + + {resourceRef.name} + + ) : ( + + ) + }))} + headers={[ + { + key: 'name', + header: intl.formatMessage({ + id: 'dashboard.tableHeader.name', + defaultMessage: 'Name' + }) + }, + { + key: 'value', + header: intl.formatMessage({ + id: 'dashboard.tableHeader.value', + defaultMessage: 'Value' + }) + } + ]} + /> + ); +} const TaskRunDetails = ({ intl, @@ -206,6 +213,7 @@ const TaskRunDetails = ({
      diff --git a/packages/components/src/components/TaskRunDetails/TaskRunDetails.stories.js b/packages/components/src/components/TaskRunDetails/TaskRunDetails.stories.js index e961583e6..82abdec8d 100644 --- a/packages/components/src/components/TaskRunDetails/TaskRunDetails.stories.js +++ b/packages/components/src/components/TaskRunDetails/TaskRunDetails.stories.js @@ -62,6 +62,40 @@ export const Base = () => ( /> ); +export const WithWarning = () => ( + +); + export const Pod = () => ( { const { reason, status } = getStatus(taskRun); - return ; + return ( + + ); }, getTaskRunStatusTooltip = (taskRun, intl) => { const { message } = getStatus(taskRun); diff --git a/packages/utils/src/utils/index.js b/packages/utils/src/utils/index.js index e0d9d8369..3377bf503 100644 --- a/packages/utils/src/utils/index.js +++ b/packages/utils/src/utils/index.js @@ -529,3 +529,16 @@ export function getTaskRunsWithPlaceholders({ return taskRunsToDisplay; } + +export function taskRunHasWarning(taskRun) { + const { reason, status } = getStatus(taskRun); + if (status !== 'True' || reason !== 'Succeeded') { + return false; + } + + const onErrorContinueStep = taskRun.status?.steps?.find( + step => + step.terminated?.reason === 'Completed' && step.terminated?.exitCode !== 0 + ); + return !!onErrorContinueStep; +} diff --git a/packages/utils/src/utils/index.test.js b/packages/utils/src/utils/index.test.js index b5288e435..73685a88e 100644 --- a/packages/utils/src/utils/index.test.js +++ b/packages/utils/src/utils/index.test.js @@ -34,6 +34,7 @@ import { getTaskRunsWithPlaceholders, getTaskSpecFromTaskRef, isRunning, + taskRunHasWarning, updateUnexecutedSteps } from '.'; @@ -850,3 +851,46 @@ describe('getTaskRunsWithPlaceholders', () => { expect(runs).toEqual([taskRun, finallyTaskRun]); }); }); + +describe('taskRunHasWarning', () => { + it('should return false for a TaskRun that has not completed', () => { + expect( + taskRunHasWarning({ + status: { + conditions: [ + { type: 'Succeeded', reason: 'Running', status: 'Unknown' } + ] + } + }) + ).toBe(false); + }); + + it('should return false for a TaskRun with steps that all completed with exit code 0', () => { + expect( + taskRunHasWarning({ + status: { + conditions: [ + { type: 'Succeeded', reason: 'Succeeded', status: 'True' } + ], + steps: [{ terminated: { exitCode: 0, reason: 'Completed' } }] + } + }) + ).toBe(false); + }); + + it('should return true for a successful TaskRun with at least one step that completed with non-zero exit code', () => { + expect( + taskRunHasWarning({ + status: { + conditions: [ + { type: 'Succeeded', reason: 'Succeeded', status: 'True' } + ], + steps: [ + { terminated: { exitCode: 1, reason: 'Completed' } }, + { terminated: { exitCode: 0, reason: 'Completed' } } + ] + } + }) + ).toBe(true); + }); +}); diff --git a/src/nls/messages_de.json b/src/nls/messages_de.json index 45d8831dc..465607efb 100644 --- a/src/nls/messages_de.json +++ b/src/nls/messages_de.json @@ -239,6 +239,7 @@ "dashboard.taskRun.status.pending": "Anstehend", "dashboard.taskRun.status.running": "Wird ausgeführt", "dashboard.taskRun.status.succeeded": "Abgeschlossen", + "dashboard.taskRun.status.succeeded.warning": "", "dashboard.taskRun.status.waiting": "Wartestatus", "dashboard.taskRun.unavailable": "", "dashboard.taskRunParams.name": "", diff --git a/src/nls/messages_en.json b/src/nls/messages_en.json index 1490f4b8f..cba865c52 100644 --- a/src/nls/messages_en.json +++ b/src/nls/messages_en.json @@ -239,6 +239,7 @@ "dashboard.taskRun.status.pending": "Pending", "dashboard.taskRun.status.running": "Running", "dashboard.taskRun.status.succeeded": "Completed", + "dashboard.taskRun.status.succeeded.warning": "Completed with exit code {exitCode}", "dashboard.taskRun.status.waiting": "Waiting", "dashboard.taskRun.unavailable": "TaskRun not available", "dashboard.taskRunParams.name": "Name", diff --git a/src/nls/messages_es.json b/src/nls/messages_es.json index 1afe1ce31..45b69e575 100644 --- a/src/nls/messages_es.json +++ b/src/nls/messages_es.json @@ -239,6 +239,7 @@ "dashboard.taskRun.status.pending": "Pendiente", "dashboard.taskRun.status.running": "En ejecución", "dashboard.taskRun.status.succeeded": "Completado", + "dashboard.taskRun.status.succeeded.warning": "", "dashboard.taskRun.status.waiting": "En espera", "dashboard.taskRun.unavailable": "", "dashboard.taskRunParams.name": "", diff --git a/src/nls/messages_fr.json b/src/nls/messages_fr.json index 570ab8d52..2b3b1b08f 100644 --- a/src/nls/messages_fr.json +++ b/src/nls/messages_fr.json @@ -239,6 +239,7 @@ "dashboard.taskRun.status.pending": "En attente", "dashboard.taskRun.status.running": "En cours d'exécution", "dashboard.taskRun.status.succeeded": "Terminé", + "dashboard.taskRun.status.succeeded.warning": "", "dashboard.taskRun.status.waiting": "En attente", "dashboard.taskRun.unavailable": "", "dashboard.taskRunParams.name": "", diff --git a/src/nls/messages_it.json b/src/nls/messages_it.json index a72127934..ff6b0d89e 100644 --- a/src/nls/messages_it.json +++ b/src/nls/messages_it.json @@ -239,6 +239,7 @@ "dashboard.taskRun.status.pending": "In attesa", "dashboard.taskRun.status.running": "In esecuzione", "dashboard.taskRun.status.succeeded": "Completato", + "dashboard.taskRun.status.succeeded.warning": "", "dashboard.taskRun.status.waiting": "In attesa", "dashboard.taskRun.unavailable": "", "dashboard.taskRunParams.name": "", diff --git a/src/nls/messages_ja.json b/src/nls/messages_ja.json index c73e9b82a..0ba3369be 100644 --- a/src/nls/messages_ja.json +++ b/src/nls/messages_ja.json @@ -239,6 +239,7 @@ "dashboard.taskRun.status.pending": "保留中", "dashboard.taskRun.status.running": "実行中", "dashboard.taskRun.status.succeeded": "完了", + "dashboard.taskRun.status.succeeded.warning": "", "dashboard.taskRun.status.waiting": "待機中", "dashboard.taskRun.unavailable": "TaskRunは使用できません", "dashboard.taskRunParams.name": "名前", diff --git a/src/nls/messages_ko.json b/src/nls/messages_ko.json index 59d4fcae0..71f2bc21b 100644 --- a/src/nls/messages_ko.json +++ b/src/nls/messages_ko.json @@ -239,6 +239,7 @@ "dashboard.taskRun.status.pending": "보류 중", "dashboard.taskRun.status.running": "실행 중", "dashboard.taskRun.status.succeeded": "완료됨", + "dashboard.taskRun.status.succeeded.warning": "", "dashboard.taskRun.status.waiting": "대기 중", "dashboard.taskRun.unavailable": "", "dashboard.taskRunParams.name": "", diff --git a/src/nls/messages_pt.json b/src/nls/messages_pt.json index 2f073a392..ccecc3b00 100644 --- a/src/nls/messages_pt.json +++ b/src/nls/messages_pt.json @@ -239,6 +239,7 @@ "dashboard.taskRun.status.pending": "Pendente", "dashboard.taskRun.status.running": "Executando", "dashboard.taskRun.status.succeeded": "Concluído", + "dashboard.taskRun.status.succeeded.warning": "", "dashboard.taskRun.status.waiting": "Aguardando", "dashboard.taskRun.unavailable": "", "dashboard.taskRunParams.name": "", diff --git a/src/nls/messages_zh-Hans.json b/src/nls/messages_zh-Hans.json index 87f777f3d..c577abaf9 100644 --- a/src/nls/messages_zh-Hans.json +++ b/src/nls/messages_zh-Hans.json @@ -239,6 +239,7 @@ "dashboard.taskRun.status.pending": "暂挂中", "dashboard.taskRun.status.running": "运行中", "dashboard.taskRun.status.succeeded": "已完成", + "dashboard.taskRun.status.succeeded.warning": "", "dashboard.taskRun.status.waiting": "等待中", "dashboard.taskRun.unavailable": "TaskRun 不可用", "dashboard.taskRunParams.name": "名称", diff --git a/src/nls/messages_zh-Hant.json b/src/nls/messages_zh-Hant.json index 0cc69a26c..2e60f18a8 100644 --- a/src/nls/messages_zh-Hant.json +++ b/src/nls/messages_zh-Hant.json @@ -239,6 +239,7 @@ "dashboard.taskRun.status.pending": "擱置中", "dashboard.taskRun.status.running": "執行中", "dashboard.taskRun.status.succeeded": "已完成", + "dashboard.taskRun.status.succeeded.warning": "", "dashboard.taskRun.status.waiting": "等待中", "dashboard.taskRun.unavailable": "", "dashboard.taskRunParams.name": "",