Skip to content

Commit

Permalink
Impl [Jobs] Add reason for job failure in UI next to the red status i…
Browse files Browse the repository at this point in the history
…ndicator `1.7.1` (#2821)
  • Loading branch information
illia-prokopchuk authored Nov 4, 2024
1 parent 4791bad commit f2b5d7a
Show file tree
Hide file tree
Showing 16 changed files with 77 additions and 47 deletions.
6 changes: 4 additions & 2 deletions src/common/ReactFlow/mlReactFlow.util.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import classnames from 'classnames'
import dagre from 'dagre'
import { Position } from 'reactflow'

import { ERROR_STATE, FAILED_STATE } from '../../constants'

export const getLayoutedElements = (nodes, edges, direction = 'TB') => {
const elWidth = 300
const elHeight = 80
Expand Down Expand Up @@ -181,9 +183,9 @@ export const getWorkflowSourceHandle = phase => {

const nodeStates = {
succeeded: 'Completed',
failed: 'Error',
[FAILED_STATE]: 'Error',
skipped: 'Skipped',
error: 'Error',
[ERROR_STATE]: 'Error',
running: 'Running',
omitted: 'Omitted'
}
6 changes: 3 additions & 3 deletions src/components/ArtifactsPreview/ArtifactsPreviewView.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import PreviewError from './PreviewError/PreviewError'
import { Tooltip, TextTooltipTemplate } from 'igz-controls/components'
import WarningMessage from '../../common/WarningMessage/WarningMessage'

import { ARTIFACT_PREVIEW_TABLE_ROW_LIMIT } from '../../constants'
import { ARTIFACT_PREVIEW_TABLE_ROW_LIMIT, ERROR_STATE } from '../../constants'

import './artifactsPreview.scss'

Expand All @@ -39,7 +39,7 @@ const ArtifactsPreviewView = ({ className, preview, setShowErrorBody, showErrorB
: [],
[preview.data]
)

return preview?.hidden ? (
<div className="artifact-preview__no-data">No preview</div>
) : (
Expand All @@ -54,7 +54,7 @@ const ArtifactsPreviewView = ({ className, preview, setShowErrorBody, showErrorB
</div>
)}
<div className={className}>
{preview?.type === 'error' ? (
{preview?.type === ERROR_STATE ? (
<PreviewError
error={preview.error}
setShowErrorBody={setShowErrorBody}
Expand Down
12 changes: 7 additions & 5 deletions src/components/FilterMenu/filterMenu.settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,29 +38,31 @@ import {
JOB_KIND_NUCLIO,
JOB_KIND_SERVING,
JOB_KIND_APPLICATION,
JOB_KIND_REMOTE
JOB_KIND_REMOTE,
ERROR_STATE,
FAILED_STATE
} from '../../constants'

export const jobsStatuses = [
{ label: 'All', id: FILTER_ALL_ITEMS, status: FILTER_ALL_ITEMS },
{ label: 'Aborted', id: 'aborted', status: 'aborted' },
{ label: 'Aborting', id: 'aborting', status: 'aborting' },
{ label: 'Completed', id: 'completed', status: 'completed' },
{ label: 'Error', id: 'error', status: 'error' },
{ label: 'Error', id: ERROR_STATE, status: ERROR_STATE },
{ label: 'Running', id: 'running', status: 'running' },
{ label: 'Pending', id: 'pending', status: 'pending' }
]

export const workflowsStatuses = [
{ label: 'All', id: FILTER_ALL_ITEMS, status: FILTER_ALL_ITEMS },
{ label: 'Error', id: 'error', status: 'error' },
{ label: 'Failed', id: 'failed', status: 'failed' },
{ label: 'Error', id: ERROR_STATE, status: ERROR_STATE },
{ label: 'Failed', id: FAILED_STATE, status: FAILED_STATE },
{ label: 'Running', id: 'running', status: 'running' },
{ label: 'Completed', id: 'completed', status: 'completed' }
]

export const generateStatusFilter = useFailedStatus => {
const status = useFailedStatus ? 'failed' : 'error'
const status = useFailedStatus ? FAILED_STATE : ERROR_STATE

return [
{ label: 'All', id: FILTER_ALL_ITEMS, status: FILTER_ALL_ITEMS },
Expand Down
8 changes: 4 additions & 4 deletions src/components/FunctionsPage/functions.util.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ import { debounce, get, isEmpty, isEqual } from 'lodash'
import {
DETAILS_BUILD_LOG_TAB,
FUNCTION_CREATING_STATE,
FUNCTION_ERROR_STATE,
FUNCTION_FAILED_STATE,
ERROR_STATE,
FUNCTION_INITIALIZED_STATE,
FUNCTION_PENDINDG_STATE,
FUNCTION_READY_STATE,
Expand All @@ -37,7 +36,8 @@ import {
FUNCTION_TYPE_REMOTE,
FUNCTION_TYPE_SERVING,
FUNCTIONS_PAGE,
PANEL_FUNCTION_CREATE_MODE
PANEL_FUNCTION_CREATE_MODE,
FAILED_STATE
} from '../../constants'
import jobsActions from '../../actions/jobs'
import functionsApi from '../../api/functions-api'
Expand Down Expand Up @@ -68,7 +68,7 @@ export const detailsMenu = [
label: 'build log'
}
]
export const FUNCTIONS_FAILED_STATES = [FUNCTION_FAILED_STATE, FUNCTION_ERROR_STATE]
export const FUNCTIONS_FAILED_STATES = [FAILED_STATE, ERROR_STATE]
export const FUNCTIONS_READY_STATES = [FUNCTION_READY_STATE]
export const FUNCTIONS_EDITABLE_STATES = [
FUNCTION_CREATING_STATE,
Expand Down
6 changes: 4 additions & 2 deletions src/components/Jobs/jobs.util.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ import {
JOB_KIND_REMOTE_SPARK,
SCHEDULE_TAB,
JOB_KIND_SPARK,
JOB_KIND_LOCAL
JOB_KIND_LOCAL,
ERROR_STATE,
FAILED_STATE
} from '../../constants'
import jobsActions from '../../actions/jobs'
import { generateKeyValues, truncateUid } from '../../utils'
Expand Down Expand Up @@ -78,7 +80,7 @@ export const getInfoHeaders = (isSpark, selectedJob) => {
}
export const actionsMenuHeader = 'Batch run'

export const JOB_STEADY_STATES = ['completed', 'error', 'aborted', 'failed']
export const JOB_STEADY_STATES = ['completed', ERROR_STATE, 'aborted', FAILED_STATE]
export const JOB_RUNNING_STATES = ['running', 'pending']

export const getJobsDetailsMenu = (jobLabels = []) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ such restriction.
import { getJobIdentifier } from '../../../utils/getUniqueIdentifier'
import { validateArguments } from '../../../utils/validateArguments'
import { generateLinkToDetailsPanel } from '../../../utils/link-helper.util'
import { JOB_KIND_WORKFLOW, JOBS_PAGE, MONITOR_JOBS_TAB } from '../../../constants'
import { ERROR_STATE, JOB_KIND_WORKFLOW, JOBS_PAGE, MONITOR_JOBS_TAB } from '../../../constants'
import measureTime from '../../../utils/measureTime'
import { formatDatetime } from '../../../utils'

Expand Down Expand Up @@ -104,7 +104,7 @@ export const createJobsMonitoringContent = (jobs, jobName, isStagingMode) => {
value: measureTime(
job.startTime || new Date(job.created_at),
(job.state?.value !== 'running' && job.updated) ||
(job.state?.value !== 'error' && new Date(job.finished_at))
(job.state?.value !== ERROR_STATE && new Date(job.finished_at))
),
className: 'table-cell-1',
type: 'duration'
Expand Down
6 changes: 4 additions & 2 deletions src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ export const CANCEL_REQUEST_TIMEOUT = 120000

export const PROJECT_ONLINE_STATUS = 'online'

export const ERROR_STATE = 'error'
export const FAIL_STATE = 'fail'
export const FAILED_STATE = 'failed'

/*=========== PAGES & TABS =============*/

export const PROJECTS_PAGE = 'PROJECTS'
Expand Down Expand Up @@ -311,9 +315,7 @@ export const SET_NEW_FUNCTION_TRACK_MODELS = 'SET_NEW_FUNCTION_TRACK_MODELS'
export const SET_NEW_FUNCTION_VOLUMES = 'SET_NEW_FUNCTION_VOLUMES'
export const SET_NEW_FUNCTION_VOLUME_MOUNTS = 'SET_NEW_FUNCTION_VOLUME_MOUNTS'
export const FUNCTION_CREATING_STATE = 'creating'
export const FUNCTION_FAILED_STATE = 'failed'
export const FUNCTION_FAILED_TO_DELETE_STATE = 'failedToDelete'
export const FUNCTION_ERROR_STATE = 'error'
export const FUNCTION_INITIALIZED_STATE = 'initialized'
export const FUNCTION_READY_STATE = 'ready'
export const FUNCTION_PENDINDG_STATE = 'pending'
Expand Down
6 changes: 4 additions & 2 deletions src/elements/FeatureValidator/featureValidatior.utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ under the Apache 2.0 license is conditioned upon your compliance with
such restriction.
*/

import { ERROR_STATE, FAIL_STATE } from '../../constants'

export const validatorStates = {
error: 'error',
[ERROR_STATE]: 'error',
info: 'info',
warn: 'warning',
warning: 'warning',
fail: 'fail'
[FAIL_STATE]: 'fail'
}
4 changes: 3 additions & 1 deletion src/elements/ProjectCard/projectCard.util.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ under the Apache 2.0 license is conditioned upon your compliance with
such restriction.
*/
import { isEmpty } from 'lodash'

import { groupByUniqName } from '../../utils/groupByUniqName'
import { ERROR_STATE } from '../../constants'

export const generateProjectStatistic = (
projectSummary = {},
Expand All @@ -34,7 +36,7 @@ export const generateProjectStatistic = (
0
)
const failedNuclioFunctions = Object.values(grouppedNuclioFunctions).reduce(
(prev, curr) => (curr.status.state === 'error' ? (prev += 1) : prev),
(prev, curr) => (curr.status.state === ERROR_STATE ? (prev += 1) : prev),
0
)

Expand Down
6 changes: 3 additions & 3 deletions src/elements/ProjectFunctions/ProjectFunctions.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import nuclioActions from '../../actions/nuclio'
import { groupByUniqName } from '../../utils/groupByUniqName'
import { useNuclioMode } from '../../hooks/nuclioMode.hook'
import { generateNuclioLink } from '../../utils'
import { REQUEST_CANCELED } from '../../constants'
import { ERROR_STATE, REQUEST_CANCELED } from '../../constants'

const ProjectFunctions = ({ fetchApiGateways, fetchNuclioFunctions, nuclioStore }) => {
const params = useParams()
Expand Down Expand Up @@ -71,7 +71,7 @@ const ProjectFunctions = ({ fetchApiGateways, fetchNuclioFunctions, nuclioStore
0
)
const functionsFailed = groupeFunctionsRunning.reduce(
(prev, curr) => (['error', 'unhealthy'].includes(curr.status.state) ? (prev += 1) : prev),
(prev, curr) => ([ERROR_STATE, 'unhealthy'].includes(curr.status.state) ? (prev += 1) : prev),
0
)

Expand Down Expand Up @@ -129,7 +129,7 @@ const ProjectFunctions = ({ fetchApiGateways, fetchNuclioFunctions, nuclioStore
? 'Running'
: func?.status?.state === 'ready' && func?.spec?.disable
? 'Standby'
: ['error', 'unhealthy', 'imported', 'scaledToZero'].includes(func?.status?.state)
: [ERROR_STATE, 'unhealthy', 'imported', 'scaledToZero'].includes(func?.status?.state)
? upperFirst(lowerCase(func.status.state))
: 'Building',
className: funcClassName
Expand Down
5 changes: 3 additions & 2 deletions src/elements/ProjectStatistics/ProjectStatistics.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
datePickerPastOptions,
PAST_24_HOUR_DATE_OPTION
} from '../../utils/datePicker.util'
import { ERROR_STATE, FAILED_STATE } from '../../constants'

import './projectStatistics.scss'

Expand All @@ -52,14 +53,14 @@ const ProjectStatistics = ({ statistics }) => {
initialSelectedOptionId: anyTimeOption.id
}
}
} else if (key === 'failed') {
} else if (key === FAILED_STATE) {
const past24HourOption = datePickerPastOptions.find(
option => option.id === PAST_24_HOUR_DATE_OPTION
)

filters = {
saveFilters: true,
state: 'error',
state: ERROR_STATE,
dates: {
value: past24HourOption.handler(),
isPredefined: past24HourOption.isPredefined,
Expand Down
6 changes: 4 additions & 2 deletions src/elements/WorkflowsTable/WorkflowsTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ import Workflow from '../../components/Workflow/Workflow'
import YamlModal from '../../common/YamlModal/YamlModal'

import {
ERROR_STATE,
FAILED_STATE,
JOB_KIND_JOB,
JOBS_PAGE,
MONITOR_JOBS_TAB,
Expand Down Expand Up @@ -253,7 +255,7 @@ const WorkflowsTable = React.forwardRef(
.then(job => {
const selectedJob = findSelectedWorkflowJob()
const graphJobState = selectedJob?.phase?.toLowerCase()
const isErrorState = ['failed', 'error'].includes(graphJobState)
const isErrorState = [FAILED_STATE, ERROR_STATE].includes(graphJobState)
const customJobState = isErrorState ? graphJobState : ''

return modifyAndSelectRun(parseJob(
Expand Down Expand Up @@ -471,7 +473,7 @@ const WorkflowsTable = React.forwardRef(
if (isWorkflowStepExecutable(functionToBeSelected)) {
const workflow = { ...workflowsStore.activeWorkflow?.data }
const graphFunctionState = functionToBeSelected?.phase?.toLowerCase()
const isErrorState = ['failed', 'error'].includes(graphFunctionState)
const isErrorState = [FAILED_STATE, ERROR_STATE].includes(graphFunctionState)
const customFunctionState = isErrorState ? graphFunctionState : ''
const pipelineError = getPipelineError(isErrorState)

Expand Down
11 changes: 6 additions & 5 deletions src/utils/createJobsContent.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ such restriction.
*/

import {
ERROR_STATE,
JOB_KIND_WORKFLOW,
JOBS_MONITORING_JOBS_TAB,
JOBS_MONITORING_PAGE,
Expand Down Expand Up @@ -104,7 +105,7 @@ export const createJobsMonitorTabContent = (jobs, jobName, isStagingMode) => {
value: measureTime(
job.startTime || new Date(job.created_at),
(job.state?.value !== 'running' && job.updated) ||
(job.state?.value !== 'error' && new Date(job.finished_at))
(job.state?.value !== ERROR_STATE && new Date(job.finished_at))
),
className: 'table-cell-1',
type: 'duration'
Expand Down Expand Up @@ -302,7 +303,7 @@ export const createJobsWorkflowsTabContent = (jobs, projectName, isStagingMode,
value: measureTime(
job.startTime || new Date(job.created_at),
(job.state?.value !== 'running' && job.updated) ||
(job.state?.value !== 'error' && new Date(job.finished_at))
(job.state?.value !== ERROR_STATE && new Date(job.finished_at))
),
className: 'table-cell-1',
type: 'duration',
Expand Down Expand Up @@ -403,7 +404,7 @@ export const createJobsWorkflowContent = (
id: `duration.${identifierUnique}`,
value: measureTime(
new Date(job.startedAt),
job.state?.value !== 'error' && new Date(job.finishedAt)
job.state?.value !== ERROR_STATE && new Date(job.finishedAt)
),
className: 'table-cell-1',
type: 'duration',
Expand Down Expand Up @@ -487,7 +488,7 @@ export const createJobsMonitoringContent = (jobs, jobName, isStagingMode) => {
value: measureTime(
job.startTime || new Date(job.created_at),
(job.state?.value !== 'running' && job.updated) ||
(job.state?.value !== 'error' && new Date(job.finished_at))
(job.state?.value !== ERROR_STATE && new Date(job.finished_at))
),
className: 'table-cell-1',
type: 'duration'
Expand Down Expand Up @@ -691,7 +692,7 @@ export const createWorkflowsMonitoringContent = (jobs, isStagingMode, isSelected
value: measureTime(
job.startTime || new Date(job.created_at),
(job.state?.value !== 'running' && job.updated) ||
(job.state?.value !== 'error' && new Date(job.finished_at))
(job.state?.value !== ERROR_STATE && new Date(job.finished_at))
),
className: 'table-cell-1',
type: 'duration',
Expand Down
8 changes: 5 additions & 3 deletions src/utils/generateMonitoringData.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ import {
JOB_KIND_JOB,
JOB_KIND_WORKFLOW,
STATUS_FILTER,
TYPE_FILTER
TYPE_FILTER,
ERROR_STATE,
FAILED_STATE
} from '../constants'
import {
ANY_TIME_DATE_OPTION,
Expand Down Expand Up @@ -68,7 +70,7 @@ export const generateMonitoringStats = (data, navigate, dispatch, tab) => {
},
{
counter: data.failed,
link: () => navigateToJobsMonitoringPage({ [STATUS_FILTER]: ['error', 'aborted'] }),
link: () => navigateToJobsMonitoringPage({ [STATUS_FILTER]: [ERROR_STATE, 'aborted'] }),
statusClass: 'failed',
tooltip: 'Aborted, Error'
},
Expand Down Expand Up @@ -104,7 +106,7 @@ export const generateMonitoringStats = (data, navigate, dispatch, tab) => {
},
{
counter: data.failed,
link: () => navigateToJobsMonitoringPage({ [STATUS_FILTER]: ['error', 'failed'] }),
link: () => navigateToJobsMonitoringPage({ [STATUS_FILTER]: [ERROR_STATE, FAILED_STATE] }),
statusClass: 'failed',
tooltip: 'Error, Failed'
},
Expand Down
Loading

0 comments on commit f2b5d7a

Please sign in to comment.