From 453204978b7ad74fa6b3d32817c30c5d95cfcdc4 Mon Sep 17 00:00:00 2001 From: Dipanshu Gupta Date: Thu, 27 Jun 2024 19:00:31 +0530 Subject: [PATCH] Rename job to recurring runs --- frontend/src/__mocks__/index.ts | 2 +- .../{mockJobKF.ts => mockRecurringRunKF.ts} | 12 +- .../cypress/pages/pipelines/cloneRunPage.ts | 4 +- .../cypress/pages/pipelines/createRunPage.ts | 9 +- .../cypress/pages/pipelines/manageRuns.ts | 2 +- .../pages/pipelines/pipelineRunTable.ts | 34 ++--- .../cypress/pages/pipelines/topology.ts | 8 +- .../cypress/cypress/support/commands/odh.ts | 10 +- .../tests/mocked/pipelines/experiments.cy.ts | 8 +- .../mocked/pipelines/pipelineCreateRuns.cy.ts | 38 +++--- .../mocked/pipelines/pipelineDeleteRuns.cy.ts | 43 +++--- .../tests/mocked/pipelines/pipelineRuns.cy.ts | 124 +++++++++--------- .../mocked/pipelines/pipelinesTopology.cy.ts | 101 ++++++++------ .../api/pipelines/__tests__/custom.spec.ts | 62 +++++---- frontend/src/api/pipelines/callTypes.ts | 20 +-- frontend/src/api/pipelines/custom.ts | 105 ++++++++------- .../apiHooks/usePipelineRecurringRunById.ts | 29 ++++ ...RunJobs.ts => usePipelineRecurringRuns.ts} | 12 +- .../apiHooks/usePipelineRunJobById.ts | 29 ---- .../content/DeletePipelineRunsModal.tsx | 6 +- .../content/PipelineJobReferenceName.tsx | 32 ----- .../PipelineRecurringRunReferenceName.tsx | 32 +++++ .../content/PipelineRunTypeLabel.tsx | 4 +- .../pipelines/content/createRun/RunPage.tsx | 4 +- .../content/createRun/RunPageFooter.tsx | 4 +- .../content/createRun/submitUtils.ts | 18 +-- .../content/createRun/useCloneRunData.ts | 13 +- .../content/createRun/useRunFormData.ts | 10 +- .../pipelinesDetails/PipelineDetailsTitle.tsx | 4 +- .../PipelineRecurringRunDetails.tsx} | 41 +++--- .../PipelineRecurringRunDetailsActions.tsx} | 18 +-- .../pipelineRun/PipelineRunDetails.tsx | 4 +- .../pipelineRun/PipelineRunDetailsTabs.tsx | 10 +- .../pipelineRun/PipelineRunTabDetails.tsx | 12 +- .../pipelines/content/tables/columns.ts | 4 +- .../PipelineRecurringRunTable.tsx} | 52 ++++---- .../PipelineRecurringRunTableRow.tsx} | 54 ++++---- .../PipelineRecurringRunTableToolbar.tsx} | 8 +- .../usePipelineRecurringRunTable.ts | 10 ++ .../pipelineRun/PipelineRunTableRowTitle.tsx | 4 +- .../pipelineRunJob/usePipelineRunJobTable.ts | 10 -- .../pipelines/content/tables/renderUtils.tsx | 39 +++--- .../tables/usePipelineRunVersionInfo.ts | 4 +- .../pipelines/content/tables/utils.ts | 27 ++-- .../src/concepts/pipelines/content/utils.tsx | 7 +- .../pipelines/context/PipelinesContext.tsx | 20 +-- .../context/useJobRelatedInformation.ts | 64 --------- .../pipelines/context/usePipelineAPIState.ts | 20 +-- .../useRecurringRunRelatedInformation.ts | 63 +++++++++ frontend/src/concepts/pipelines/kfTypes.ts | 12 +- frontend/src/concepts/pipelines/types.ts | 41 +++--- frontend/src/concepts/pipelines/utils.ts | 6 +- .../GlobalPipelineExperimentsRoutes.tsx | 4 +- .../pipelines/GlobalPipelineRunsRoutes.tsx | 12 +- .../pages/pipelines/GlobalPipelinesRoutes.tsx | 12 +- .../pipelines/global/runs/ScheduledRuns.tsx | 14 +- .../src/pages/projects/ProjectViewRoutes.tsx | 10 +- .../trainModels/PipelinesCardMetrics.tsx | 10 +- frontend/src/routes/pipelines/global.ts | 49 ++++--- frontend/src/routes/pipelines/runs.ts | 8 +- 60 files changed, 767 insertions(+), 661 deletions(-) rename frontend/src/__mocks__/{mockJobKF.ts => mockRecurringRunKF.ts} (77%) create mode 100644 frontend/src/concepts/pipelines/apiHooks/usePipelineRecurringRunById.ts rename frontend/src/concepts/pipelines/apiHooks/{usePipelineRunJobs.ts => usePipelineRecurringRuns.ts} (73%) delete mode 100644 frontend/src/concepts/pipelines/apiHooks/usePipelineRunJobById.ts delete mode 100644 frontend/src/concepts/pipelines/content/PipelineJobReferenceName.tsx create mode 100644 frontend/src/concepts/pipelines/content/PipelineRecurringRunReferenceName.tsx rename frontend/src/concepts/pipelines/content/pipelinesDetails/{pipelineRunJob/PipelineRunJobDetails.tsx => pipelineRecurringRun/PipelineRecurringRunDetails.tsx} (79%) rename frontend/src/concepts/pipelines/content/pipelinesDetails/{pipelineRunJob/PipelineRunJobDetailsActions.tsx => pipelineRecurringRun/PipelineRecurringRunDetailsActions.tsx} (80%) rename frontend/src/concepts/pipelines/content/tables/{pipelineRunJob/PipelineRunJobTable.tsx => pipelineRecurringRun/PipelineRecurringRunTable.tsx} (68%) rename frontend/src/concepts/pipelines/content/tables/{pipelineRunJob/PipelineRunJobTableRow.tsx => pipelineRecurringRun/PipelineRecurringRunTableRow.tsx} (71%) rename frontend/src/concepts/pipelines/content/tables/{pipelineRunJob/PipelineRunJobTableToolbar.tsx => pipelineRecurringRun/PipelineRecurringRunTableToolbar.tsx} (87%) create mode 100644 frontend/src/concepts/pipelines/content/tables/pipelineRecurringRun/usePipelineRecurringRunTable.ts delete mode 100644 frontend/src/concepts/pipelines/content/tables/pipelineRunJob/usePipelineRunJobTable.ts delete mode 100644 frontend/src/concepts/pipelines/context/useJobRelatedInformation.ts create mode 100644 frontend/src/concepts/pipelines/context/useRecurringRunRelatedInformation.ts diff --git a/frontend/src/__mocks__/index.ts b/frontend/src/__mocks__/index.ts index 755152967c..37611da8a9 100644 --- a/frontend/src/__mocks__/index.ts +++ b/frontend/src/__mocks__/index.ts @@ -5,7 +5,7 @@ export * from './mockProjectK8sResource'; export * from './mockRouteK8sResource'; export * from './mockStatus'; export * from './mockRunKF'; -export * from './mockJobKF'; +export * from './mockRecurringRunKF'; export * from './mockExperimentKF'; export * from './mockPipelineVersionsProxy'; export * from './mockPipelinesProxy'; diff --git a/frontend/src/__mocks__/mockJobKF.ts b/frontend/src/__mocks__/mockRecurringRunKF.ts similarity index 77% rename from frontend/src/__mocks__/mockJobKF.ts rename to frontend/src/__mocks__/mockRecurringRunKF.ts index 20b9448314..96a3528145 100644 --- a/frontend/src/__mocks__/mockJobKF.ts +++ b/frontend/src/__mocks__/mockRecurringRunKF.ts @@ -1,13 +1,15 @@ /* eslint-disable camelcase */ import { - PipelineRunJobKFv2, + PipelineRecurringRunKFv2, RecurringRunMode, RecurringRunStatus, } from '~/concepts/pipelines/kfTypes'; -export const buildMockJobKF = (job?: Partial): PipelineRunJobKFv2 => ({ - recurring_run_id: 'test-job', - display_name: 'Test job', +export const buildMockRecurringRunKF = ( + recurringRun?: Partial, +): PipelineRecurringRunKFv2 => ({ + recurring_run_id: 'test-recurring-run', + display_name: 'Test recurring run', pipeline_version_reference: { pipeline_id: '3195ec84-69d1-4c10-b8ac-6e2334319444', pipeline_version_id: '29d12191-3a34-4e2a-b05f-6224b6fa7de8', @@ -34,5 +36,5 @@ export const buildMockJobKF = (job?: Partial): PipelineRunJo status: RecurringRunStatus.ENABLED, namespace: 'jps-fun-world', experiment_id: 'f1353050-6b31-424d-859e-1fd95feb2cb8', - ...job, + ...recurringRun, }); diff --git a/frontend/src/__tests__/cypress/cypress/pages/pipelines/cloneRunPage.ts b/frontend/src/__tests__/cypress/cypress/pages/pipelines/cloneRunPage.ts index fe42d9132d..d16290828e 100644 --- a/frontend/src/__tests__/cypress/cypress/pages/pipelines/cloneRunPage.ts +++ b/frontend/src/__tests__/cypress/cypress/pages/pipelines/cloneRunPage.ts @@ -1,7 +1,7 @@ import type { ExperimentKFv2, PipelineKFv2, - PipelineRunJobKFv2, + PipelineRecurringRunKFv2, PipelineRunKFv2, PipelineVersionKFv2, } from '~/concepts/pipelines/kfTypes'; @@ -24,7 +24,7 @@ class CloneRunPage extends CreateRunPage { ); } - mockGetRecurringRun(namespace: string, recurringRun: PipelineRunJobKFv2) { + mockGetRecurringRun(namespace: string, recurringRun: PipelineRecurringRunKFv2) { return cy.interceptOdh( 'GET /api/service/pipelines/:namespace/:serviceName/apis/v2beta1/recurringruns/:recurringRunId', { path: { namespace, serviceName: 'dspa', recurringRunId: recurringRun.recurring_run_id } }, diff --git a/frontend/src/__tests__/cypress/cypress/pages/pipelines/createRunPage.ts b/frontend/src/__tests__/cypress/cypress/pages/pipelines/createRunPage.ts index 91959e0071..f8ab655e83 100644 --- a/frontend/src/__tests__/cypress/cypress/pages/pipelines/createRunPage.ts +++ b/frontend/src/__tests__/cypress/cypress/pages/pipelines/createRunPage.ts @@ -2,14 +2,15 @@ import type { ExperimentKFv2, PipelineKFv2, - PipelineRunJobKFv2, + PipelineRecurringRunKFv2, PipelineRunKFv2, PipelineVersionKFv2, } from '~/concepts/pipelines/kfTypes'; -import { buildMockExperiments, buildMockJobKF, buildMockRunKF } from '~/__mocks__'; +import { buildMockExperiments, buildMockRunKF } from '~/__mocks__'; import { buildMockPipelines } from '~/__mocks__/mockPipelinesProxy'; import { buildMockPipelineVersionsV2 } from '~/__mocks__/mockPipelineVersionsProxy'; import { Contextual } from '~/__tests__/cypress/cypress/pages/components/Contextual'; +import { buildMockRecurringRunKF } from '~/__mocks__/mockRecurringRunKF'; class ParamsSection extends Contextual { findParamById(id: string): Cypress.Chainable> { @@ -222,7 +223,7 @@ export class CreateRunPage { mockCreateRecurringRun( namespace: string, pipelineVersion: PipelineVersionKFv2, - { recurring_run_id, ...recurringRun }: Partial, + { recurring_run_id, ...recurringRun }: Partial, ): Cypress.Chainable { return cy.interceptOdh( 'POST /api/service/pipelines/:namespace/:serviceName/apis/v2beta1/recurringruns', @@ -242,7 +243,7 @@ export class CreateRunPage { expect(JSON.stringify(req.body.runtime_config)).to.equal( JSON.stringify(recurringRun.runtime_config), ); - req.reply(buildMockJobKF({ ...data, recurring_run_id })); + req.reply(buildMockRecurringRunKF({ ...data, recurring_run_id })); }, ); } diff --git a/frontend/src/__tests__/cypress/cypress/pages/pipelines/manageRuns.ts b/frontend/src/__tests__/cypress/cypress/pages/pipelines/manageRuns.ts index cd9cbf92ef..684784a6a3 100644 --- a/frontend/src/__tests__/cypress/cypress/pages/pipelines/manageRuns.ts +++ b/frontend/src/__tests__/cypress/cypress/pages/pipelines/manageRuns.ts @@ -38,7 +38,7 @@ class ManageRunsRow extends TableRow { } findStatusSwitchByRowName() { - return this.find().findByTestId('job-status-switch'); + return this.find().findByTestId('recurring-run-status-switch'); } } diff --git a/frontend/src/__tests__/cypress/cypress/pages/pipelines/pipelineRunTable.ts b/frontend/src/__tests__/cypress/cypress/pages/pipelines/pipelineRunTable.ts index 2fccde0fdc..0373f8e187 100644 --- a/frontend/src/__tests__/cypress/cypress/pages/pipelines/pipelineRunTable.ts +++ b/frontend/src/__tests__/cypress/cypress/pages/pipelines/pipelineRunTable.ts @@ -1,5 +1,5 @@ /* eslint-disable camelcase */ -import type { PipelineRunJobKFv2, PipelineRunKFv2 } from '~/concepts/pipelines/kfTypes'; +import type { PipelineRecurringRunKFv2, PipelineRunKFv2 } from '~/concepts/pipelines/kfTypes'; import { TableRow } from '~/__tests__/cypress/cypress/pages/components/table'; class PipelineRunsRow extends TableRow { @@ -19,9 +19,9 @@ class PipelineRunTableRow extends PipelineRunsRow { } } -class PipelineRunJobTableRow extends PipelineRunsRow { +class PipelineRecurringRunTableRow extends PipelineRunsRow { findStatusSwitchByRowName() { - return this.find().findByTestId('job-status-switch'); + return this.find().findByTestId('recurring-run-status-switch'); } } @@ -143,13 +143,13 @@ class ArchivedRunsTable extends PipelineRunsTable { } } -class PipelineRunJobTable extends PipelineRunsTable { +class PipelineRecurringRunTable extends PipelineRunsTable { constructor() { super('schedules'); } getRowByName(name: string) { - return new PipelineRunJobTableRow(() => + return new PipelineRecurringRunTableRow(() => this.find().find(`[data-label=Name]`).contains(name).parents('tr'), ); } @@ -173,41 +173,45 @@ class PipelineRunJobTable extends PipelineRunsTable { return cy.findByTestId('experiment-search-select'); } - mockGetJobs(jobs: PipelineRunJobKFv2[], namespace: string) { + mockGetRecurringRuns(recurringRuns: PipelineRecurringRunKFv2[], namespace: string) { return cy.interceptOdh( 'GET /api/service/pipelines/:namespace/:serviceName/apis/v2beta1/recurringruns', { path: { namespace, serviceName: 'dspa' } }, - { recurringRuns: jobs, total_size: jobs.length }, + { recurringRuns, total_size: recurringRuns.length }, ); } - mockGetJob(job: PipelineRunJobKFv2, namespace: string) { + mockGetRecurringRun(recurringRun: PipelineRecurringRunKFv2, namespace: string) { return cy.interceptOdh( 'GET /api/service/pipelines/:namespace/:serviceName/apis/v2beta1/recurringruns/:recurringRunId', - { path: { namespace, serviceName: 'dspa', recurringRunId: job.recurring_run_id } }, - job, + { path: { namespace, serviceName: 'dspa', recurringRunId: recurringRun.recurring_run_id } }, + recurringRun, ); } - mockEnableJob(job: PipelineRunJobKFv2, namespace: string) { + mockEnableRecurringRun(recurringRun: PipelineRecurringRunKFv2, namespace: string) { return cy.interceptOdh( 'POST /api/service/pipelines/:namespace/:serviceName/apis/v2beta1/recurringruns/:recurringRunId', { path: { namespace, serviceName: 'dspa', - recurringRunId: `${job.recurring_run_id}:'enable'`, + recurringRunId: `${recurringRun.recurring_run_id}:'enable'`, }, }, {}, ); } - mockDisableJob(job: PipelineRunJobKFv2, namespace: string) { + mockDisableRecurringRun(recurringRun: PipelineRecurringRunKFv2, namespace: string) { return cy.interceptOdh( 'POST /api/service/pipelines/:namespace/:serviceName/apis/v2beta1/recurringruns/:recurringRunId', { - path: { namespace, serviceName: 'dspa', recurringRunId: `${job.recurring_run_id}:disable` }, + path: { + namespace, + serviceName: 'dspa', + recurringRunId: `${recurringRun.recurring_run_id}:disable`, + }, }, {}, ); @@ -216,4 +220,4 @@ class PipelineRunJobTable extends PipelineRunsTable { export const activeRunsTable = new ActiveRunsTable(); export const archivedRunsTable = new ArchivedRunsTable(); -export const pipelineRunJobTable = new PipelineRunJobTable(); +export const pipelineRecurringRunTable = new PipelineRecurringRunTable(); diff --git a/frontend/src/__tests__/cypress/cypress/pages/pipelines/topology.ts b/frontend/src/__tests__/cypress/cypress/pages/pipelines/topology.ts index 3401eb352a..05c454818b 100644 --- a/frontend/src/__tests__/cypress/cypress/pages/pipelines/topology.ts +++ b/frontend/src/__tests__/cypress/cypress/pages/pipelines/topology.ts @@ -179,14 +179,14 @@ class PipelineDetails extends PipelinesTopology { } } -class PipelineRunJobDetails extends RunDetails { +class PipelineRecurringRunDetails extends RunDetails { visit(namespace: string, pipelineId: string) { - cy.visitWithLogin(`/pipelines/${namespace}/pipelineRunJob/view/${pipelineId}`); + cy.visitWithLogin(`/pipelines/${namespace}/pipelineRecurringRun/view/${pipelineId}`); this.wait(); } findActionsDropdown() { - return cy.findByTestId('pipeline-run-job-details-actions'); + return cy.findByTestId('pipeline-recurring-run-details-actions'); } selectActionDropdownItem(label: string) { @@ -259,5 +259,5 @@ class PipelineRunDetails extends RunDetails { export const pipelineDetails = new PipelineDetails(); export const pipelineRunDetails = new PipelineRunDetails(); -export const pipelineRunJobDetails = new PipelineRunJobDetails(); +export const pipelineRecurringRunDetails = new PipelineRecurringRunDetails(); export const pipelinesTopology = new PipelinesTopology(); diff --git a/frontend/src/__tests__/cypress/cypress/support/commands/odh.ts b/frontend/src/__tests__/cypress/cypress/support/commands/odh.ts index 2adc0ac576..e1637fb50c 100644 --- a/frontend/src/__tests__/cypress/cypress/support/commands/odh.ts +++ b/frontend/src/__tests__/cypress/cypress/support/commands/odh.ts @@ -37,12 +37,12 @@ import type { ExperimentKFv2, GoogleRpcStatusKF, ListExperimentsResponseKF, - ListPipelineRunJobsResourceKF, + ListPipelineRecurringRunsResourceKF, ListPipelineRunsResourceKF, ListPipelineVersionsKF, ListPipelinesResponseKF, PipelineKFv2, - PipelineRunJobKFv2, + PipelineRecurringRunKFv2, PipelineRunKFv2, PipelineVersionKFv2, } from '~/concepts/pipelines/kfTypes'; @@ -403,7 +403,7 @@ declare global { (( type: `GET /api/service/pipelines/:namespace/:serviceName/apis/v2beta1/recurringruns/:recurringRunId`, options: { path: { namespace: string; serviceName: string; recurringRunId: string } }, - response: OdhResponse, + response: OdhResponse, ) => Cypress.Chainable) & (( type: `DELETE /api/service/pipelines/:namespace/:serviceName/apis/v2beta1/recurringruns/:recurringRunId`, @@ -463,12 +463,12 @@ declare global { (( type: `POST /api/service/pipelines/:namespace/:serviceName/apis/v2beta1/recurringruns`, options: { path: { namespace: string; serviceName: string }; times?: number }, - response: OdhResponse, + response: OdhResponse, ) => Cypress.Chainable) & (( type: `GET /api/service/pipelines/:namespace/:serviceName/apis/v2beta1/recurringruns`, options: { path: { namespace: string; serviceName: string } }, - response: OdhResponse, + response: OdhResponse, ) => Cypress.Chainable) & (( type: `POST /api/service/mlmd/:namespace/:serviceName/ml_metadata.MetadataStoreService/GetArtifactTypes`, diff --git a/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/experiments.cy.ts b/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/experiments.cy.ts index 869e8f9172..0eeb8848bd 100644 --- a/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/experiments.cy.ts +++ b/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/experiments.cy.ts @@ -9,14 +9,14 @@ import { mockProjectK8sResource, mockRouteK8sResource, buildMockRunKF, - buildMockJobKF, + buildMockRecurringRunKF, } from '~/__mocks__'; import { archivedRunsTable, archiveExperimentModal, bulkArchiveExperimentModal, bulkRestoreExperimentModal, - pipelineRunJobTable, + pipelineRecurringRunTable, pipelineRunsGlobal, restoreExperimentModal, } from '~/__tests__/cypress/cypress/pages/pipelines'; @@ -301,7 +301,7 @@ describe('Runs page for archived experiment', () => { { path: { namespace: projectName, serviceName: 'dspa' }, }, - { recurringRuns: [buildMockJobKF({ status: RecurringRunStatus.DISABLED })] }, + { recurringRuns: [buildMockRecurringRunKF({ status: RecurringRunStatus.DISABLED })] }, ); experimentsTabs.mockGetExperiments(projectName, [], mockExperiments); experimentsTabs.visit(projectName); @@ -327,7 +327,7 @@ describe('Runs page for archived experiment', () => { it('has no create schedule button on schedules tab', () => { pipelineRunsGlobal.findSchedulesTab().click(); - pipelineRunJobTable.getRowByName('Test job').findCheckbox().click(); + pipelineRecurringRunTable.getRowByName('Test recurring run').findCheckbox().click(); pipelineRunsGlobal.findScheduleRunButton().should('not.exist'); }); }); diff --git a/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/pipelineCreateRuns.cy.ts b/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/pipelineCreateRuns.cy.ts index 9658629000..713e81157f 100644 --- a/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/pipelineCreateRuns.cy.ts +++ b/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/pipelineCreateRuns.cy.ts @@ -1,17 +1,17 @@ /* eslint-disable camelcase */ -import type { PipelineRunJobKFv2, PipelineRunKFv2 } from '~/concepts/pipelines/kfTypes'; +import type { PipelineRecurringRunKFv2, PipelineRunKFv2 } from '~/concepts/pipelines/kfTypes'; import { InputDefinitionParameterType } from '~/concepts/pipelines/kfTypes'; import { buildMockRunKF, buildMockPipelineV2, buildMockPipelineVersionV2, - buildMockJobKF, + buildMockRecurringRunKF, buildMockExperimentKF, } from '~/__mocks__'; import { createRunPage, cloneRunPage, - pipelineRunJobTable, + pipelineRecurringRunTable, pipelineRunsGlobal, activeRunsTable, createSchedulePage, @@ -45,7 +45,7 @@ const initialMockRuns = [ }), ]; const initialMockRecurringRuns = [ - buildMockJobKF({ + buildMockRecurringRunKF({ pipeline_version_reference: pipelineVersionRef, experiment_id: 'experiment-1', }), @@ -67,7 +67,7 @@ describe('Pipeline create runs', () => { visitLegacyRunsPage(); pipelineRunsGlobal.findSchedulesTab().click(); - pipelineRunJobTable.getRowByName('Test job').find().should('exist'); + pipelineRecurringRunTable.getRowByName('Test recurring run').find().should('exist'); pipelineRunsGlobal.findActiveRunsTab().click(); activeRunsTable.getRowByName('Test run').find().should('exist'); @@ -512,10 +512,10 @@ describe('Pipeline create runs', () => { visitLegacyRunsPage(); pipelineRunsGlobal.findSchedulesTab().click(); - const createRecurringRunParams: Partial = { - display_name: 'New job', - description: 'New job description', - recurring_run_id: 'new-job-id', + const createRecurringRunParams: Partial = { + display_name: 'New recurring run', + description: 'New recurring run description', + recurring_run_id: 'new-recurring-run-id', runtime_config: { parameters: { min_max_scaler: false, @@ -540,8 +540,8 @@ describe('Pipeline create runs', () => { createSchedulePage.find(); // Fill out the form with a schedule and submit - createSchedulePage.fillName('New job'); - createSchedulePage.fillDescription('New job description'); + createSchedulePage.fillName('New recurring run'); + createSchedulePage.fillDescription('New recurring run description'); createSchedulePage.findExperimentSelect().should('not.be.disabled').click(); createSchedulePage.selectExperimentByName('Test experiment 1'); createSchedulePage.findPipelineSelect().should('not.be.disabled').click(); @@ -560,8 +560,8 @@ describe('Pipeline create runs', () => { cy.wait('@createSchedule').then((interception) => { expect(interception.request.body).to.eql({ - display_name: 'New job', - description: 'New job description', + display_name: 'New recurring run', + description: 'New recurring run description', pipeline_version_reference: { pipeline_id: 'test-pipeline', pipeline_version_id: 'test-pipeline-version', @@ -580,16 +580,16 @@ describe('Pipeline create runs', () => { // Should be redirected to the schedule details page verifyRelativeURL( - `/pipelines/${projectName}/pipelineRunJob/view/${createRecurringRunParams.recurring_run_id}`, + `/pipelines/${projectName}/pipelineRecurringRun/view/${createRecurringRunParams.recurring_run_id}`, ); }); it('duplicates a schedule', () => { const [mockRecurringRun] = initialMockRecurringRuns; const mockExperiment = mockExperiments[0]; - const mockDuplicateRecurringRun = buildMockJobKF({ - display_name: 'Duplicate of Test job', - recurring_run_id: 'duplicate-job-id', + const mockDuplicateRecurringRun = buildMockRecurringRunKF({ + display_name: 'Duplicate of Test recurring run', + recurring_run_id: 'duplicate-recurring-run-id', experiment_id: mockExperiment.experiment_id, }); @@ -609,7 +609,7 @@ describe('Pipeline create runs', () => { // Navigate to clone run page for a given schedule cy.visitWithLogin(`/experiments/${projectName}/experiment-1/runs`); pipelineRunsGlobal.findSchedulesTab().click(); - pipelineRunJobTable + pipelineRecurringRunTable .getRowByName(mockRecurringRun.display_name) .findKebabAction('Duplicate') .click(); @@ -634,7 +634,7 @@ describe('Pipeline create runs', () => { cy.wait('@duplicateSchedule').then((interception) => { expect(interception.request.body).to.eql({ - display_name: 'Duplicate of Test job', + display_name: 'Duplicate of Test recurring run', description: '', pipeline_version_reference: { pipeline_id: 'test-pipeline', diff --git a/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/pipelineDeleteRuns.cy.ts b/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/pipelineDeleteRuns.cy.ts index 707de865e3..7f3b6ffe27 100644 --- a/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/pipelineDeleteRuns.cy.ts +++ b/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/pipelineDeleteRuns.cy.ts @@ -3,13 +3,12 @@ import { mockDataSciencePipelineApplicationK8sResource } from '~/__mocks__/mockD import { mockDscStatus } from '~/__mocks__/mockDscStatus'; import { mockK8sResourceList } from '~/__mocks__/mockK8sResourceList'; import { mockNotebookK8sResource } from '~/__mocks__/mockNotebookK8sResource'; -import { buildMockJobKF } from '~/__mocks__/mockJobKF'; import { mockProjectK8sResource } from '~/__mocks__/mockProjectK8sResource'; import { mockRouteK8sResource } from '~/__mocks__/mockRouteK8sResource'; import { mockSecretK8sResource } from '~/__mocks__/mockSecretK8sResource'; import { buildMockRunKF } from '~/__mocks__/mockRunKF'; import { - pipelineRunJobTable, + pipelineRecurringRunTable, pipelineRunsGlobal, archivedRunsTable, runsDeleteModal, @@ -24,6 +23,7 @@ import { } from '~/__tests__/cypress/cypress/utils/models'; import { mockSuccessGoogleRpcStatus } from '~/__mocks__/mockGoogleRpcStatusKF'; import { buildMockPipelineVersionV2 } from '~/__mocks__'; +import { buildMockRecurringRunKF } from '~/__mocks__/mockRecurringRunKF'; const initIntercepts = () => { cy.interceptOdh( @@ -40,8 +40,14 @@ const initIntercepts = () => { }, { recurringRuns: [ - buildMockJobKF({ display_name: 'test-pipeline', recurring_run_id: 'test-pipeline' }), - buildMockJobKF({ display_name: 'other-pipeline', recurring_run_id: 'other-pipeline' }), + buildMockRecurringRunKF({ + display_name: 'test-pipeline', + recurring_run_id: 'test-pipeline', + }), + buildMockRecurringRunKF({ + display_name: 'other-pipeline', + recurring_run_id: 'other-pipeline', + }), ], }, ); @@ -98,7 +104,7 @@ describe('Pipeline runs', () => { pipelineRunsGlobal.isApiAvailable(); pipelineRunsGlobal.findSchedulesTab().click(); - pipelineRunJobTable.getRowByName('test-pipeline').findKebabAction('Delete').click(); + pipelineRecurringRunTable.getRowByName('test-pipeline').findKebabAction('Delete').click(); schedulesDeleteModal.shouldBeOpen(); schedulesDeleteModal.findSubmitButton().should('be.disabled'); @@ -110,7 +116,7 @@ describe('Pipeline runs', () => { path: { namespace: 'test-project', serviceName: 'dspa', recurringRunId: 'test-pipeline' }, }, mockSuccessGoogleRpcStatus({}), - ).as('deleteJobPipeline'); + ).as('deleteRecurringRunPipeline'); cy.interceptOdh( 'GET /api/service/pipelines/:namespace/:serviceName/apis/v2beta1/recurringruns', @@ -119,14 +125,17 @@ describe('Pipeline runs', () => { }, { recurringRuns: [ - buildMockJobKF({ recurring_run_id: 'other-pipeline', display_name: 'other-pipeline' }), + buildMockRecurringRunKF({ + recurring_run_id: 'other-pipeline', + display_name: 'other-pipeline', + }), ], }, ).as('getRuns'); schedulesDeleteModal.findSubmitButton().click(); - cy.wait('@deleteJobPipeline'); + cy.wait('@deleteRecurringRunPipeline'); cy.wait('@getRuns').then((interception) => { expect(interception.request.query).to.eql({ @@ -136,7 +145,7 @@ describe('Pipeline runs', () => { '{"predicates":[{"key":"pipeline_version_id","operation":"EQUALS","string_value":"version_id"}]}', }); - pipelineRunJobTable.findEmptyState().should('not.exist'); + pipelineRecurringRunTable.findEmptyState().should('not.exist'); }); }); @@ -147,10 +156,10 @@ describe('Pipeline runs', () => { pipelineRunsGlobal.isApiAvailable(); pipelineRunsGlobal.findSchedulesTab().click(); - pipelineRunJobTable.getRowByName('test-pipeline').findCheckbox().click(); - pipelineRunJobTable.getRowByName('other-pipeline').findCheckbox().click(); + pipelineRecurringRunTable.getRowByName('test-pipeline').findCheckbox().click(); + pipelineRecurringRunTable.getRowByName('other-pipeline').findCheckbox().click(); - pipelineRunJobTable.findActionsKebab().findDropdownItem('Delete').click(); + pipelineRecurringRunTable.findActionsKebab().findDropdownItem('Delete').click(); schedulesDeleteModal.shouldBeOpen(); schedulesDeleteModal.findSubmitButton().should('be.disabled'); @@ -162,7 +171,7 @@ describe('Pipeline runs', () => { path: { namespace: 'test-project', serviceName: 'dspa', recurringRunId: 'test-pipeline' }, }, mockSuccessGoogleRpcStatus({}), - ).as('deleteJobPipeline-1'); + ).as('deleteRecurringRunPipeline-1'); cy.interceptOdh( 'DELETE /api/service/pipelines/:namespace/:serviceName/apis/v2beta1/recurringruns/:recurringRunId', @@ -174,7 +183,7 @@ describe('Pipeline runs', () => { }, }, mockSuccessGoogleRpcStatus({}), - ).as('deleteJobPipeline-2'); + ).as('deleteRecurringRunPipeline-2'); cy.interceptOdh( 'GET /api/service/pipelines/:namespace/:serviceName/apis/v2beta1/recurringruns', @@ -186,8 +195,8 @@ describe('Pipeline runs', () => { schedulesDeleteModal.findSubmitButton().click(); - cy.wait('@deleteJobPipeline-1'); - cy.wait('@deleteJobPipeline-2'); + cy.wait('@deleteRecurringRunPipeline-1'); + cy.wait('@deleteRecurringRunPipeline-2'); cy.wait('@getRuns').then((interception) => { expect(interception.request.query).to.eql({ @@ -197,7 +206,7 @@ describe('Pipeline runs', () => { '{"predicates":[{"key":"pipeline_version_id","operation":"EQUALS","string_value":"version_id"}]}', }); }); - pipelineRunJobTable.findEmptyState().should('exist'); + pipelineRecurringRunTable.findEmptyState().should('exist'); }); it('Test delete a single archived run', () => { diff --git a/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/pipelineRuns.cy.ts b/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/pipelineRuns.cy.ts index fa89cbd830..5dd7fc1f64 100644 --- a/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/pipelineRuns.cy.ts +++ b/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/pipelineRuns.cy.ts @@ -7,18 +7,18 @@ import { mockProjectK8sResource, mockRouteK8sResource, buildMockRunKF, - buildMockJobKF, buildMockPipelineVersionsV2, buildMockPipelineVersionV2, buildMockPipelines, buildMockPipelineV2, buildMockExperimentKF, + buildMockRecurringRunKF, } from '~/__mocks__'; import { activeRunsTable, pipelineRunsGlobal, pipelineRunFilterBar, - pipelineRunJobTable, + pipelineRecurringRunTable, archivedRunsTable, restoreRunModal, bulkRestoreRunModal, @@ -97,8 +97,8 @@ const mockVersions = mockVersionIds.map((versionId) => }), ); -const mockJobs = [ - buildMockJobKF({ +const mockRecurringRuns = [ + buildMockRecurringRunKF({ display_name: 'test-pipeline', recurring_run_id: 'test-pipeline', experiment_id: 'test-experiment-1', @@ -107,7 +107,7 @@ const mockJobs = [ pipeline_version_id: 'test-version-1', }, }), - buildMockJobKF({ + buildMockRecurringRunKF({ display_name: 'other-pipeline', recurring_run_id: 'other-test-pipeline', experiment_id: 'test-experiment-2', @@ -116,7 +116,7 @@ const mockJobs = [ pipeline_version_id: 'test-version-2', }, }), - buildMockJobKF({ + buildMockRecurringRunKF({ display_name: 'another-pipeline', recurring_run_id: 'another-test-pipeline', experiment_id: 'test-experiment-1', @@ -760,12 +760,12 @@ describe('Pipeline runs', () => { describe('Schedules', () => { describe('empty state', () => { beforeEach(() => { - pipelineRunJobTable.mockGetJobs([], projectName); + pipelineRecurringRunTable.mockGetRecurringRuns([], projectName); pipelineRunsGlobal.visit(projectName, pipelineId, pipelineVersionId, 'scheduled'); }); it('shows empty state', () => { - pipelineRunJobTable.findEmptyState().should('exist'); + pipelineRecurringRunTable.findEmptyState().should('exist'); }); it('navigate to create run page', () => { @@ -775,15 +775,15 @@ describe('Pipeline runs', () => { }); it('shows empty state', () => { - pipelineRunJobTable.mockGetJobs([], projectName); + pipelineRecurringRunTable.mockGetRecurringRuns([], projectName); pipelineRunsGlobal.visit(projectName, pipelineId, pipelineVersionId, 'scheduled'); - pipelineRunJobTable.findEmptyState().should('exist'); + pipelineRecurringRunTable.findEmptyState().should('exist'); }); describe('table pagination', () => { it('Scheduled run table pagination', () => { - const mockJobRuns = Array.from({ length: 15 }, (_, i) => - buildMockJobKF({ + const mockRuns = Array.from({ length: 15 }, (_, i) => + buildMockRecurringRunKF({ display_name: `another-pipeline-${i}`, recurring_run_id: `another-test-pipeline-${i}`, experiment_id: `test-experiment-${i}`, @@ -800,7 +800,7 @@ describe('Pipeline runs', () => { path: { namespace: projectName, serviceName: 'dspa' }, }, { - recurringRuns: mockJobRuns.slice(0, 10), + recurringRuns: mockRuns.slice(0, 10), total_size: 15, next_page_token: 'page-2-token', }, @@ -816,8 +816,8 @@ describe('Pipeline runs', () => { }); }); - pipelineRunJobTable.getRowByName('another-pipeline-0').find().should('exist'); - pipelineRunJobTable.findRows().should('have.length', 10); + pipelineRecurringRunTable.getRowByName('another-pipeline-0').find().should('exist'); + pipelineRecurringRunTable.findRows().should('have.length', 10); const pagination = tablePagination.top; @@ -830,7 +830,7 @@ describe('Pipeline runs', () => { path: { namespace: projectName, serviceName: 'dspa' }, }, { - recurringRuns: mockJobRuns.slice(10, 15), + recurringRuns: mockRuns.slice(10, 15), total_size: 15, }, ).as('refreshScheduledRuns'); @@ -847,8 +847,8 @@ describe('Pipeline runs', () => { }); pagination.findInput().should('have.value', '2'); - pipelineRunJobTable.getRowByName('another-pipeline-14').find().should('exist'); - pipelineRunJobTable.findRows().should('have.length', 5); + pipelineRecurringRunTable.getRowByName('another-pipeline-14').find().should('exist'); + pipelineRecurringRunTable.findRows().should('have.length', 5); //test first button pagination.findLastButton().should('be.disabled'); @@ -859,15 +859,15 @@ describe('Pipeline runs', () => { path: { namespace: projectName, serviceName: 'dspa' }, }, { - recurringRuns: mockJobRuns.slice(0, 10), + recurringRuns: mockRuns.slice(0, 10), total_size: 15, next_page_token: 'new-page-token', }, ); pagination.findFirstButton().click(); pagination.findInput().should('have.value', '1'); - pipelineRunJobTable.getRowByName('another-pipeline-0').find().should('exist'); - pipelineRunJobTable.findRows().should('have.length', 10); + pipelineRecurringRunTable.getRowByName('another-pipeline-0').find().should('exist'); + pipelineRecurringRunTable.findRows().should('have.length', 10); //test last button pagination.findFirstButton().should('be.disabled'); @@ -878,17 +878,17 @@ describe('Pipeline runs', () => { path: { namespace: projectName, serviceName: 'dspa' }, }, { - recurringRuns: mockJobRuns.slice(10, 15), + recurringRuns: mockRuns.slice(10, 15), total_size: 15, }, - ).as('refreshPipelineRunJobs'); + ).as('refreshPipelineRecurringRuns'); pagination.findLastButton().click(); pagination.findInput().should('have.value', Math.ceil(15 / 10)); - pipelineRunJobTable.getRowByName('another-pipeline-14').find().should('exist'); - pipelineRunJobTable.findRows().should('have.length', 5); + pipelineRecurringRunTable.getRowByName('another-pipeline-14').find().should('exist'); + pipelineRecurringRunTable.findRows().should('have.length', 5); - cy.wait('@refreshPipelineRunJobs').then((interception) => { + cy.wait('@refreshPipelineRecurringRuns').then((interception) => { expect(interception.request.query).to.eql({ filter: '{"predicates":[{"key":"pipeline_version_id","operation":"EQUALS","string_value":"test-version"}]}', @@ -907,14 +907,14 @@ describe('Pipeline runs', () => { path: { namespace: projectName, serviceName: 'dspa' }, }, { - recurringRuns: mockJobRuns.slice(0, 10), + recurringRuns: mockRuns.slice(0, 10), total_size: 15, }, ); pagination.findPreviousButton().click(); pagination.findInput().should('have.value', '1'); - pipelineRunJobTable.getRowByName('another-pipeline-0').find().should('exist'); - pipelineRunJobTable.findRows().should('have.length', 10); + pipelineRecurringRunTable.getRowByName('another-pipeline-0').find().should('exist'); + pipelineRecurringRunTable.findRows().should('have.length', 10); // 20 per page cy.interceptOdh( @@ -923,16 +923,16 @@ describe('Pipeline runs', () => { path: { namespace: projectName, serviceName: 'dspa' }, }, { - recurringRuns: mockJobRuns.slice(0, 15), + recurringRuns: mockRuns.slice(0, 15), total_size: 15, }, ); pagination.selectToggleOption('20 per page'); - pipelineRunJobTable.getRowByName('another-pipeline-0').find().should('exist'); - pipelineRunJobTable.getRowByName('another-pipeline-14').find().should('exist'); - pipelineRunJobTable.findRows().should('have.length', 15); + pipelineRecurringRunTable.getRowByName('another-pipeline-0').find().should('exist'); + pipelineRecurringRunTable.getRowByName('another-pipeline-14').find().should('exist'); + pipelineRecurringRunTable.findRows().should('have.length', 15); pagination.findLastButton().should('be.disabled'); pagination.findNextButton().should('be.disabled'); pagination.findPreviousButton().should('be.disabled'); @@ -943,25 +943,27 @@ describe('Pipeline runs', () => { describe('with data', () => { beforeEach(() => { - pipelineRunJobTable.mockGetJobs(mockJobs, projectName); + pipelineRecurringRunTable.mockGetRecurringRuns(mockRecurringRuns, projectName); }); it('renders the page with table rows', () => { pipelineRunsGlobal.visit(projectName, pipelineId, pipelineVersionId, 'scheduled'); - pipelineRunJobTable.find().should('exist'); - pipelineRunJobTable.getRowByName('test-pipeline').find().should('exist'); - pipelineRunJobTable.getRowByName('other-pipeline').find().should('exist'); - pipelineRunJobTable.getRowByName('another-pipeline').find().should('exist'); + pipelineRecurringRunTable.find().should('exist'); + pipelineRecurringRunTable.getRowByName('test-pipeline').find().should('exist'); + pipelineRecurringRunTable.getRowByName('other-pipeline').find().should('exist'); + pipelineRecurringRunTable.getRowByName('another-pipeline').find().should('exist'); }); - it('can disable a job', () => { + it('can disable a recurring run', () => { pipelineRunsGlobal.visit(projectName, pipelineId, pipelineVersionId, 'scheduled'); - pipelineRunJobTable.mockDisableJob(mockJobs[0], projectName).as('disableJob'); - pipelineRunJobTable - .getRowByName(mockJobs[0].display_name) + pipelineRecurringRunTable + .mockDisableRecurringRun(mockRecurringRuns[0], projectName) + .as('disableRecurringRun'); + pipelineRecurringRunTable + .getRowByName(mockRecurringRuns[0].display_name) .findStatusSwitchByRowName() .click(); - cy.wait('@disableJob'); + cy.wait('@disableRecurringRun'); }); describe('Navigation', () => { @@ -977,25 +979,25 @@ describe('Pipeline runs', () => { cy.visitWithLogin(`/experiments/${projectName}/test-experiment-1/runs`); pipelineRunsGlobal.findSchedulesTab().click(); - pipelineRunJobTable - .getRowByName(mockJobs[0].display_name) + pipelineRecurringRunTable + .getRowByName(mockRecurringRuns[0].display_name) .findKebabAction('Duplicate') .click(); verifyRelativeURL( - `/experiments/${projectName}/test-experiment-1/schedules/clone/${mockJobs[0].recurring_run_id}?runType=scheduled`, + `/experiments/${projectName}/test-experiment-1/schedules/clone/${mockRecurringRuns[0].recurring_run_id}?runType=scheduled`, ); }); it('navigate to scheduled run details page', () => { pipelineRunsGlobal.visit(projectName, pipelineId, pipelineVersionId, 'scheduled'); pipelineRunsGlobal.findSchedulesTab().click(); - pipelineRunJobTable - .getRowByName(mockJobs[0].display_name) - .findColumnName(mockJobs[0].display_name) + pipelineRecurringRunTable + .getRowByName(mockRecurringRuns[0].display_name) + .findColumnName(mockRecurringRuns[0].display_name) .click(); verifyRelativeURL( - `/pipelines/${projectName}/pipelineRunJob/view/${mockJobs[0].recurring_run_id}`, + `/pipelines/${projectName}/pipelineRecurringRun/view/${mockRecurringRuns[0].recurring_run_id}`, ); }); }); @@ -1006,21 +1008,23 @@ describe('Pipeline runs', () => { pipelineRunsGlobal.findSchedulesTab().click(); // Verify initial job rows exist - pipelineRunJobTable.findRows().should('have.length', 3); + pipelineRecurringRunTable.findRows().should('have.length', 3); // Select the "Schedule" filter, enter a value to filter by - pipelineRunJobTable.selectFilterByName('Schedule'); - pipelineRunJobTable.findFilterTextField().type('test-pipeline'); - - // Mock jobs (filtered by typed job name) - pipelineRunJobTable.mockGetJobs( - mockJobs.filter((mockJob) => mockJob.display_name.includes('test-pipeline')), + pipelineRecurringRunTable.selectFilterByName('Schedule'); + pipelineRecurringRunTable.findFilterTextField().type('test-pipeline'); + + // Mock recurring runs (filtered by typed recurring run name) + pipelineRecurringRunTable.mockGetRecurringRuns( + mockRecurringRuns.filter((mockRecurringRun) => + mockRecurringRun.display_name.includes('test-pipeline'), + ), projectName, ); - // Verify only rows with the typed job name exist - pipelineRunJobTable.findRows().should('have.length', 1); - pipelineRunJobTable.getRowByName('test-pipeline').find().should('exist'); + // Verify only rows with the typed recurring run name exist + pipelineRecurringRunTable.findRows().should('have.length', 1); + pipelineRecurringRunTable.getRowByName('test-pipeline').find().should('exist'); }); it('Sort by Name', () => { diff --git a/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/pipelinesTopology.cy.ts b/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/pipelinesTopology.cy.ts index 650bc8d7f4..cf0e8b8fe0 100644 --- a/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/pipelinesTopology.cy.ts +++ b/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/pipelinesTopology.cy.ts @@ -9,11 +9,11 @@ import { import { mockProjectK8sResource } from '~/__mocks__/mockProjectK8sResource'; import { mockRouteK8sResource } from '~/__mocks__/mockRouteK8sResource'; import { mockSecretK8sResource } from '~/__mocks__/mockSecretK8sResource'; -import { buildMockJobKF } from '~/__mocks__/mockJobKF'; +import { buildMockRecurringRunKF } from '~/__mocks__/mockRecurringRunKF'; import { mockPodLogs } from '~/__mocks__/mockPodLogs'; import { pipelineDetails, - pipelineRunJobDetails, + pipelineRecurringRunDetails, pipelineRunDetails, pipelineVersionImportModal, } from '~/__tests__/cypress/cypress/pages/pipelines'; @@ -53,7 +53,7 @@ const mockRun = buildMockRunKF({ pipeline_version_id: mockVersion.pipeline_version_id, }, }); -const mockJob = buildMockJobKF({ +const mockRecurringRun = buildMockRecurringRunKF({ display_name: 'test-pipeline', recurring_run_id: 'test-pipeline', pipeline_version_reference: { @@ -120,9 +120,13 @@ const initIntercepts = () => { cy.interceptOdh( 'GET /api/service/pipelines/:namespace/:serviceName/apis/v2beta1/recurringruns/:recurringRunId', { - path: { namespace: projectId, serviceName: 'dspa', recurringRunId: mockJob.recurring_run_id }, + path: { + namespace: projectId, + serviceName: 'dspa', + recurringRunId: mockRecurringRun.recurring_run_id, + }, }, - mockJob, + mockRecurringRun, ); cy.interceptOdh( 'GET /api/service/pipelines/:namespace/:serviceName/apis/v2beta1/runs/:runId', @@ -315,17 +319,17 @@ describe('Pipeline topology', () => { verifyRelativeURL(`/pipelines/${projectId}/pipelineRun/clone/${mockRun.run_id}`); }); - it('Test pipeline job duplicate navigation', () => { - pipelineRunJobDetails.visit(projectId, mockJob.recurring_run_id); - pipelineRunJobDetails.selectActionDropdownItem('Duplicate'); + it('Test pipeline recurring run duplicate navigation', () => { + pipelineRecurringRunDetails.visit(projectId, mockRecurringRun.recurring_run_id); + pipelineRecurringRunDetails.selectActionDropdownItem('Duplicate'); verifyRelativeURL( - `/pipelines/${projectId}/pipelineRun/cloneJob/${mockJob.recurring_run_id}?runType=scheduled`, + `/pipelines/${projectId}/pipelineRun/cloneRecurringRun/${mockRecurringRun.recurring_run_id}?runType=scheduled`, ); }); - it('Test pipeline job delete navigation', () => { - pipelineRunJobDetails.visit(projectId, mockJob.recurring_run_id); - pipelineRunJobDetails.selectActionDropdownItem('Delete'); + it('Test pipeline recurring run delete navigation', () => { + pipelineRecurringRunDetails.visit(projectId, mockRecurringRun.recurring_run_id); + pipelineRecurringRunDetails.selectActionDropdownItem('Delete'); deleteModal.shouldBeOpen(); deleteModal.findInput().type(mockPipeline.display_name); @@ -339,55 +343,71 @@ describe('Pipeline topology', () => { }, }, {}, - ).as('deletepipelineRunJob'); + ).as('deletepipelineRecurringRun'); deleteModal.findSubmitButton().click(); - cy.wait('@deletepipelineRunJob'); + cy.wait('@deletepipelineRecurringRun'); }); - it('Test pipeline job details project navigation', () => { - pipelineRunJobDetails.visit(projectId, mockJob.recurring_run_id); + it('Test pipeline recurring run details project navigation', () => { + pipelineRecurringRunDetails.visit(projectId, mockRecurringRun.recurring_run_id); - pipelineRunJobDetails.findDetailsTab().click(); - pipelineRunJobDetails.findDetailItem('Project').findValue().find('a').click(); + pipelineRecurringRunDetails.findDetailsTab().click(); + pipelineRecurringRunDetails.findDetailItem('Project').findValue().find('a').click(); verifyRelativeURL(`/projects/${projectId}?section=overview`); }); - it('Test pipeline job details pipeline version navigation', () => { - pipelineRunJobDetails.visit(projectId, mockJob.recurring_run_id); + it('Test pipeline recurring run details pipeline version navigation', () => { + pipelineRecurringRunDetails.visit(projectId, mockRecurringRun.recurring_run_id); - pipelineRunJobDetails.findDetailsTab().click(); - pipelineRunJobDetails.findDetailItem('Pipeline version').findValue().find('a').click(); + pipelineRecurringRunDetails.findDetailsTab().click(); + pipelineRecurringRunDetails + .findDetailItem('Pipeline version') + .findValue() + .find('a') + .click(); verifyRelativeURL( - `/pipelines/${projectId}/pipeline/view/${mockJob.pipeline_version_reference.pipeline_id}/${mockJob.pipeline_version_reference.pipeline_version_id}`, + `/pipelines/${projectId}/pipeline/view/${mockRecurringRun.pipeline_version_reference.pipeline_id}/${mockRecurringRun.pipeline_version_reference.pipeline_version_id}`, ); }); }); - it('Test pipeline job tab details', () => { + it('Test pipeline recurring run tab details', () => { initIntercepts(); - pipelineRunJobDetails.visit(projectId, mockJob.recurring_run_id); + pipelineRecurringRunDetails.visit(projectId, mockRecurringRun.recurring_run_id); - pipelineRunJobDetails.findDetailsTab().click(); - pipelineRunJobDetails.findDetailItem('Name').findValue().contains(mockJob.display_name); - pipelineRunJobDetails.findDetailItem('Project').findValue().contains('Test Project'); - pipelineRunJobDetails.findDetailItem('Run ID').findValue().contains(mockJob.display_name); - pipelineRunJobDetails + pipelineRecurringRunDetails.findDetailsTab().click(); + pipelineRecurringRunDetails + .findDetailItem('Name') + .findValue() + .contains(mockRecurringRun.display_name); + pipelineRecurringRunDetails.findDetailItem('Project').findValue().contains('Test Project'); + pipelineRecurringRunDetails + .findDetailItem('Run ID') + .findValue() + .contains(mockRecurringRun.display_name); + pipelineRecurringRunDetails .findDetailItem('Pipeline version') .findValue() .contains('test-version-name'); - pipelineRunJobDetails.findDetailItem('Pipeline').findValue().contains('test-pipeline'); - pipelineRunJobDetails.findDetailItem('Workflow name').findValue().contains('test-pipeline'); - pipelineRunJobDetails.findDetailItem('Created').findValue().contains('February 8, 2024'); - pipelineRunJobDetails.findDetailItem('Run trigger enabled').findValue().contains('Yes'); - pipelineRunJobDetails.findDetailItem('Trigger').findValue().contains('Every 1 minute'); + pipelineRecurringRunDetails.findDetailItem('Pipeline').findValue().contains('test-pipeline'); + pipelineRecurringRunDetails + .findDetailItem('Workflow name') + .findValue() + .contains('test-pipeline'); + pipelineRecurringRunDetails + .findDetailItem('Created') + .findValue() + .contains('February 8, 2024'); + pipelineRecurringRunDetails.findDetailItem('Run trigger enabled').findValue().contains('Yes'); + pipelineRecurringRunDetails.findDetailItem('Trigger').findValue().contains('Every 1 minute'); }); it('Ensure that clicking on a node will open a right-side drawer', () => { initIntercepts(); - pipelineRunJobDetails.visit(projectId, mockJob.recurring_run_id); + pipelineRecurringRunDetails.visit(projectId, mockRecurringRun.recurring_run_id); pipelineDetails.findTaskNode('create-dataset').click(); const taskDrawer = pipelineDetails.getTaskDrawer(); @@ -407,16 +427,19 @@ describe('Pipeline topology', () => { pipelineRunDetails.visit(projectId, mockRun.run_id); - pipelineRunJobDetails.findPipelineSpecTab(); + pipelineRecurringRunDetails.findPipelineSpecTab(); pipelineRunDetails.findDetailsTab().click(); - pipelineRunDetails.findDetailItem('Name').findValue().contains(mockJob.display_name); + pipelineRunDetails.findDetailItem('Name').findValue().contains(mockRecurringRun.display_name); pipelineRunDetails .findDetailItem('Pipeline version') .findValue() .contains('test-version-name'); pipelineRunDetails.findDetailItem('Pipeline').findValue().contains('test-pipeline'); pipelineRunDetails.findDetailItem('Project').findValue().contains('Test Project'); - pipelineRunDetails.findDetailItem('Run ID').findValue().contains(mockJob.display_name); + pipelineRunDetails + .findDetailItem('Run ID') + .findValue() + .contains(mockRecurringRun.display_name); pipelineRunDetails.findDetailItem('Workflow name').findValue().contains('test-pipeline'); pipelineRunDetails.findDetailItem('Started').findValue().contains('March 15, 2024'); pipelineRunDetails.findDetailItem('Finished').findValue().contains('March 15, 2024'); diff --git a/frontend/src/api/pipelines/__tests__/custom.spec.ts b/frontend/src/api/pipelines/__tests__/custom.spec.ts index 9befa906b8..a4b5bbb43a 100644 --- a/frontend/src/api/pipelines/__tests__/custom.spec.ts +++ b/frontend/src/api/pipelines/__tests__/custom.spec.ts @@ -1,24 +1,24 @@ /* eslint-disable camelcase */ import { createExperiment, + createPipelineRecurringRun, createPipelineRun, - createPipelineRunJob, deletePipeline, + deletePipelineRecurringRun, deletePipelineRun, - deletePipelineRunJob, deletePipelineVersion, getExperiment, getPipeline, + getPipelineRecurringRun, getPipelineRun, - getPipelineRunJob, getPipelineVersion, listExperiments, - listPipelineRunJobs, + listPipelineRecurringRuns, listPipelineRuns, listPipelineVersions, listPipelines, stopPipelineRun, - updatePipelineRunJob, + updatePipelineRecurringRun, uploadPipeline, uploadPipelineVersion, } from '~/api/pipelines/custom'; @@ -26,7 +26,7 @@ import { handlePipelineFailures } from '~/api/pipelines/errorUtils'; import { proxyCREATE, proxyDELETE, proxyENDPOINT, proxyFILE, proxyGET } from '~/api/proxyUtils'; import { CreateExperimentKFData, - CreatePipelineRunJobKFData, + CreatePipelineRecurringRunKFData, CreatePipelineRunKFData, RecurringRunMode, } from '~/concepts/pipelines/kfTypes'; @@ -117,8 +117,8 @@ describe('createPipelineRun', () => { }); }); -describe('createPipelineRunJob', () => { - const data: CreatePipelineRunJobKFData = { +describe('createPipelineRecurringRun', () => { + const data: CreatePipelineRecurringRunKFData = { display_name: 'name', max_concurrency: 'max_concurrency', trigger: { @@ -132,8 +132,8 @@ describe('createPipelineRunJob', () => { }, mode: RecurringRunMode.ENABLE, }; - it('should call proxyCREATE and handlePipelineFailures to create pipeline run job', () => { - expect(createPipelineRunJob('hostPath')({}, data)).toBe(mockResultPromise); + it('should call proxyCREATE and handlePipelineFailures to create pipeline recurring run', () => { + expect(createPipelineRecurringRun('hostPath')({}, data)).toBe(mockResultPromise); expect(proxyCREATEMock).toHaveBeenCalledTimes(1); expect(proxyCREATEMock).toHaveBeenCalledWith( 'hostPath', @@ -212,13 +212,15 @@ describe('getPipelineRun', () => { }); }); -describe('getPipelineRunJob', () => { - it('should call proxyGET and handlePipelineFailures to fetch pipeline run job', () => { - expect(getPipelineRunJob('hostPath')({}, 'pipelineRunJobId')).toBe(mockResultPromise); +describe('getPipelineRecurringRun', () => { + it('should call proxyGET and handlePipelineFailures to fetch pipeline recurring run', () => { + expect(getPipelineRecurringRun('hostPath')({}, 'pipelineRecurringRunId')).toBe( + mockResultPromise, + ); expect(proxyGETMock).toHaveBeenCalledTimes(1); expect(proxyGETMock).toHaveBeenCalledWith( 'hostPath', - '/apis/v2beta1/recurringruns/pipelineRunJobId', + '/apis/v2beta1/recurringruns/pipelineRecurringRunId', {}, {}, ); @@ -276,13 +278,13 @@ describe('deletePipelineRun', () => { }); }); -describe('deletePipelineRunJob', () => { - it('should call proxyDELETE and handlePipelineFailures to delete pipeline run job', () => { - expect(deletePipelineRunJob('hostPath')({}, 'jobId')).toBe(mockResultPromise); +describe('deletePipelineRecurringRun', () => { + it('should call proxyDELETE and handlePipelineFailures to delete pipeline recurring run', () => { + expect(deletePipelineRecurringRun('hostPath')({}, 'recurringRunId')).toBe(mockResultPromise); expect(proxyDELETEMock).toHaveBeenCalledTimes(1); expect(proxyDELETEMock).toHaveBeenCalledWith( 'hostPath', - '/apis/v2beta1/recurringruns/jobId', + '/apis/v2beta1/recurringruns/recurringRunId', {}, {}, {}, @@ -350,9 +352,9 @@ describe('listPipelineRuns', () => { }); }); -describe('listPipelineRunJobs', () => { - it('should call proxyGET and handlePipelineFailures to list pipeline run jobs', () => { - expect(listPipelineRunJobs('hostPath')({}, createParam())).toBe(mockResultPromise); +describe('listPipelineRecurringRuns', () => { + it('should call proxyGET and handlePipelineFailures to list pipeline recurring runs', () => { + expect(listPipelineRecurringRuns('hostPath')({}, createParam())).toBe(mockResultPromise); expect(proxyGETMock).toHaveBeenCalledTimes(1); expect(proxyGETMock).toHaveBeenCalledWith( 'hostPath', @@ -401,25 +403,29 @@ describe('stopPipelineRun', () => { }); }); -describe('updatePipelineRunJob', () => { - it('should call proxyENDPOINT and handlePipelineFailures to update pipeline run job, when enabled is true', () => { - expect(updatePipelineRunJob('hostPath')({}, 'jobId', true)).toBe(mockResultPromise); +describe('updatePipelineRecurringRun', () => { + it('should call proxyENDPOINT and handlePipelineFailures to update pipeline recurring run, when enabled is true', () => { + expect(updatePipelineRecurringRun('hostPath')({}, 'recurringRunId', true)).toBe( + mockResultPromise, + ); expect(proxyENDPOINTMock).toHaveBeenCalledTimes(1); expect(proxyENDPOINTMock).toHaveBeenCalledWith( 'hostPath', - '/apis/v2beta1/recurringruns/jobId:enable', + '/apis/v2beta1/recurringruns/recurringRunId:enable', {}, {}, ); expect(handlePipelineFailuresMock).toHaveBeenCalledTimes(1); expect(handlePipelineFailuresMock).toHaveBeenCalledWith(mockProxyPromise); }); - it('should call proxyENDPOINT and handlePipelineFailures to update pipeline run job, when enabled is false', () => { - expect(updatePipelineRunJob('hostPath')({}, 'jobId', false)).toBe(mockResultPromise); + it('should call proxyENDPOINT and handlePipelineFailures to update pipeline recurring run, when enabled is false', () => { + expect(updatePipelineRecurringRun('hostPath')({}, 'recurringRunId', false)).toBe( + mockResultPromise, + ); expect(proxyENDPOINTMock).toHaveBeenCalledTimes(1); expect(proxyENDPOINTMock).toHaveBeenCalledWith( 'hostPath', - '/apis/v2beta1/recurringruns/jobId:disable', + '/apis/v2beta1/recurringruns/recurringRunId:disable', {}, {}, ); diff --git a/frontend/src/api/pipelines/callTypes.ts b/frontend/src/api/pipelines/callTypes.ts index 8d3c210d06..4648eb7a03 100644 --- a/frontend/src/api/pipelines/callTypes.ts +++ b/frontend/src/api/pipelines/callTypes.ts @@ -2,19 +2,19 @@ import { GetPipeline, DeletePipeline, ListPipelineRuns, - ListPipelineRunJobs, + ListPipelineRecurringRuns, ListPipelines, UploadPipeline, - UpdatePipelineRunJob, + UpdatePipelineRecurringRun, GetPipelineRun, UpdatePipelineRun, ListExperiments, CreateExperiment, GetExperiment, CreatePipelineRun, - CreatePipelineRunJob, - GetPipelineRunJob, - DeletePipelineRunJob, + CreatePipelineRecurringRun, + GetPipelineRecurringRun, + DeletePipelineRecurringRun, DeletePipelineRun, UploadPipelineVersion, GetPipelineVersion, @@ -36,24 +36,24 @@ export type CreatePipelineVersionAPI = KubeflowAPICall; export type CreatePipelineAndVersionAPI = KubeflowAPICall; export type CreateExperimentAPI = KubeflowAPICall; export type CreatePipelineRunAPI = KubeflowAPICall; -export type CreatePipelineRunJobAPI = KubeflowAPICall; +export type CreatePipelineRecurringRunAPI = KubeflowAPICall; export type GetExperimentAPI = KubeflowAPICall; export type GetPipelineAPI = KubeflowAPICall; export type GetPipelineRunAPI = KubeflowAPICall; -export type GetPipelineRunJobAPI = KubeflowAPICall; +export type GetPipelineRecurringRunAPI = KubeflowAPICall; export type GetPipelineVersionAPI = KubeflowAPICall; export type DeletePipelineAPI = KubeflowAPICall; export type DeletePipelineRunAPI = KubeflowAPICall; -export type DeletePipelineRunJobAPI = KubeflowAPICall; +export type DeletePipelineRecurringRunAPI = KubeflowAPICall; export type DeletePipelineVersionAPI = KubeflowAPICall; export type DeleteExperimentAPI = KubeflowAPICall; export type ListExperimentsAPI = KubeflowAPICall; export type ListPipelinesAPI = KubeflowAPICall; export type ListPipelinesRunAPI = KubeflowAPICall; -export type ListPipelinesRunJobAPI = KubeflowAPICall; +export type ListPipelineRecurringRunsAPI = KubeflowAPICall; export type ListPipelineVersionsAPI = KubeflowAPICall; export type UpdatePipelineRunAPI = KubeflowAPICall; -export type UpdatePipelineRunJobAPI = KubeflowAPICall; +export type UpdatePipelineRecurringRunAPI = KubeflowAPICall; export type UpdateExperimentAPI = KubeflowAPICall; export type UploadPipelineAPI = KubeflowAPICall; export type UploadPipelineVersionAPI = KubeflowAPICall; diff --git a/frontend/src/api/pipelines/custom.ts b/frontend/src/api/pipelines/custom.ts index 5040a8cdf3..e1cc690126 100644 --- a/frontend/src/api/pipelines/custom.ts +++ b/frontend/src/api/pipelines/custom.ts @@ -5,19 +5,19 @@ import { GetPipelineAPI, DeletePipelineAPI, ListPipelinesRunAPI, - ListPipelinesRunJobAPI, + ListPipelineRecurringRunsAPI, ListPipelinesAPI, UploadPipelineAPI, - UpdatePipelineRunJobAPI, + UpdatePipelineRecurringRunAPI, GetPipelineRunAPI, ListExperimentsAPI, CreateExperimentAPI, GetExperimentAPI, CreatePipelineRunAPI, - CreatePipelineRunJobAPI, - GetPipelineRunJobAPI, + CreatePipelineRecurringRunAPI, + GetPipelineRecurringRunAPI, DeletePipelineRunAPI, - DeletePipelineRunJobAPI, + DeletePipelineRecurringRunAPI, UploadPipelineVersionAPI, DeletePipelineVersionAPI, GetPipelineVersionAPI, @@ -63,8 +63,9 @@ export const createPipelineVersion: CreatePipelineVersionAPI = export const createPipelineRun: CreatePipelineRunAPI = (hostPath) => (opts, data) => handlePipelineFailures(proxyCREATE(hostPath, `/apis/v2beta1/runs`, data, {}, opts)); -export const createPipelineRunJob: CreatePipelineRunJobAPI = (hostPath) => (opts, data) => - handlePipelineFailures(proxyCREATE(hostPath, `/apis/v2beta1/recurringruns`, data, {}, opts)); +export const createPipelineRecurringRun: CreatePipelineRecurringRunAPI = + (hostPath) => (opts, data) => + handlePipelineFailures(proxyCREATE(hostPath, `/apis/v2beta1/recurringruns`, data, {}, opts)); export const getExperiment: GetExperimentAPI = (hostPath) => (opts, experimentId) => handlePipelineFailures(proxyGET(hostPath, `/apis/v2beta1/experiments/${experimentId}`, {}, opts)); @@ -75,10 +76,11 @@ export const getPipeline: GetPipelineAPI = (hostPath) => (opts, pipelineId) => export const getPipelineRun: GetPipelineRunAPI = (hostPath) => (opts, pipelineRunId) => handlePipelineFailures(proxyGET(hostPath, `/apis/v2beta1/runs/${pipelineRunId}`, {}, opts)); -export const getPipelineRunJob: GetPipelineRunJobAPI = (hostPath) => (opts, pipelineRunJobId) => - handlePipelineFailures( - proxyGET(hostPath, `/apis/v2beta1/recurringruns/${pipelineRunJobId}`, {}, opts), - ); +export const getPipelineRecurringRun: GetPipelineRecurringRunAPI = + (hostPath) => (opts, pipelineRecurringRunId) => + handlePipelineFailures( + proxyGET(hostPath, `/apis/v2beta1/recurringruns/${pipelineRecurringRunId}`, {}, opts), + ); export const getPipelineVersion: GetPipelineVersionAPI = (hostPath) => (opts, pipelineId, pipelineVersionId) => @@ -99,10 +101,11 @@ export const deletePipeline: DeletePipelineAPI = (hostPath) => (opts, pipelineId export const deletePipelineRun: DeletePipelineRunAPI = (hostPath) => (opts, runId) => handlePipelineFailures(proxyDELETE(hostPath, `/apis/v2beta1/runs/${runId}`, {}, {}, opts)); -export const deletePipelineRunJob: DeletePipelineRunJobAPI = (hostPath) => (opts, jobId) => - handlePipelineFailures( - proxyDELETE(hostPath, `/apis/v2beta1/recurringruns/${jobId}`, {}, {}, opts), - ); +export const deletePipelineRecurringRun: DeletePipelineRecurringRunAPI = + (hostPath) => (opts, recurringRunId) => + handlePipelineFailures( + proxyDELETE(hostPath, `/apis/v2beta1/recurringruns/${recurringRunId}`, {}, {}, opts), + ); export const deletePipelineVersion: DeletePipelineVersionAPI = (hostPath) => (opts, pipelineId, pipelineVersionId) => @@ -205,33 +208,34 @@ export const listPipelineArchivedRuns: ListPipelinesRunAPI = (hostPath) => (opts }); }; -export const listPipelineRunJobs: ListPipelinesRunJobAPI = (hostPath) => (opts, params) => { - let predicates = params?.filter?.predicates ?? []; - if (params?.pipelineVersionId) { - predicates = [ - ...predicates, - { - key: 'pipeline_version_id', - operation: PipelinesFilterOp.EQUALS, - // eslint-disable-next-line camelcase - string_value: params.pipelineVersionId, - }, - ]; - } +export const listPipelineRecurringRuns: ListPipelineRecurringRunsAPI = + (hostPath) => (opts, params) => { + let predicates = params?.filter?.predicates ?? []; + if (params?.pipelineVersionId) { + predicates = [ + ...predicates, + { + key: 'pipeline_version_id', + operation: PipelinesFilterOp.EQUALS, + // eslint-disable-next-line camelcase + string_value: params.pipelineVersionId, + }, + ]; + } - return handlePipelineFailures( - proxyGET( - hostPath, - '/apis/v2beta1/recurringruns', - { - ...pipelineParamsToQuery({ ...params, filter: { predicates } }), - // eslint-disable-next-line camelcase - experiment_id: params?.experimentId, - }, - opts, - ), - ); -}; + return handlePipelineFailures( + proxyGET( + hostPath, + '/apis/v2beta1/recurringruns', + { + ...pipelineParamsToQuery({ ...params, filter: { predicates } }), + // eslint-disable-next-line camelcase + experiment_id: params?.experimentId, + }, + opts, + ), + ); + }; export const listPipelineVersions: ListPipelineVersionsAPI = (hostPath) => (opts, pipelineId, params) => @@ -274,15 +278,16 @@ export const stopPipelineRun: UpdatePipelineRunAPI = (hostPath) => (opts, runId) export const retryPipelineRun: UpdatePipelineRunAPI = (hostPath) => (opts, runId) => handlePipelineFailures(proxyENDPOINT(hostPath, `/apis/v2beta1/runs/${runId}:retry`, {}, opts)); -export const updatePipelineRunJob: UpdatePipelineRunJobAPI = (hostPath) => (opts, jobId, enabled) => - handlePipelineFailures( - proxyENDPOINT( - hostPath, - `/apis/v2beta1/recurringruns/${jobId}:${enabled ? 'enable' : 'disable'}`, - {}, - opts, - ), - ); +export const updatePipelineRecurringRun: UpdatePipelineRecurringRunAPI = + (hostPath) => (opts, recurringRunId, enabled) => + handlePipelineFailures( + proxyENDPOINT( + hostPath, + `/apis/v2beta1/recurringruns/${recurringRunId}:${enabled ? 'enable' : 'disable'}`, + {}, + opts, + ), + ); export const uploadPipeline: UploadPipelineAPI = (hostPath) => (opts, name, description, fileContents) => diff --git a/frontend/src/concepts/pipelines/apiHooks/usePipelineRecurringRunById.ts b/frontend/src/concepts/pipelines/apiHooks/usePipelineRecurringRunById.ts new file mode 100644 index 0000000000..8f4be1b164 --- /dev/null +++ b/frontend/src/concepts/pipelines/apiHooks/usePipelineRecurringRunById.ts @@ -0,0 +1,29 @@ +import * as React from 'react'; +import useFetchState, { + FetchState, + FetchStateCallbackPromise, + NotReadyError, +} from '~/utilities/useFetchState'; +import { usePipelinesAPI } from '~/concepts/pipelines/context'; +import { PipelineRecurringRunKFv2 } from '~/concepts/pipelines/kfTypes'; + +const usePipelineRecurringRunById = ( + pipelineRecurringRunByIdId?: string, +): FetchState => { + const { api } = usePipelinesAPI(); + + const call = React.useCallback>( + (opts) => { + if (!pipelineRecurringRunByIdId) { + return Promise.reject(new NotReadyError('No pipeline recurring run id')); + } + + return api.getPipelineRecurringRun(opts, pipelineRecurringRunByIdId); + }, + [api, pipelineRecurringRunByIdId], + ); + + return useFetchState(call, null); +}; + +export default usePipelineRecurringRunById; diff --git a/frontend/src/concepts/pipelines/apiHooks/usePipelineRunJobs.ts b/frontend/src/concepts/pipelines/apiHooks/usePipelineRecurringRuns.ts similarity index 73% rename from frontend/src/concepts/pipelines/apiHooks/usePipelineRunJobs.ts rename to frontend/src/concepts/pipelines/apiHooks/usePipelineRecurringRuns.ts index 972eee9344..ec217767ac 100644 --- a/frontend/src/concepts/pipelines/apiHooks/usePipelineRunJobs.ts +++ b/frontend/src/concepts/pipelines/apiHooks/usePipelineRecurringRuns.ts @@ -1,22 +1,22 @@ import * as React from 'react'; -import { PipelineRunJobKFv2 } from '~/concepts/pipelines/kfTypes'; +import { PipelineRecurringRunKFv2 } from '~/concepts/pipelines/kfTypes'; import { FetchState } from '~/utilities/useFetchState'; import { usePipelinesAPI } from '~/concepts/pipelines/context'; import usePipelineQuery from '~/concepts/pipelines/apiHooks/usePipelineQuery'; import { PipelineListPaged, PipelineRunOptions } from '~/concepts/pipelines/types'; -const usePipelineRunJobs = ( +const usePipelineRecurringRuns = ( options?: PipelineRunOptions, -): FetchState> => { +): FetchState> => { const { api } = usePipelinesAPI(); const experimentId = options?.experimentId; const pipelineVersionId = options?.pipelineVersionId; - return usePipelineQuery( + return usePipelineQuery( React.useCallback( (opts, params) => api - .listPipelineRunJobs(opts, { + .listPipelineRecurringRuns(opts, { ...params, ...(experimentId && { experimentId }), ...(pipelineVersionId && { pipelineVersionId }), @@ -28,4 +28,4 @@ const usePipelineRunJobs = ( ); }; -export default usePipelineRunJobs; +export default usePipelineRecurringRuns; diff --git a/frontend/src/concepts/pipelines/apiHooks/usePipelineRunJobById.ts b/frontend/src/concepts/pipelines/apiHooks/usePipelineRunJobById.ts deleted file mode 100644 index 21f4d202ef..0000000000 --- a/frontend/src/concepts/pipelines/apiHooks/usePipelineRunJobById.ts +++ /dev/null @@ -1,29 +0,0 @@ -import * as React from 'react'; -import useFetchState, { - FetchState, - FetchStateCallbackPromise, - NotReadyError, -} from '~/utilities/useFetchState'; -import { usePipelinesAPI } from '~/concepts/pipelines/context'; -import { PipelineRunJobKFv2 } from '~/concepts/pipelines/kfTypes'; - -const usePipelineRunJobById = ( - pipelineRunJobId?: string, -): FetchState => { - const { api } = usePipelinesAPI(); - - const call = React.useCallback>( - (opts) => { - if (!pipelineRunJobId) { - return Promise.reject(new NotReadyError('No pipeline run job id')); - } - - return api.getPipelineRunJob(opts, pipelineRunJobId); - }, - [api, pipelineRunJobId], - ); - - return useFetchState(call, null); -}; - -export default usePipelineRunJobById; diff --git a/frontend/src/concepts/pipelines/content/DeletePipelineRunsModal.tsx b/frontend/src/concepts/pipelines/content/DeletePipelineRunsModal.tsx index 959eacbf57..43319a1e7d 100644 --- a/frontend/src/concepts/pipelines/content/DeletePipelineRunsModal.tsx +++ b/frontend/src/concepts/pipelines/content/DeletePipelineRunsModal.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { Stack, StackItem } from '@patternfly/react-core'; import DeleteModal from '~/pages/projects/components/DeleteModal'; import { usePipelinesAPI } from '~/concepts/pipelines/context'; -import { PipelineRunJobKFv2, PipelineRunKFv2 } from '~/concepts/pipelines/kfTypes'; +import { PipelineRecurringRunKFv2, PipelineRunKFv2 } from '~/concepts/pipelines/kfTypes'; import { K8sAPIOptions } from '~/k8sTypes'; import { PipelineRunType } from '~/pages/pipelines/global/runs/types'; import DeletePipelineModalExpandableSection from '~/concepts/pipelines/content/DeletePipelineModalExpandableSection'; @@ -18,7 +18,7 @@ type DeletePipelineRunsModalProps = { } | { type: PipelineRunType.SCHEDULED; - toDeleteResources: PipelineRunJobKFv2[]; + toDeleteResources: PipelineRecurringRunKFv2[]; } ); @@ -51,7 +51,7 @@ const DeletePipelineRunsModal: React.FC = ({ callFunc = api.deletePipelineRun; break; case PipelineRunType.SCHEDULED: - callFunc = api.deletePipelineRunJob; + callFunc = api.deletePipelineRecurringRun; break; default: // eslint-disable-next-line no-console diff --git a/frontend/src/concepts/pipelines/content/PipelineJobReferenceName.tsx b/frontend/src/concepts/pipelines/content/PipelineJobReferenceName.tsx deleted file mode 100644 index c8123f225e..0000000000 --- a/frontend/src/concepts/pipelines/content/PipelineJobReferenceName.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import React from 'react'; -import { Text, TextVariants } from '@patternfly/react-core'; -import { getPipelineJobExecutionCount } from '~/concepts/pipelines/content/tables/utils'; -import { usePipelinesAPI } from '~/concepts/pipelines/context'; - -type PipelineJobReferenceNameProps = { - runName: string; - recurringRunId?: string; -}; - -const PipelineJobReferenceName: React.FC = ({ - runName, - recurringRunId, -}) => { - const { getJobInformation } = usePipelinesAPI(); - const { data, loading } = getJobInformation(recurringRunId); - - return ( - <> - {loading ? ( - 'loading...' - ) : data ? ( - - Run {getPipelineJobExecutionCount(runName)} of {data.display_name} - - ) : ( - '' - )} - - ); -}; -export default PipelineJobReferenceName; diff --git a/frontend/src/concepts/pipelines/content/PipelineRecurringRunReferenceName.tsx b/frontend/src/concepts/pipelines/content/PipelineRecurringRunReferenceName.tsx new file mode 100644 index 0000000000..33756f3bf0 --- /dev/null +++ b/frontend/src/concepts/pipelines/content/PipelineRecurringRunReferenceName.tsx @@ -0,0 +1,32 @@ +import React from 'react'; +import { Text, TextVariants } from '@patternfly/react-core'; +import { getPipelineRecurringRunExecutionCount } from '~/concepts/pipelines/content/tables/utils'; +import { usePipelinesAPI } from '~/concepts/pipelines/context'; + +type PipelineRecurringRunReferenceNameProps = { + runName: string; + recurringRunId?: string; +}; + +const PipelineRecurringRunReferenceName: React.FC = ({ + runName, + recurringRunId, +}) => { + const { getRecurringRunInformation } = usePipelinesAPI(); + const { data, loading } = getRecurringRunInformation(recurringRunId); + + return ( + <> + {loading ? ( + 'loading...' + ) : data ? ( + + Run {getPipelineRecurringRunExecutionCount(runName)} of {data.display_name} + + ) : ( + '' + )} + + ); +}; +export default PipelineRecurringRunReferenceName; diff --git a/frontend/src/concepts/pipelines/content/PipelineRunTypeLabel.tsx b/frontend/src/concepts/pipelines/content/PipelineRunTypeLabel.tsx index afddc87009..21df3e8d8a 100644 --- a/frontend/src/concepts/pipelines/content/PipelineRunTypeLabel.tsx +++ b/frontend/src/concepts/pipelines/content/PipelineRunTypeLabel.tsx @@ -1,10 +1,10 @@ import React from 'react'; import { Label, Tooltip } from '@patternfly/react-core'; import { PipelineRunLabels } from '~/concepts/pipelines/content/tables/utils'; -import { PipelineRunJobKFv2, PipelineRunKFv2 } from '~/concepts/pipelines/kfTypes'; +import { PipelineRecurringRunKFv2, PipelineRunKFv2 } from '~/concepts/pipelines/kfTypes'; type PipelineRunTypeLabelProps = { - run: PipelineRunKFv2 | PipelineRunJobKFv2; + run: PipelineRunKFv2 | PipelineRecurringRunKFv2; isCompact?: boolean; }; const PipelineRunTypeLabel: React.FC = ({ run, isCompact }) => ( diff --git a/frontend/src/concepts/pipelines/content/createRun/RunPage.tsx b/frontend/src/concepts/pipelines/content/createRun/RunPage.tsx index e9b928131c..fb56bcaecf 100644 --- a/frontend/src/concepts/pipelines/content/createRun/RunPage.tsx +++ b/frontend/src/concepts/pipelines/content/createRun/RunPage.tsx @@ -3,7 +3,7 @@ import { useLocation, useParams } from 'react-router-dom'; import { PageSection } from '@patternfly/react-core'; -import { PipelineRunJobKFv2, PipelineRunKFv2 } from '~/concepts/pipelines/kfTypes'; +import { PipelineRecurringRunKFv2, PipelineRunKFv2 } from '~/concepts/pipelines/kfTypes'; import GenericSidebar from '~/components/GenericSidebar'; import { CreateRunPageSections, @@ -31,7 +31,7 @@ import { routePipelineRunsNamespace } from '~/routes'; import { SupportedArea, useIsAreaAvailable } from '~/concepts/areas'; type RunPageProps = { - cloneRun?: PipelineRunKFv2 | PipelineRunJobKFv2 | null; + cloneRun?: PipelineRunKFv2 | PipelineRecurringRunKFv2 | null; contextPath?: string; testId?: string; }; diff --git a/frontend/src/concepts/pipelines/content/createRun/RunPageFooter.tsx b/frontend/src/concepts/pipelines/content/createRun/RunPageFooter.tsx index 776d4ad79c..cfc04547a6 100644 --- a/frontend/src/concepts/pipelines/content/createRun/RunPageFooter.tsx +++ b/frontend/src/concepts/pipelines/content/createRun/RunPageFooter.tsx @@ -13,7 +13,7 @@ import { useGetSearchParamValues } from '~/utilities/useGetSearchParamValues'; import { PipelineRunType } from '~/pages/pipelines/global/runs'; import { SupportedArea, useIsAreaAvailable } from '~/concepts/areas'; import { isRunSchedule } from '~/concepts/pipelines/utils'; -import { routePipelineRunDetails, routePipelineRunJobDetails } from '~/routes'; +import { routePipelineRunDetails, routePipelineRecurringRunDetails } from '~/routes'; type RunPageFooterProps = { data: RunFormData; @@ -55,7 +55,7 @@ const RunPageFooter: React.FC = ({ data, contextPath }) => { handleSubmit(data, api) .then((resource) => { let detailsPath = isRunSchedule(resource) - ? routePipelineRunJobDetails(resource.recurring_run_id) + ? routePipelineRecurringRunDetails(resource.recurring_run_id) : routePipelineRunDetails(resource.run_id); if (isExperimentsAvailable && experimentId) { diff --git a/frontend/src/concepts/pipelines/content/createRun/submitUtils.ts b/frontend/src/concepts/pipelines/content/createRun/submitUtils.ts index f16b330a57..65d038849f 100644 --- a/frontend/src/concepts/pipelines/content/createRun/submitUtils.ts +++ b/frontend/src/concepts/pipelines/content/createRun/submitUtils.ts @@ -6,11 +6,11 @@ import { ScheduledType, } from '~/concepts/pipelines/content/createRun/types'; import { - CreatePipelineRunJobKFData, + CreatePipelineRecurringRunKFData, CreatePipelineRunKFData, DateTimeKF, InputDefinitionParameterType, - PipelineRunJobKFv2, + PipelineRecurringRunKFv2, PipelineRunKFv2, PipelineVersionKFv2, RecurringRunMode, @@ -55,10 +55,10 @@ export const convertDateDataToKFDateTime = (dateData?: RunDateTime): DateTimeKF return date.toISOString(); }; -const createJob = async ( +const createRecurringRun = async ( formData: SafeRunFormData, - createPipelineRunJob: PipelineAPIs['createPipelineRunJob'], -): Promise => { + createPipelineRecurringRun: PipelineAPIs['createPipelineRecurringRun'], +): Promise => { if (formData.runType.type !== RunTypeOption.SCHEDULED) { return Promise.reject(new Error('Cannot create a schedule with incomplete data.')); } @@ -68,7 +68,7 @@ const createJob = async ( const periodicScheduleIntervalTime = convertPeriodicTimeToSeconds(formData.runType.data.value); /* eslint-disable camelcase */ - const data: CreatePipelineRunJobKFData = { + const data: CreatePipelineRecurringRunKFData = { display_name: formData.nameDesc.name, description: formData.nameDesc.description, pipeline_version_reference: { @@ -107,14 +107,14 @@ const createJob = async ( }; /* eslint-enable camelcase */ - return createPipelineRunJob({}, data); + return createPipelineRecurringRun({}, data); }; /** Returns the relative path to navigate to from the namespace qualified route */ export const handleSubmit = ( formData: RunFormData, api: PipelineAPIs, -): Promise => { +): Promise => { if (!isFilledRunFormData(formData)) { throw new Error('Form data was incomplete.'); } @@ -123,7 +123,7 @@ export const handleSubmit = ( case RunTypeOption.ONE_TRIGGER: return createRun(formData, api.createPipelineRun); case RunTypeOption.SCHEDULED: - return createJob(formData, api.createPipelineRunJob); + return createRecurringRun(formData, api.createPipelineRecurringRun); default: // eslint-disable-next-line no-console console.error('Unknown run type', formData.runType); diff --git a/frontend/src/concepts/pipelines/content/createRun/useCloneRunData.ts b/frontend/src/concepts/pipelines/content/createRun/useCloneRunData.ts index 1b64908c82..fe173cd2b6 100644 --- a/frontend/src/concepts/pipelines/content/createRun/useCloneRunData.ts +++ b/frontend/src/concepts/pipelines/content/createRun/useCloneRunData.ts @@ -1,19 +1,20 @@ import { useParams } from 'react-router-dom'; import usePipelineRunById from '~/concepts/pipelines/apiHooks/usePipelineRunById'; -import { PipelineRunJobKFv2, PipelineRunKFv2 } from '~/concepts/pipelines/kfTypes'; -import usePipelineRunJobById from '~/concepts/pipelines/apiHooks/usePipelineRunJobById'; +import { PipelineRecurringRunKFv2, PipelineRunKFv2 } from '~/concepts/pipelines/kfTypes'; +import usePipelineRecurringRunById from '~/concepts/pipelines/apiHooks/usePipelineRecurringRunById'; const useCloneRunData = (): [ - run: PipelineRunKFv2 | PipelineRunJobKFv2 | null, + run: PipelineRunKFv2 | PipelineRecurringRunKFv2 | null, loaded: boolean, error: Error | undefined, ] => { const { runId, recurringRunId } = useParams(); const [run, runLoaded, runError] = usePipelineRunById(runId); - const [job, jobLoaded, jobError] = usePipelineRunJobById(recurringRunId); + const [recurringRun, recurringRunLoaded, recurringRunError] = + usePipelineRecurringRunById(recurringRunId); - if (jobLoaded || jobError) { - return [job, jobLoaded, jobError]; + if (recurringRunLoaded || recurringRunError) { + return [recurringRun, recurringRunLoaded, recurringRunError]; } if (runLoaded || runError) { return [run ?? null, runLoaded, runError]; diff --git a/frontend/src/concepts/pipelines/content/createRun/useRunFormData.ts b/frontend/src/concepts/pipelines/content/createRun/useRunFormData.ts index 2a36c49ee0..eb47ef6016 100644 --- a/frontend/src/concepts/pipelines/content/createRun/useRunFormData.ts +++ b/frontend/src/concepts/pipelines/content/createRun/useRunFormData.ts @@ -12,7 +12,7 @@ import { DateTimeKF, ExperimentKFv2, PipelineKFv2, - PipelineRunJobKFv2, + PipelineRecurringRunKFv2, PipelineRunKFv2, PipelineVersionKFv2, StorageStateKF, @@ -26,7 +26,7 @@ import { DEFAULT_TIME, } from '~/concepts/pipelines/content/createRun/const'; import { convertDateToTimeString, convertSecondsToPeriodicTime } from '~/utilities/time'; -import { isPipelineRunJob } from '~/concepts/pipelines/content/utils'; +import { isPipelineRecurringRun } from '~/concepts/pipelines/content/utils'; const parseKFTime = (kfTime?: DateTimeKF): RunDateTime | undefined => { if (!kfTime) { @@ -40,10 +40,10 @@ const parseKFTime = (kfTime?: DateTimeKF): RunDateTime | undefined => { const useUpdateRunType = ( setFunction: UpdateObjectAtPropAndValue, - initialData?: PipelineRunKFv2 | PipelineRunJobKFv2 | null, + initialData?: PipelineRunKFv2 | PipelineRecurringRunKFv2 | null, ): void => { React.useEffect(() => { - if (!initialData || !isPipelineRunJob(initialData)) { + if (!initialData || !isPipelineRecurringRun(initialData)) { return; } @@ -139,7 +139,7 @@ const useUpdatePipelineFormData = ( }; const useRunFormData = ( - run?: PipelineRunKFv2 | PipelineRunJobKFv2 | null, + run?: PipelineRunKFv2 | PipelineRecurringRunKFv2 | null, initialFormData?: Partial, ): GenericObjectState => { const { project } = usePipelinesAPI(); diff --git a/frontend/src/concepts/pipelines/content/pipelinesDetails/PipelineDetailsTitle.tsx b/frontend/src/concepts/pipelines/content/pipelinesDetails/PipelineDetailsTitle.tsx index 8bc8db18ab..81358d8474 100644 --- a/frontend/src/concepts/pipelines/content/pipelinesDetails/PipelineDetailsTitle.tsx +++ b/frontend/src/concepts/pipelines/content/pipelinesDetails/PipelineDetailsTitle.tsx @@ -4,13 +4,13 @@ import { PipelineRunKFv2, StorageStateKF } from '~/concepts/pipelines/kfTypes'; import { computeRunStatus } from '~/concepts/pipelines/content/utils'; import PipelineRunTypeLabel from '~/concepts/pipelines/content/PipelineRunTypeLabel'; -type RunJobTitleProps = { +type RecurringRunTitleProps = { run: PipelineRunKFv2; statusIcon?: boolean; pipelineRunLabel?: boolean; }; -const PipelineDetailsTitle: React.FC = ({ +const PipelineDetailsTitle: React.FC = ({ run, statusIcon, pipelineRunLabel, diff --git a/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRunJob/PipelineRunJobDetails.tsx b/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRecurringRun/PipelineRecurringRunDetails.tsx similarity index 79% rename from frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRunJob/PipelineRunJobDetails.tsx rename to frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRecurringRun/PipelineRecurringRunDetails.tsx index abb5335da2..a586654235 100644 --- a/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRunJob/PipelineRunJobDetails.tsx +++ b/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRecurringRun/PipelineRecurringRunDetails.tsx @@ -21,25 +21,26 @@ import MarkdownView from '~/components/MarkdownView'; import { PipelineCoreDetailsPageComponent } from '~/concepts/pipelines/content/types'; import DeletePipelineRunsModal from '~/concepts/pipelines/content/DeletePipelineRunsModal'; import { usePipelinesAPI } from '~/concepts/pipelines/context'; -import usePipelineRunJobById from '~/concepts/pipelines/apiHooks/usePipelineRunJobById'; import usePipelineVersionById from '~/concepts/pipelines/apiHooks/usePipelineVersionById'; import { PipelineRunType } from '~/pages/pipelines/global/runs'; import { routePipelineRunsNamespace, routePipelineVersionRunsNamespace } from '~/routes'; import SelectedTaskDrawerContent from '~/concepts/pipelines/content/pipelinesDetails/pipeline/SelectedTaskDrawerContent'; import { PipelineRunDetailsTabs } from '~/concepts/pipelines/content/pipelinesDetails/pipelineRun/PipelineRunDetailsTabs'; -import PipelineRunJobDetailsActions from './PipelineRunJobDetailsActions'; +import usePipelineRecurringRunById from '~/concepts/pipelines/apiHooks/usePipelineRecurringRunById'; +import PipelineRecurringRunDetailsActions from './PipelineRecurringRunDetailsActions'; -const PipelineRunJobDetails: PipelineCoreDetailsPageComponent = ({ +const PipelineRecurringRunDetails: PipelineCoreDetailsPageComponent = ({ breadcrumbPath, contextPath, }) => { const { recurringRunId } = useParams(); const navigate = useNavigate(); const { namespace } = usePipelinesAPI(); - const [job, jobLoaded, jobError] = usePipelineRunJobById(recurringRunId); + const [recurringRun, recurringRunLoaded, recurringRunError] = + usePipelineRecurringRunById(recurringRunId); const [version, versionLoaded, versionError] = usePipelineVersionById( - job?.pipeline_version_reference.pipeline_id, - job?.pipeline_version_reference.pipeline_version_id, + recurringRun?.pipeline_version_reference.pipeline_id, + recurringRun?.pipeline_version_reference.pipeline_version_id, ); const [deleting, setDeleting] = React.useState(false); const [selectedId, setSelectedId] = React.useState(null); @@ -53,8 +54,8 @@ const PipelineRunJobDetails: PipelineCoreDetailsPageComponent = ({ const getFirstNode = (firstId: string) => nodes.find((n) => n.id === firstId)?.data?.pipelineTask; - const loaded = versionLoaded && jobLoaded; - const error = versionError || jobError; + const loaded = versionLoaded && recurringRunLoaded; + const error = versionError || recurringRunError; if (!loaded && !error) { return ( @@ -88,8 +89,14 @@ const PipelineRunJobDetails: PipelineCoreDetailsPageComponent = ({ } > : ''} + title={recurringRun?.display_name} + description={ + recurringRun ? ( + + ) : ( + '' + ) + } loaded={loaded} loadError={error} breadcrumb={ @@ -111,13 +118,15 @@ const PipelineRunJobDetails: PipelineCoreDetailsPageComponent = ({ 'Loading...' )} - {job?.display_name ?? 'Loading...'} + + {recurringRun?.display_name ?? 'Loading...'} + } headerAction={ loaded && ( - setDeleting(true)} /> ) @@ -125,7 +134,7 @@ const PipelineRunJobDetails: PipelineCoreDetailsPageComponent = ({ empty={false} > { if (deleteComplete) { navigate(contextPath ?? routePipelineRunsNamespace(namespace)); @@ -161,4 +170,4 @@ const PipelineRunJobDetails: PipelineCoreDetailsPageComponent = ({ ); }; -export default PipelineRunJobDetails; +export default PipelineRecurringRunDetails; diff --git a/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRunJob/PipelineRunJobDetailsActions.tsx b/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRecurringRun/PipelineRecurringRunDetailsActions.tsx similarity index 80% rename from frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRunJob/PipelineRunJobDetailsActions.tsx rename to frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRecurringRun/PipelineRecurringRunDetailsActions.tsx index 6ec286d0a2..4837293615 100644 --- a/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRunJob/PipelineRunJobDetailsActions.tsx +++ b/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRecurringRun/PipelineRecurringRunDetailsActions.tsx @@ -7,20 +7,20 @@ import { } from '@patternfly/react-core/deprecated'; import { useNavigate, useParams } from 'react-router-dom'; import { usePipelinesAPI } from '~/concepts/pipelines/context'; -import { PipelineRunJobKFv2 } from '~/concepts/pipelines/kfTypes'; +import { PipelineRecurringRunKFv2 } from '~/concepts/pipelines/kfTypes'; import { cloneScheduleRoute } from '~/routes'; import { PipelineRunSearchParam } from '~/concepts/pipelines/content/types'; import { PipelineRunType } from '~/pages/pipelines/global/runs'; import { useIsAreaAvailable, SupportedArea } from '~/concepts/areas'; -type PipelineRunJobDetailsActionsProps = { - job?: PipelineRunJobKFv2; +type PipelineRecurringRunDetailsActionsProps = { + recurringRun?: PipelineRecurringRunKFv2; onDelete: () => void; }; -const PipelineRunJobDetailsActions: React.FC = ({ +const PipelineRecurringRunDetailsActions: React.FC = ({ onDelete, - job, + recurringRun, }) => { const navigate = useNavigate(); const { namespace } = usePipelinesAPI(); @@ -30,7 +30,7 @@ const PipelineRunJobDetailsActions: React.FC return ( setOpen(false)} toggle={ setOpen(!open)}> @@ -40,7 +40,7 @@ const PipelineRunJobDetailsActions: React.FC isOpen={open} position="right" dropdownItems={ - !job + !recurringRun ? [] : [ navigate({ pathname: cloneScheduleRoute( namespace, - job.recurring_run_id, + recurringRun.recurring_run_id, isExperimentsAvailable ? experimentId : undefined, ), search: `?${PipelineRunSearchParam.RunType}=${PipelineRunType.SCHEDULED}`, @@ -68,4 +68,4 @@ const PipelineRunJobDetailsActions: React.FC ); }; -export default PipelineRunJobDetailsActions; +export default PipelineRecurringRunDetailsActions; diff --git a/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/PipelineRunDetails.tsx b/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/PipelineRunDetails.tsx index ebd7bb8098..c280758a4c 100644 --- a/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/PipelineRunDetails.tsx +++ b/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/PipelineRunDetails.tsx @@ -29,11 +29,11 @@ import usePipelineVersionById from '~/concepts/pipelines/apiHooks/usePipelineVer import { usePipelineTaskTopology } from '~/concepts/pipelines/topology'; import { PipelineRunType } from '~/pages/pipelines/global/runs/types'; import { routePipelineRunsNamespace, routePipelineVersionRunsNamespace } from '~/routes'; -import PipelineJobReferenceName from '~/concepts/pipelines/content/PipelineJobReferenceName'; import useExecutionsForPipelineRun from '~/concepts/pipelines/content/pipelinesDetails/pipelineRun/useExecutionsForPipelineRun'; import { useGetEventsByExecutionIds } from '~/concepts/pipelines/apiHooks/mlmd/useGetEventsByExecutionId'; import { PipelineTopology } from '~/concepts/topology'; import { StorageStateKF } from '~/concepts/pipelines/kfTypes'; +import PipelineRecurringRunReferenceName from '~/concepts/pipelines/content/PipelineRecurringRunReferenceName'; import { usePipelineRunArtifacts } from './artifacts'; import { PipelineRunDetailsTabs } from './PipelineRunDetailsTabs'; @@ -119,7 +119,7 @@ const PipelineRunDetails: PipelineCoreDetailsPageComponent = ({ breadcrumbPath, } subtext={ run && ( - diff --git a/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/PipelineRunDetailsTabs.tsx b/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/PipelineRunDetailsTabs.tsx index 908cd4525a..a6064d33a7 100644 --- a/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/PipelineRunDetailsTabs.tsx +++ b/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/PipelineRunDetailsTabs.tsx @@ -4,11 +4,11 @@ import { Tabs, Tab, TabTitleText, TabContentBody, TabContent } from '@patternfly import PipelineDetailsYAML from '~/concepts/pipelines/content/pipelinesDetails/PipelineDetailsYAML'; import { - PipelineRunJobKFv2, + PipelineRecurringRunKFv2, PipelineRunKFv2, PipelineSpecVariable, } from '~/concepts/pipelines/kfTypes'; -import { isPipelineRunJob } from '~/concepts/pipelines/content/utils'; +import { isPipelineRecurringRun } from '~/concepts/pipelines/content/utils'; import PipelineRunTabDetails from './PipelineRunTabDetails'; enum DetailsTabKey { @@ -18,7 +18,7 @@ enum DetailsTabKey { } interface PipelineRunDetailsTabsProps { - run: PipelineRunKFv2 | PipelineRunJobKFv2 | null; + run: PipelineRunKFv2 | PipelineRecurringRunKFv2 | null; pipelineSpec: PipelineSpecVariable | undefined; graphContent: React.ReactNode; } @@ -29,7 +29,7 @@ export const PipelineRunDetailsTabs: React.FC = ({ graphContent, }) => { const [activeKey, setActiveKey] = React.useState(DetailsTabKey.Graph); - const isJob = run && isPipelineRunJob(run); + const isRecurringRun = run && isPipelineRecurringRun(run); return ( <> @@ -57,7 +57,7 @@ export const PipelineRunDetailsTabs: React.FC = ({ - {!isJob && pipelineSpec && ( + {!isRecurringRun && pipelineSpec && ( = ({ run, work : []), { key: 'Run ID', value: runId }, { key: 'Workflow name', value: workflowName }, - ...(!isPipelineRunJob(run) + ...(!isPipelineRecurringRun(run) ? [ { key: 'Started', value: asTimestamp(new Date(run.created_at)) }, { @@ -99,7 +99,7 @@ const PipelineRunTabDetails: React.FC = ({ run, work key: 'Run trigger enabled', value: run.status === RecurringRunStatus.ENABLED ? 'Yes' : 'No', }, - { key: 'Trigger', value: }, + { key: 'Trigger', value: }, ]), ]; diff --git a/frontend/src/concepts/pipelines/content/tables/columns.ts b/frontend/src/concepts/pipelines/content/tables/columns.ts index 46925056c6..fee4c39384 100644 --- a/frontend/src/concepts/pipelines/content/tables/columns.ts +++ b/frontend/src/concepts/pipelines/content/tables/columns.ts @@ -7,7 +7,7 @@ import { import { PipelineVersionKFv2, PipelineKFv2, - PipelineRunJobKFv2, + PipelineRecurringRunKFv2, PipelineRunKFv2, ExperimentKFv2, } from '~/concepts/pipelines/kfTypes'; @@ -177,7 +177,7 @@ export function getExperimentRunColumns( ]; } -export const pipelineRunJobColumns: SortableData[] = [ +export const pipelineRecurringRunColumns: SortableData[] = [ checkboxTableColumn(), { label: 'Schedule', diff --git a/frontend/src/concepts/pipelines/content/tables/pipelineRunJob/PipelineRunJobTable.tsx b/frontend/src/concepts/pipelines/content/tables/pipelineRecurringRun/PipelineRecurringRunTable.tsx similarity index 68% rename from frontend/src/concepts/pipelines/content/tables/pipelineRunJob/PipelineRunJobTable.tsx rename to frontend/src/concepts/pipelines/content/tables/pipelineRecurringRun/PipelineRecurringRunTable.tsx index 51eeda568c..4b4f21ca4a 100644 --- a/frontend/src/concepts/pipelines/content/tables/pipelineRunJob/PipelineRunJobTable.tsx +++ b/frontend/src/concepts/pipelines/content/tables/pipelineRecurringRun/PipelineRecurringRunTable.tsx @@ -1,11 +1,8 @@ import * as React from 'react'; import { TableVariant } from '@patternfly/react-table'; import { useParams } from 'react-router-dom'; -import { PipelineRunJobKFv2 } from '~/concepts/pipelines/kfTypes'; -import { pipelineRunJobColumns } from '~/concepts/pipelines/content/tables/columns'; +import { PipelineRecurringRunKFv2 } from '~/concepts/pipelines/kfTypes'; import { getTableColumnSort, useCheckboxTable, TableBase } from '~/components/table'; -import PipelineRunJobTableRow from '~/concepts/pipelines/content/tables/pipelineRunJob/PipelineRunJobTableRow'; -import PipelineRunJobTableToolbar from '~/concepts/pipelines/content/tables/pipelineRunJob/PipelineRunJobTableToolbar'; import DashboardEmptyTableView from '~/concepts/dashboard/DashboardEmptyTableView'; import DeletePipelineRunsModal from '~/concepts/pipelines/content/DeletePipelineRunsModal'; import { usePipelinesAPI } from '~/concepts/pipelines/context'; @@ -14,9 +11,12 @@ import { PipelinesFilter } from '~/concepts/pipelines/types'; import usePipelineFilter from '~/concepts/pipelines/content/tables/usePipelineFilter'; import SimpleMenuActions from '~/components/SimpleMenuActions'; import { useSetVersionFilter } from '~/concepts/pipelines/content/tables/useSetVersionFilter'; +import { pipelineRecurringRunColumns } from '~/concepts/pipelines/content/tables/columns'; +import PipelineRecurringRunTableRow from './PipelineRecurringRunTableRow'; +import PipelineRecurringRunTableToolbar from './PipelineRecurringRunTableToolbar'; type PipelineRunTableProps = { - jobs: PipelineRunJobKFv2[]; + recurringRuns: PipelineRecurringRunKFv2[]; loading?: boolean; totalSize: number; page: number; @@ -30,8 +30,8 @@ type PipelineRunTableProps = { setFilter: (filter?: PipelinesFilter) => void; }; -const PipelineRunJobTable: React.FC = ({ - jobs, +const PipelineRecurringRunTable: React.FC = ({ + recurringRuns, loading, totalSize, page, @@ -50,13 +50,13 @@ const PipelineRunJobTable: React.FC = ({ toggleSelection, isSelected, // eslint-disable-next-line camelcase - } = useCheckboxTable(jobs.map(({ recurring_run_id }) => recurring_run_id)); - const [deleteResources, setDeleteResources] = React.useState([]); + } = useCheckboxTable(recurringRuns.map(({ recurring_run_id }) => recurring_run_id)); + const [deleteResources, setDeleteResources] = React.useState([]); useSetVersionFilter(filterToolbarProps.onFilterUpdate); const getColumns = () => { - let columns = pipelineRunJobColumns; + let columns = pipelineRecurringRunColumns; if (pipelineVersionId) { columns = columns.filter((column) => column.field !== 'pipeline_version'); } @@ -78,14 +78,14 @@ const PipelineRunJobTable: React.FC = ({ }} onPerPageSelect={(_, newSize) => setPageSize(newSize)} itemCount={totalSize} - data={jobs} + data={recurringRuns} columns={getColumns()} enablePagination emptyTableView={ } toolbarContent={ - = ({ onClick: () => setDeleteResources( selections - .map((selection) => - // eslint-disable-next-line camelcase - jobs.find(({ recurring_run_id }) => recurring_run_id === selection), + .map((selection) => + recurringRuns.find( + // eslint-disable-next-line camelcase + ({ recurring_run_id }) => recurring_run_id === selection, + ), ) - .filter((v): v is PipelineRunJobKFv2 => !!v), + .filter((v): v is PipelineRecurringRunKFv2 => !!v), ), isDisabled: !selections.length, }, @@ -111,17 +113,17 @@ const PipelineRunJobTable: React.FC = ({ } /> } - rowRenderer={(job) => ( - toggleSelection(job.recurring_run_id)} - onDelete={() => setDeleteResources([job])} - job={job} + rowRenderer={(recurringRun) => ( + toggleSelection(recurringRun.recurring_run_id)} + onDelete={() => setDeleteResources([recurringRun])} + recurringRun={recurringRun} /> )} variant={TableVariant.compact} - getColumnSort={getTableColumnSort({ columns: pipelineRunJobColumns, ...tableProps })} + getColumnSort={getTableColumnSort({ columns: pipelineRecurringRunColumns, ...tableProps })} data-testid="schedules-table" /> @@ -139,4 +141,4 @@ const PipelineRunJobTable: React.FC = ({ ); }; -export default PipelineRunJobTable; +export default PipelineRecurringRunTable; diff --git a/frontend/src/concepts/pipelines/content/tables/pipelineRunJob/PipelineRunJobTableRow.tsx b/frontend/src/concepts/pipelines/content/tables/pipelineRecurringRun/PipelineRecurringRunTableRow.tsx similarity index 71% rename from frontend/src/concepts/pipelines/content/tables/pipelineRunJob/PipelineRunJobTableRow.tsx rename to frontend/src/concepts/pipelines/content/tables/pipelineRecurringRun/PipelineRecurringRunTableRow.tsx index db38d95685..f3f9d9054d 100644 --- a/frontend/src/concepts/pipelines/content/tables/pipelineRunJob/PipelineRunJobTableRow.tsx +++ b/frontend/src/concepts/pipelines/content/tables/pipelineRecurringRun/PipelineRecurringRunTableRow.tsx @@ -1,14 +1,8 @@ import * as React from 'react'; import { ActionsColumn, TableText, Td, Tr } from '@patternfly/react-table'; import { Link, useNavigate, useParams } from 'react-router-dom'; -import { PipelineRunJobKFv2 } from '~/concepts/pipelines/kfTypes'; +import { PipelineRecurringRunKFv2 } from '~/concepts/pipelines/kfTypes'; import { TableRowTitleDescription, CheckboxTd } from '~/components/table'; -import { - JobCreated, - RunJobScheduled, - RunJobStatus, - RunJobTrigger, -} from '~/concepts/pipelines/content/tables/renderUtils'; import { usePipelinesAPI } from '~/concepts/pipelines/context'; import usePipelineRunVersionInfo from '~/concepts/pipelines/content/tables/usePipelineRunVersionInfo'; import { PipelineVersionLink } from '~/concepts/pipelines/content/PipelineVersionLink'; @@ -16,43 +10,53 @@ import { PipelineRunType } from '~/pages/pipelines/global/runs'; import { PipelineRunSearchParam } from '~/concepts/pipelines/content/types'; import { cloneScheduleRoute, scheduleDetailsRoute } from '~/routes'; import { SupportedArea, useIsAreaAvailable } from '~/concepts/areas'; +import { + RecurringRunCreated, + RecurringRunScheduled, + RecurringRunStatus, + RecurringRunTrigger, +} from '~/concepts/pipelines/content/tables/renderUtils'; -type PipelineRunJobTableRowProps = { +type PipelineRecurringRunTableRowProps = { isChecked: boolean; onToggleCheck: () => void; onDelete: () => void; - job: PipelineRunJobKFv2; + recurringRun: PipelineRecurringRunKFv2; }; -const PipelineRunJobTableRow: React.FC = ({ +const PipelineRecurringRunTableRow: React.FC = ({ isChecked, onToggleCheck, onDelete, - job, + recurringRun, }) => { const navigate = useNavigate(); const { experimentId, pipelineVersionId } = useParams(); const { namespace, api, refreshAllAPI } = usePipelinesAPI(); - const { version, loaded, error } = usePipelineRunVersionInfo(job); + const { version, loaded, error } = usePipelineRunVersionInfo(recurringRun); const isExperimentsAvailable = useIsAreaAvailable(SupportedArea.PIPELINE_EXPERIMENTS).status; return ( - + - {job.display_name} + {recurringRun.display_name} } - description={job.description} + description={recurringRun.description} descriptionAsMarkdown /> @@ -67,21 +71,23 @@ const PipelineRunJobTableRow: React.FC = ({ )} - + - + - - api.updatePipelineRunJob({}, job.recurring_run_id, checked).then(refreshAllAPI) + api + .updatePipelineRecurringRun({}, recurringRun.recurring_run_id, checked) + .then(refreshAllAPI) } /> - + = ({ navigate({ pathname: cloneScheduleRoute( namespace, - job.recurring_run_id, + recurringRun.recurring_run_id, isExperimentsAvailable ? experimentId : undefined, ), search: `?${PipelineRunSearchParam.RunType}=${PipelineRunType.SCHEDULED}`, @@ -119,4 +125,4 @@ const PipelineRunJobTableRow: React.FC = ({ ); }; -export default PipelineRunJobTableRow; +export default PipelineRecurringRunTableRow; diff --git a/frontend/src/concepts/pipelines/content/tables/pipelineRunJob/PipelineRunJobTableToolbar.tsx b/frontend/src/concepts/pipelines/content/tables/pipelineRecurringRun/PipelineRecurringRunTableToolbar.tsx similarity index 87% rename from frontend/src/concepts/pipelines/content/tables/pipelineRunJob/PipelineRunJobTableToolbar.tsx rename to frontend/src/concepts/pipelines/content/tables/pipelineRecurringRun/PipelineRecurringRunTableToolbar.tsx index 2e4b7f74f9..3c26896c60 100644 --- a/frontend/src/concepts/pipelines/content/tables/pipelineRunJob/PipelineRunJobTableToolbar.tsx +++ b/frontend/src/concepts/pipelines/content/tables/pipelineRecurringRun/PipelineRecurringRunTableToolbar.tsx @@ -13,11 +13,11 @@ export type FilterProps = Pick< 'filterData' | 'onFilterUpdate' | 'onClearFilters' >; -interface PipelineRunJobTableToolbarProps extends FilterProps { +interface PipelineRecurringRunTableToolbarProps extends FilterProps { dropdownActions: React.ReactNode; } -const PipelineRunJobTableToolbar: React.FC = ({ +const PipelineRecurringRunTableToolbar: React.FC = ({ dropdownActions, ...toolbarProps }) => { @@ -61,9 +61,9 @@ const PipelineRunJobTableToolbar: React.FC = ({ )} - {dropdownActions} + {dropdownActions} ); }; -export default PipelineRunJobTableToolbar; +export default PipelineRecurringRunTableToolbar; diff --git a/frontend/src/concepts/pipelines/content/tables/pipelineRecurringRun/usePipelineRecurringRunTable.ts b/frontend/src/concepts/pipelines/content/tables/pipelineRecurringRun/usePipelineRecurringRunTable.ts new file mode 100644 index 0000000000..af585703ed --- /dev/null +++ b/frontend/src/concepts/pipelines/content/tables/pipelineRecurringRun/usePipelineRecurringRunTable.ts @@ -0,0 +1,10 @@ +import usePipelineRecurringRuns from '~/concepts/pipelines/apiHooks/usePipelineRecurringRuns'; +import { useCreatePipelineRunTable } from '~/concepts/pipelines/content/tables/usePipelineTable'; +import { PipelineRecurringRunKFv2 } from '~/concepts/pipelines/kfTypes'; +import { PipelineRunOptions } from '~/concepts/pipelines/types'; + +export const usePipelineScheduledRunsTable = ( + options?: PipelineRunOptions, + limit?: number, +): ReturnType> => + useCreatePipelineRunTable(usePipelineRecurringRuns, options, limit); diff --git a/frontend/src/concepts/pipelines/content/tables/pipelineRun/PipelineRunTableRowTitle.tsx b/frontend/src/concepts/pipelines/content/tables/pipelineRun/PipelineRunTableRowTitle.tsx index b388358e50..dda4a54046 100644 --- a/frontend/src/concepts/pipelines/content/tables/pipelineRun/PipelineRunTableRowTitle.tsx +++ b/frontend/src/concepts/pipelines/content/tables/pipelineRun/PipelineRunTableRowTitle.tsx @@ -5,9 +5,9 @@ import { TableRowTitleDescription } from '~/components/table'; import { PipelineRunKFv2 } from '~/concepts/pipelines/kfTypes'; import { usePipelinesAPI } from '~/concepts/pipelines/context'; import PipelineRunTypeLabel from '~/concepts/pipelines/content/PipelineRunTypeLabel'; -import PipelineJobReferenceName from '~/concepts/pipelines/content/PipelineJobReferenceName'; import { SupportedArea, useIsAreaAvailable } from '~/concepts/areas'; import { runDetailsRoute } from '~/routes'; +import PipelineRecurringRunReferenceName from '~/concepts/pipelines/content/PipelineRecurringRunReferenceName'; type PipelineRunTableRowTitleProps = { run: PipelineRunKFv2; @@ -32,7 +32,7 @@ const PipelineRunTableRowTitle: React.FC = ({ run } subtitle={ - diff --git a/frontend/src/concepts/pipelines/content/tables/pipelineRunJob/usePipelineRunJobTable.ts b/frontend/src/concepts/pipelines/content/tables/pipelineRunJob/usePipelineRunJobTable.ts deleted file mode 100644 index f0c826b0a0..0000000000 --- a/frontend/src/concepts/pipelines/content/tables/pipelineRunJob/usePipelineRunJobTable.ts +++ /dev/null @@ -1,10 +0,0 @@ -import usePipelineRunJobs from '~/concepts/pipelines/apiHooks/usePipelineRunJobs'; -import { useCreatePipelineRunTable } from '~/concepts/pipelines/content/tables/usePipelineTable'; -import { PipelineRunJobKFv2 } from '~/concepts/pipelines/kfTypes'; -import { PipelineRunOptions } from '~/concepts/pipelines/types'; - -export const usePipelineScheduledRunsTable = ( - options?: PipelineRunOptions, - limit?: number, -): ReturnType> => - useCreatePipelineRunTable(usePipelineRunJobs, options, limit); diff --git a/frontend/src/concepts/pipelines/content/tables/renderUtils.tsx b/frontend/src/concepts/pipelines/content/tables/renderUtils.tsx index 3cbd17ca0a..f537ba0a61 100644 --- a/frontend/src/concepts/pipelines/content/tables/renderUtils.tsx +++ b/frontend/src/concepts/pipelines/content/tables/renderUtils.tsx @@ -16,12 +16,12 @@ import { printSeconds, relativeDuration, relativeTime } from '~/utilities/time'; import { PipelineRunKFv2, runtimeStateLabels, - PipelineRunJobKFv2, + PipelineRecurringRunKFv2, RecurringRunMode, } from '~/concepts/pipelines/kfTypes'; import { getRunDuration, - getPipelineRunJobScheduledState, + getPipelineRecurringRunScheduledState, ScheduledState, } from '~/concepts/pipelines/content/tables/utils'; import { computeRunStatus } from '~/concepts/pipelines/content/utils'; @@ -32,7 +32,7 @@ export const NoRunContent = (): React.JSX.Element => <>-; type ExtraProps = Record; type RunUtil

= React.FC<{ run: PipelineRunKFv2 } & P>; -type RunJobUtil

= React.FC<{ job: PipelineRunJobKFv2 } & P>; +type RecurringRunUtil

= React.FC<{ recurringRun: PipelineRecurringRunKFv2 } & P>; export const RunStatus: RunUtil<{ justIcon?: boolean }> = ({ justIcon, run }) => { const { icon, status, label, details, createdAt } = computeRunStatus(run); @@ -78,25 +78,27 @@ export const RunCreated: RunUtil = ({ run }) => { return ; }; -export const JobCreated: RunJobUtil = ({ job }) => { - const createdDate = new Date(job.created_at); +export const RecurringRunCreated: RecurringRunUtil = ({ recurringRun }) => { + const createdDate = new Date(recurringRun.created_at); return ; }; -export const RunJobTrigger: RunJobUtil = ({ job }) => { - if (job.trigger.periodic_schedule) { - return <>Every {printSeconds(parseInt(job.trigger.periodic_schedule.interval_second))}; +export const RecurringRunTrigger: RecurringRunUtil = ({ recurringRun }) => { + if (recurringRun.trigger.periodic_schedule) { + return ( + <>Every {printSeconds(parseInt(recurringRun.trigger.periodic_schedule.interval_second))} + ); } - if (job.trigger.cron_schedule) { + if (recurringRun.trigger.cron_schedule) { // TODO: convert Cron into readable text - return <>Cron {job.trigger.cron_schedule.cron}; + return <>Cron {recurringRun.trigger.cron_schedule.cron}; } return ; }; -export const RunJobScheduled: RunJobUtil = ({ job }) => { - const [state, startDate, endDate] = getPipelineRunJobScheduledState(job); +export const RecurringRunScheduled: RecurringRunUtil = ({ recurringRun }) => { + const [state, startDate, endDate] = getPipelineRecurringRunScheduledState(recurringRun); switch (state) { case ScheduledState.ENDED: @@ -127,15 +129,14 @@ export const RunJobScheduled: RunJobUtil = ({ job }) => { return ; }; -export const RunJobStatus: RunJobUtil<{ onToggle: (value: boolean) => Promise }> = ({ - job, - onToggle, -}) => { +export const RecurringRunStatus: RecurringRunUtil<{ + onToggle: (value: boolean) => Promise; +}> = ({ recurringRun, onToggle }) => { const [error, setError] = React.useState(null); const [isChangingFlag, setIsChangingFlag] = React.useState(false); const isExperimentArchived = useContextExperimentArchived(); - const isEnabled = job.mode === RecurringRunMode.ENABLE; + const isEnabled = recurringRun.mode === RecurringRunMode.ENABLE; React.useEffect(() => { // When the network updates, if we are currently locked fetching, disable it so we can accept the change setIsChangingFlag((v) => (v ? false : v)); @@ -143,9 +144,9 @@ export const RunJobStatus: RunJobUtil<{ onToggle: (value: boolean) => Promise - + { diff --git a/frontend/src/concepts/pipelines/content/tables/usePipelineRunVersionInfo.ts b/frontend/src/concepts/pipelines/content/tables/usePipelineRunVersionInfo.ts index a75d05b441..b9a38dfe1a 100644 --- a/frontend/src/concepts/pipelines/content/tables/usePipelineRunVersionInfo.ts +++ b/frontend/src/concepts/pipelines/content/tables/usePipelineRunVersionInfo.ts @@ -1,13 +1,13 @@ import * as React from 'react'; import { - PipelineRunJobKFv2, + PipelineRecurringRunKFv2, PipelineRunKFv2, PipelineVersionKFv2, } from '~/concepts/pipelines/kfTypes'; import { PipelineRunVersionsContext } from '~/pages/pipelines/global/runs/PipelineRunVersionsContext'; const usePipelineRunVersionInfo = ( - run: PipelineRunKFv2 | PipelineRunJobKFv2 | null, + run: PipelineRunKFv2 | PipelineRecurringRunKFv2 | null, ): { version: PipelineVersionKFv2 | undefined; loaded: boolean; diff --git a/frontend/src/concepts/pipelines/content/tables/utils.ts b/frontend/src/concepts/pipelines/content/tables/utils.ts index f495d7e870..c26a3698ef 100644 --- a/frontend/src/concepts/pipelines/content/tables/utils.ts +++ b/frontend/src/concepts/pipelines/content/tables/utils.ts @@ -1,4 +1,4 @@ -import { PipelineRunJobKFv2, PipelineRunKFv2 } from '~/concepts/pipelines/kfTypes'; +import { PipelineRecurringRunKFv2, PipelineRunKFv2 } from '~/concepts/pipelines/kfTypes'; export const getRunDuration = (run: PipelineRunKFv2): number => { const finishedDate = new Date(run.finished_at); @@ -11,15 +11,22 @@ export const getRunDuration = (run: PipelineRunKFv2): number => { return finishedDate.getTime() - createdDate.getTime(); }; -export const getPipelineRunJobStartTime = (job: PipelineRunJobKFv2): Date | null => { +export const getPipelineRecurringRunStartTime = ( + recurringRun: PipelineRecurringRunKFv2, +): Date | null => { const startTime = - job.trigger.cron_schedule?.start_time || job.trigger.periodic_schedule?.start_time; + recurringRun.trigger.cron_schedule?.start_time || + recurringRun.trigger.periodic_schedule?.start_time; return startTime ? new Date(startTime) : null; }; -export const getPipelineRunJobEndTime = (job: PipelineRunJobKFv2): Date | null => { - const endTime = job.trigger.cron_schedule?.end_time || job.trigger.periodic_schedule?.end_time; +export const getPipelineRecurringRunEndTime = ( + recurringRun: PipelineRecurringRunKFv2, +): Date | null => { + const endTime = + recurringRun.trigger.cron_schedule?.end_time || + recurringRun.trigger.periodic_schedule?.end_time; return endTime ? new Date(endTime) : null; }; @@ -36,11 +43,11 @@ export enum PipelineRunLabels { } const inPast = (date: Date | null): boolean => (date ? date.getTime() - Date.now() <= 0 : false); -export const getPipelineRunJobScheduledState = ( - job: PipelineRunJobKFv2, +export const getPipelineRecurringRunScheduledState = ( + recurringRun: PipelineRecurringRunKFv2, ): [state: ScheduledState, started: Date | null, ended: Date | null] => { - const startDate = getPipelineRunJobStartTime(job); - const endDate = getPipelineRunJobEndTime(job); + const startDate = getPipelineRecurringRunStartTime(recurringRun); + const endDate = getPipelineRecurringRunEndTime(recurringRun); const startDateInPast = inPast(startDate); const endDateInPast = inPast(endDate); @@ -60,7 +67,7 @@ export const getPipelineRunJobScheduledState = ( return [state, startDate, endDate]; }; -export const getPipelineJobExecutionCount = (resourceName: string): string | null => { +export const getPipelineRecurringRunExecutionCount = (resourceName: string): string | null => { const regex = /(\w+)(?:-[^-]*)?$/; const match = resourceName.match(regex); return match ? match[1] : null; diff --git a/frontend/src/concepts/pipelines/content/utils.tsx b/frontend/src/concepts/pipelines/content/utils.tsx index 71196ca67c..ef0b73ea5d 100644 --- a/frontend/src/concepts/pipelines/content/utils.tsx +++ b/frontend/src/concepts/pipelines/content/utils.tsx @@ -10,7 +10,7 @@ import { import { Icon, LabelProps } from '@patternfly/react-core'; import { PipelineCoreResourceKFv2, - PipelineRunJobKFv2, + PipelineRecurringRunKFv2, PipelineRunKFv2, RuntimeStateKF, runtimeStateLabels, @@ -101,6 +101,7 @@ export const getPipelineResourceUniqueID = (resource: PipelineCoreResourceKFv2): export const isPipelineRun = (resource: PipelineCoreResourceKFv2): resource is PipelineRunKFv2 => 'run_id' in resource; -export const isPipelineRunJob = ( +export const isPipelineRecurringRun = ( resource: PipelineCoreResourceKFv2, -): resource is PipelineRunJobKFv2 => 'recurring_run_id' in resource && !('run_id' in resource); +): resource is PipelineRecurringRunKFv2 => + 'recurring_run_id' in resource && !('run_id' in resource); diff --git a/frontend/src/concepts/pipelines/context/PipelinesContext.tsx b/frontend/src/concepts/pipelines/context/PipelinesContext.tsx index c58d9c74b8..b2157be3d0 100644 --- a/frontend/src/concepts/pipelines/context/PipelinesContext.tsx +++ b/frontend/src/concepts/pipelines/context/PipelinesContext.tsx @@ -17,15 +17,17 @@ import ViewPipelineServerModal from '~/concepts/pipelines/content/ViewPipelineSe import useSyncPreferredProject from '~/concepts/projects/useSyncPreferredProject'; import useManageElyraSecret from '~/concepts/pipelines/context/useManageElyraSecret'; import { deleteServer } from '~/concepts/pipelines/utils'; -import useJobRelatedInformation from '~/concepts/pipelines/context/useJobRelatedInformation'; import { conditionalArea, SupportedArea } from '~/concepts/areas'; import { DEV_MODE } from '~/utilities/const'; import { MetadataStoreServicePromiseClient } from '~/third_party/mlmd'; import usePipelineAPIState, { PipelineAPIState } from './usePipelineAPIState'; import usePipelineNamespaceCR, { dspaLoaded, hasServerTimedOut } from './usePipelineNamespaceCR'; import usePipelinesAPIRoute from './usePipelinesAPIRoute'; +import useRecurringRunRelatedInformation from './useRecurringRunRelatedInformation'; -type GetJobInformationType = ReturnType['getJobInformation']; +type GetRecurringRunInformationType = ReturnType< + typeof useRecurringRunRelatedInformation +>['getRecurringRunInformation']; type PipelineContext = { hasCR: boolean; @@ -38,7 +40,7 @@ type PipelineContext = { project: ProjectKind; refreshState: () => Promise; refreshAPIState: () => void; - getJobInformation: GetJobInformationType; + getRecurringRunInformation: GetRecurringRunInformationType; apiState: PipelineAPIState; metadataStoreServiceClient: MetadataStoreServicePromiseClient; }; @@ -55,7 +57,7 @@ const PipelinesContext = React.createContext({ project: null as unknown as ProjectKind, refreshState: async () => undefined, refreshAPIState: () => undefined, - getJobInformation: () => ({ + getRecurringRunInformation: () => ({ loading: false, data: null, }), @@ -117,7 +119,7 @@ export const PipelineContextProvider = conditionalArea @@ -170,7 +172,7 @@ type UsePipelinesAPI = PipelineAPIState & { * Allows agnostic functionality to request all watched API to be reacquired. * Triggering this will invalidate the memo for API - pay attention to only calling it once per need. */ - getJobInformation: GetJobInformationType; + getRecurringRunInformation: GetRecurringRunInformationType; refreshAllAPI: () => void; metadataStoreServiceClient: MetadataStoreServicePromiseClient; }; @@ -186,7 +188,7 @@ export const usePipelinesAPI = (): UsePipelinesAPI => { namespace, project, refreshAPIState: refreshAllAPI, - getJobInformation, + getRecurringRunInformation, metadataStoreServiceClient, } = React.useContext(PipelinesContext); @@ -203,7 +205,7 @@ export const usePipelinesAPI = (): UsePipelinesAPI => { namespace, project, refreshAllAPI, - getJobInformation, + getRecurringRunInformation, metadataStoreServiceClient, ...apiState, }; diff --git a/frontend/src/concepts/pipelines/context/useJobRelatedInformation.ts b/frontend/src/concepts/pipelines/context/useJobRelatedInformation.ts deleted file mode 100644 index c7b2a0cc4a..0000000000 --- a/frontend/src/concepts/pipelines/context/useJobRelatedInformation.ts +++ /dev/null @@ -1,64 +0,0 @@ -import * as React from 'react'; -import { PipelineRunJobKFv2 } from '~/concepts/pipelines/kfTypes'; -import { PipelineAPIState } from '~/concepts/pipelines/context/usePipelineAPIState'; - -type JobStatus = { - loading: boolean; - data: PipelineRunJobKFv2 | null; -}; - -export type GetJobInformation = (recurringRunId?: string) => JobStatus; - -const useJobRelatedInformation = ( - apiState: PipelineAPIState, -): { getJobInformation: GetJobInformation } => { - const [jobStorage, setJobStorage] = React.useState<{ [jobId: string]: JobStatus } | undefined>( - {}, - ); - const loadedIds = React.useRef([]); - - return { - getJobInformation: React.useCallback( - (recurringRunId) => { - if (!apiState.apiAvailable) { - return { loading: false, data: null }; - } - if (!recurringRunId) { - return { loading: false, data: null }; - } - const jobId = recurringRunId; - if (jobStorage?.[jobId]) { - return jobStorage[jobId]; - } - if (loadedIds.current.includes(jobId)) { - return { loading: true, data: null }; - } - loadedIds.current.push(jobId); - - apiState.api - .getPipelineRunJob({}, jobId) - .then((job) => { - setJobStorage((jobState) => ({ - ...jobState, - [jobId]: { loading: false, data: job }, - })); - }) - .catch((e) => { - // eslint-disable-next-line no-console - console.error('Could not fetch job reference', e); - setJobStorage((jobState) => ({ - ...jobState, - [jobId]: { loading: false, data: null }, - })); - loadedIds.current = loadedIds.current.filter((i) => i !== jobId); - return null; - }); - - return { loading: true, data: null }; - }, - [apiState, jobStorage], - ), - }; -}; - -export default useJobRelatedInformation; diff --git a/frontend/src/concepts/pipelines/context/usePipelineAPIState.ts b/frontend/src/concepts/pipelines/context/usePipelineAPIState.ts index 837b3f39bc..8b517ae8e9 100644 --- a/frontend/src/concepts/pipelines/context/usePipelineAPIState.ts +++ b/frontend/src/concepts/pipelines/context/usePipelineAPIState.ts @@ -2,25 +2,25 @@ import React from 'react'; import { createExperiment, createPipelineRun, - createPipelineRunJob, + createPipelineRecurringRun, deletePipeline, deletePipelineRun, - deletePipelineRunJob, + deletePipelineRecurringRun, deletePipelineVersion, getExperiment, getPipeline, getPipelineRun, - getPipelineRunJob, + getPipelineRecurringRun, getPipelineVersion, listExperiments, - listPipelineRunJobs, + listPipelineRecurringRuns, listPipelineRuns, listPipelineActiveRuns, listPipelineArchivedRuns, listPipelines, listPipelineVersions, stopPipelineRun, - updatePipelineRunJob, + updatePipelineRecurringRun, uploadPipeline, uploadPipelineVersion, archivePipelineRun, @@ -47,15 +47,15 @@ const usePipelineAPIState = ( createPipelineAndVersion: createPipelineAndVersion(path), createExperiment: createExperiment(path), createPipelineRun: createPipelineRun(path), - createPipelineRunJob: createPipelineRunJob(path), + createPipelineRecurringRun: createPipelineRecurringRun(path), getExperiment: getExperiment(path), getPipeline: getPipeline(path), getPipelineRun: getPipelineRun(path), - getPipelineRunJob: getPipelineRunJob(path), + getPipelineRecurringRun: getPipelineRecurringRun(path), getPipelineVersion: getPipelineVersion(path), deletePipeline: deletePipeline(path), deletePipelineRun: deletePipelineRun(path), - deletePipelineRunJob: deletePipelineRunJob(path), + deletePipelineRecurringRun: deletePipelineRecurringRun(path), deletePipelineVersion: deletePipelineVersion(path), deleteExperiment: deleteExperiment(path), listExperiments: listExperiments(path), @@ -63,7 +63,7 @@ const usePipelineAPIState = ( listPipelineRuns: listPipelineRuns(path), listPipelineActiveRuns: listPipelineActiveRuns(path), listPipelineArchivedRuns: listPipelineArchivedRuns(path), - listPipelineRunJobs: listPipelineRunJobs(path), + listPipelineRecurringRuns: listPipelineRecurringRuns(path), listPipelineVersions: listPipelineVersions(path), archivePipelineRun: archivePipelineRun(path), unarchivePipelineRun: unarchivePipelineRun(path), @@ -71,7 +71,7 @@ const usePipelineAPIState = ( archiveExperiment: archiveExperiment(path), unarchiveExperiment: unarchiveExperiment(path), stopPipelineRun: stopPipelineRun(path), - updatePipelineRunJob: updatePipelineRunJob(path), + updatePipelineRecurringRun: updatePipelineRecurringRun(path), uploadPipeline: uploadPipeline(path), uploadPipelineVersion: uploadPipelineVersion(path), }), diff --git a/frontend/src/concepts/pipelines/context/useRecurringRunRelatedInformation.ts b/frontend/src/concepts/pipelines/context/useRecurringRunRelatedInformation.ts new file mode 100644 index 0000000000..90ddaaa5ac --- /dev/null +++ b/frontend/src/concepts/pipelines/context/useRecurringRunRelatedInformation.ts @@ -0,0 +1,63 @@ +import * as React from 'react'; +import { PipelineRecurringRunKFv2 } from '~/concepts/pipelines/kfTypes'; +import { PipelineAPIState } from '~/concepts/pipelines/context/usePipelineAPIState'; + +type RecurringRunStatus = { + loading: boolean; + data: PipelineRecurringRunKFv2 | null; +}; + +export type GetRecurringRunInformation = (recurringRunId?: string) => RecurringRunStatus; + +const useRecurringRunRelatedInformation = ( + apiState: PipelineAPIState, +): { getRecurringRunInformation: GetRecurringRunInformation } => { + const [recurringRunStorage, setRecurringRunStorage] = React.useState< + { [recurringRunId: string]: RecurringRunStatus } | undefined + >({}); + const loadedIds = React.useRef([]); + + return { + getRecurringRunInformation: React.useCallback( + (recurringRunId) => { + if (!apiState.apiAvailable) { + return { loading: false, data: null }; + } + if (!recurringRunId) { + return { loading: false, data: null }; + } + if (recurringRunStorage?.[recurringRunId]) { + return recurringRunStorage[recurringRunId]; + } + if (loadedIds.current.includes(recurringRunId)) { + return { loading: true, data: null }; + } + loadedIds.current.push(recurringRunId); + + apiState.api + .getPipelineRecurringRun({}, recurringRunId) + .then((recurringRun) => { + setRecurringRunStorage((recurringRunState) => ({ + ...recurringRunState, + [recurringRunId]: { loading: false, data: recurringRun }, + })); + }) + .catch((e) => { + // eslint-disable-next-line no-console + console.error('Could not fetch recurring run reference', e); + setRecurringRunStorage((recurringRunState) => ({ + ...recurringRunState, + [recurringRunId]: { loading: false, data: null }, + })); + loadedIds.current = loadedIds.current.filter((i) => i !== recurringRunId); + return null; + }); + + return { loading: true, data: null }; + }, + [apiState, recurringRunStorage], + ), + }; +}; + +export default useRecurringRunRelatedInformation; diff --git a/frontend/src/concepts/pipelines/kfTypes.ts b/frontend/src/concepts/pipelines/kfTypes.ts index 0df0175525..3a3b9cda23 100644 --- a/frontend/src/concepts/pipelines/kfTypes.ts +++ b/frontend/src/concepts/pipelines/kfTypes.ts @@ -594,7 +594,7 @@ export type PipelineRunKF = PipelineCoreResourceKF & { /** * @deprecated - * Use PipelineRunJobKFv2 for all new stories + * Use PipelineRecurringRunKFv2 for all new stories */ export type PipelineRunJobKF = PipelineCoreResourceKF & { pipeline_spec: PipelineSpecKF; @@ -615,7 +615,7 @@ export type PipelineVersionReference = { pipeline_version_id: string; }; -export type PipelineRunJobKFv2 = PipelineCoreResourceKFv2 & { +export type PipelineRecurringRunKFv2 = PipelineCoreResourceKFv2 & { pipeline_spec?: PipelineSpecKF; service_account?: string; max_concurrency: string; @@ -676,8 +676,8 @@ export type ListPipelinesResponseKF = PipelineKFCallCommon<{ export type ListPipelineRunsResourceKF = PipelineKFCallCommon<{ runs: PipelineRunKFv2[]; }>; -export type ListPipelineRunJobsResourceKF = PipelineKFCallCommon<{ - recurringRuns: PipelineRunJobKFv2[]; +export type ListPipelineRecurringRunsResourceKF = PipelineKFCallCommon<{ + recurringRuns: PipelineRecurringRunKFv2[]; }>; export type ListPipelineVersionsKF = PipelineKFCallCommon<{ pipeline_versions: PipelineVersionKFv2[]; @@ -715,8 +715,8 @@ export type CreatePipelineRunKFData = Omit< | 'run_details' >; -export type CreatePipelineRunJobKFData = Omit< - PipelineRunJobKFv2, +export type CreatePipelineRecurringRunKFData = Omit< + PipelineRecurringRunKFv2, | 'recurring_run_id' | 'status' | 'created_at' diff --git a/frontend/src/concepts/pipelines/types.ts b/frontend/src/concepts/pipelines/types.ts index d8ddbef882..668d4394a3 100644 --- a/frontend/src/concepts/pipelines/types.ts +++ b/frontend/src/concepts/pipelines/types.ts @@ -1,19 +1,19 @@ import { K8sAPIOptions } from '~/k8sTypes'; import { ListPipelineRunsResourceKF, - ListPipelineRunJobsResourceKF, + ListPipelineRecurringRunsResourceKF, ListPipelinesResponseKF, ListExperimentsResponseKF, ExperimentKFv2, CreatePipelineRunKFData, - CreatePipelineRunJobKFData, + CreatePipelineRecurringRunKFData, PipelinesFilterPredicate, ListPipelineVersionsKF, PipelineKFv2, PipelineVersionKFv2, PipelineCoreResourceKFv2, PipelineRunKFv2, - PipelineRunJobKFv2, + PipelineRecurringRunKFv2, CreatePipelineAndVersionKFData, CreatePipelineVersionKFData, CreateExperimentKFData, @@ -63,20 +63,20 @@ export type CreatePipelineRun = ( opts: K8sAPIOptions, data: CreatePipelineRunKFData, ) => Promise; -export type CreatePipelineRunJob = ( +export type CreatePipelineRecurringRun = ( opts: K8sAPIOptions, - data: CreatePipelineRunJobKFData, -) => Promise; + data: CreatePipelineRecurringRunKFData, +) => Promise; export type GetExperiment = (opts: K8sAPIOptions, experimentId: string) => Promise; export type GetPipeline = (opts: K8sAPIOptions, pipelineId: string) => Promise; export type GetPipelineRun = ( opts: K8sAPIOptions, pipelineRunId: string, ) => Promise; -export type GetPipelineRunJob = ( +export type GetPipelineRecurringRun = ( opts: K8sAPIOptions, - pipelineRunJobId: string, -) => Promise; + pipelineRecurringRunId: string, +) => Promise; export type GetPipelineVersion = ( opts: K8sAPIOptions, pipelineId: string | undefined, @@ -84,7 +84,10 @@ export type GetPipelineVersion = ( ) => Promise; export type DeletePipeline = (opts: K8sAPIOptions, pipelineId: string) => Promise; export type DeletePipelineRun = (opts: K8sAPIOptions, runId: string) => Promise; -export type DeletePipelineRunJob = (opts: K8sAPIOptions, jobId: string) => Promise; +export type DeletePipelineRecurringRun = ( + opts: K8sAPIOptions, + recurringRunId: string, +) => Promise; export type DeletePipelineVersion = ( opts: K8sAPIOptions, pipelineId: string, @@ -103,19 +106,19 @@ export type ListPipelineRuns = ( opts: K8sAPIOptions, params?: PipelineRunParams, ) => Promise; -export type ListPipelineRunJobs = ( +export type ListPipelineRecurringRuns = ( opts: K8sAPIOptions, params?: PipelineRunParams, -) => Promise; +) => Promise; export type ListPipelineVersions = ( opts: K8sAPIOptions, pipelineId: string, params?: PipelineParams, ) => Promise; export type UpdatePipelineRun = (opts: K8sAPIOptions, runId: string) => Promise; -export type UpdatePipelineRunJob = ( +export type UpdatePipelineRecurringRun = ( opts: K8sAPIOptions, - jobId: string, + recurringRunId: string, enabled: boolean, ) => Promise; export type UpdateExperiment = (opts: K8sAPIOptions, experimentId: string) => Promise; @@ -138,15 +141,15 @@ export type PipelineAPIs = { createPipelineAndVersion: CreatePipelineAndVersion; createExperiment: CreateExperiment; createPipelineRun: CreatePipelineRun; - createPipelineRunJob: CreatePipelineRunJob; + createPipelineRecurringRun: CreatePipelineRecurringRun; getExperiment: GetExperiment; getPipeline: GetPipeline; getPipelineRun: GetPipelineRun; - getPipelineRunJob: GetPipelineRunJob; + getPipelineRecurringRun: GetPipelineRecurringRun; getPipelineVersion: GetPipelineVersion; deletePipeline: DeletePipeline; deletePipelineRun: DeletePipelineRun; - deletePipelineRunJob: DeletePipelineRunJob; + deletePipelineRecurringRun: DeletePipelineRecurringRun; deletePipelineVersion: DeletePipelineVersion; deleteExperiment: DeleteExperiment; listExperiments: ListExperiments; @@ -154,7 +157,7 @@ export type PipelineAPIs = { listPipelineRuns: ListPipelineRuns; listPipelineActiveRuns: ListPipelineRuns; listPipelineArchivedRuns: ListPipelineRuns; - listPipelineRunJobs: ListPipelineRunJobs; + listPipelineRecurringRuns: ListPipelineRecurringRuns; listPipelineVersions: ListPipelineVersions; archivePipelineRun: UpdatePipelineRun; retryPipelineRun: UpdatePipelineRun; @@ -162,7 +165,7 @@ export type PipelineAPIs = { archiveExperiment: UpdateExperiment; unarchiveExperiment: UpdateExperiment; stopPipelineRun: UpdatePipelineRun; - updatePipelineRunJob: UpdatePipelineRunJob; + updatePipelineRecurringRun: UpdatePipelineRecurringRun; uploadPipeline: UploadPipeline; uploadPipelineVersion: UploadPipelineVersion; }; diff --git a/frontend/src/concepts/pipelines/utils.ts b/frontend/src/concepts/pipelines/utils.ts index e674ecae2d..eba05fe29c 100644 --- a/frontend/src/concepts/pipelines/utils.ts +++ b/frontend/src/concepts/pipelines/utils.ts @@ -5,7 +5,7 @@ import { } from '~/concepts/pipelines/content/configurePipelinesServer/const'; import { ELYRA_SECRET_NAME } from '~/concepts/pipelines/elyra/const'; import { allSettledPromises } from '~/utilities/allSettledPromises'; -import { PipelineRunJobKFv2, PipelineRunKFv2 } from './kfTypes'; +import { PipelineRecurringRunKFv2, PipelineRunKFv2 } from './kfTypes'; export const deleteServer = async (namespace: string, crName: string): Promise => { const dspa = await getPipelinesCR(namespace, crName); @@ -31,5 +31,5 @@ export const isGeneratedDSPAExternalStorageSecret = (name: string): boolean => /^secret-[a-z0-9]{6}$/.test(name); export const isRunSchedule = ( - resource: PipelineRunKFv2 | PipelineRunJobKFv2, -): resource is PipelineRunJobKFv2 => 'trigger' in resource; + resource: PipelineRunKFv2 | PipelineRecurringRunKFv2, +): resource is PipelineRecurringRunKFv2 => 'trigger' in resource; diff --git a/frontend/src/pages/pipelines/GlobalPipelineExperimentsRoutes.tsx b/frontend/src/pages/pipelines/GlobalPipelineExperimentsRoutes.tsx index 27765915c6..1c514318fb 100644 --- a/frontend/src/pages/pipelines/GlobalPipelineExperimentsRoutes.tsx +++ b/frontend/src/pages/pipelines/GlobalPipelineExperimentsRoutes.tsx @@ -9,7 +9,7 @@ import { } from '~/pages/pipelines/global/experiments/const'; import GlobalExperiments from '~/pages/pipelines/global/experiments/GlobalExperiments'; import PipelineRunDetails from '~/concepts/pipelines/content/pipelinesDetails/pipelineRun/PipelineRunDetails'; -import PipelineRunJobDetails from '~/concepts/pipelines/content/pipelinesDetails/pipelineRunJob/PipelineRunJobDetails'; +import PipelineRecurringRunDetails from '~/concepts/pipelines/content/pipelinesDetails/pipelineRecurringRun/PipelineRecurringRunDetails'; import { experimentsBaseRoute } from '~/routes'; import CreateRunPage from '~/concepts/pipelines/content/createRun/CreateRunPage'; import CloneRunPage from '~/concepts/pipelines/content/createRun/CloneRunPage'; @@ -55,7 +55,7 @@ const GlobalPipelineExperimentsRoutes: React.FC = () => ( path="schedules/:recurringRunId" element={ } diff --git a/frontend/src/pages/pipelines/GlobalPipelineRunsRoutes.tsx b/frontend/src/pages/pipelines/GlobalPipelineRunsRoutes.tsx index 6651122a6e..80a9ccab55 100644 --- a/frontend/src/pages/pipelines/GlobalPipelineRunsRoutes.tsx +++ b/frontend/src/pages/pipelines/GlobalPipelineRunsRoutes.tsx @@ -11,15 +11,15 @@ import PipelineDetails from '~/concepts/pipelines/content/pipelinesDetails/pipel import PipelineRunDetails from '~/concepts/pipelines/content/pipelinesDetails/pipelineRun/PipelineRunDetails'; import CreateRunPage from '~/concepts/pipelines/content/createRun/CreateRunPage'; import CloneRunPage from '~/concepts/pipelines/content/createRun/CloneRunPage'; -import PipelineRunJobDetails from '~/concepts/pipelines/content/pipelinesDetails/pipelineRunJob/PipelineRunJobDetails'; +import PipelineRecurringRunDetails from '~/concepts/pipelines/content/pipelinesDetails/pipelineRecurringRun/PipelineRecurringRunDetails'; import { globNamespaceAll, globPipelineDetails, globPipelineRunClone, globPipelineRunCreate, globPipelineRunDetails, - globPipelineRunJobClone, - globPipelineRunJobDetails, + globPipelineRecurringRunClone, + globPipelineRecurringRunDetails, routePipelineRunsNamespace, } from '~/routes'; import GlobalPipelineRuns from './global/runs/GlobalPipelineRuns'; @@ -58,10 +58,10 @@ const GlobalPipelineRunsRoutes: React.FC = () => ( } /> @@ -88,7 +88,7 @@ const GlobalPipelineRunsRoutes: React.FC = () => ( } /> ( } /> @@ -100,7 +100,7 @@ const GlobalPipelinesRoutes: React.FC = () => ( } /> { const { experimentId, pipelineVersionId } = useParams(); - const [[{ items: jobs, totalSize }, loaded, error], { initialLoaded, ...tableProps }] = + const [[{ items: recurringRuns, totalSize }, loaded, error], { initialLoaded, ...tableProps }] = usePipelineScheduledRunsTable({ experimentId, pipelineVersionId }); const isExperimentArchived = useIsExperimentArchived(); @@ -73,7 +72,12 @@ const ScheduledRuns: React.FC = () => { } return ( - + ); }; diff --git a/frontend/src/pages/projects/ProjectViewRoutes.tsx b/frontend/src/pages/projects/ProjectViewRoutes.tsx index 494af7b340..2d0d70d50f 100644 --- a/frontend/src/pages/projects/ProjectViewRoutes.tsx +++ b/frontend/src/pages/projects/ProjectViewRoutes.tsx @@ -9,7 +9,7 @@ import PipelineDetails from '~/concepts/pipelines/content/pipelinesDetails/pipel import PipelineRunDetails from '~/concepts/pipelines/content/pipelinesDetails/pipelineRun/PipelineRunDetails'; import CreateRunPage from '~/concepts/pipelines/content/createRun/CreateRunPage'; import CloneRunPage from '~/concepts/pipelines/content/createRun/CloneRunPage'; -import PipelineRunJobDetails from '~/concepts/pipelines/content/pipelinesDetails/pipelineRunJob/PipelineRunJobDetails'; +import PipelineRecurringRunDetails from '~/concepts/pipelines/content/pipelinesDetails/pipelineRecurringRun/PipelineRecurringRunDetails'; import ProjectModelMetricsConfigurationPage from '~/pages/modelServing/screens/projects/ProjectModelMetricsConfigurationPage'; import ProjectModelMetricsPage from '~/pages/modelServing/screens/projects/ProjectModelMetricsPage'; import ProjectInferenceExplainabilityWrapper from '~/pages/modelServing/screens/projects/ProjectInferenceExplainabilityWrapper'; @@ -19,7 +19,7 @@ import { globPipelineRunClone, globPipelineRunCreate, globPipelineRunDetails, - globPipelineRunJobDetails, + globPipelineRecurringRunDetails, } from '~/routes'; import ProjectDetails from './screens/detail/ProjectDetails'; import ProjectView from './screens/projects/ProjectView'; @@ -72,9 +72,11 @@ const ProjectViewRoutes: React.FC = () => { } /> + } /> { @@ -42,9 +42,11 @@ const PipelinesCardMetrics: React.FC = () => { usePipelineArchivedRuns({ pageSize: 1, }); - const [{ totalSize: scheduledCount }, scheduledLoaded, scheduledError] = usePipelineRunJobs({ - pageSize: 1, - }); + const [{ totalSize: scheduledCount }, scheduledLoaded, scheduledError] = usePipelineRecurringRuns( + { + pageSize: 1, + }, + ); const [{ totalSize: experimentsCount }, experimentsLoaded, experimentsError] = useExperiments({ pageSize: 1, }); diff --git a/frontend/src/routes/pipelines/global.ts b/frontend/src/routes/pipelines/global.ts index 32fa3276b2..3fe18b89ce 100644 --- a/frontend/src/routes/pipelines/global.ts +++ b/frontend/src/routes/pipelines/global.ts @@ -6,7 +6,7 @@ export const globNamespaceAll = `/${globNamespace}?/*`; const globPipelineId = ':pipelineId'; const globPipelineVersionId = ':pipelineVersionId'; const globPipelineRunId = ':runId'; -const globPipelineRunJobId = ':recurringRunId'; +const globPipelineRecurringRunId = ':recurringRunId'; // pipelines and versions const globPipeline = 'pipeline'; @@ -44,18 +44,20 @@ export const routePipelineRunCloneNamespacePipelinesPage = ( namespace: string, runId: string, ): string => `${routePipelinesNamespace(namespace)}/${routePipelineRunClone(runId)}`; -export const routePipelineRunJobCloneNamespacePipelinesPage = ( +export const routePipelineRecurringRunCloneNamespacePipelinesPage = ( namespace: string, - jobId: string, -): string => `${routePipelinesNamespace(namespace)}/${routePipelineRunJobClone(jobId)}`; + recurringRunId: string, +): string => + `${routePipelinesNamespace(namespace)}/${routePipelineRecurringRunClone(recurringRunId)}`; export const routePipelineRunDetailsNamespacePipelinesPage = ( namespace: string, runId: string, ): string => `${routePipelinesNamespace(namespace)}/${routePipelineRunDetails(runId)}`; -export const routePipelineRunJobDetailsNamespacePipelinesPage = ( +export const routePipelineRecurringRunDetailsNamespacePipelinesPage = ( namespace: string, - jobId: string, -): string => `${routePipelinesNamespace(namespace)}/${routePipelineRunJobDetails(jobId)}`; + recurringRunId: string, +): string => + `${routePipelinesNamespace(namespace)}/${routePipelineRecurringRunDetails(recurringRunId)}`; // pipeline runs const globPipelineRun = 'pipelineRun'; @@ -79,14 +81,25 @@ export const globPipelineRunClone = routePipelineRunClone(globPipelineRunId); export const routePipelineRunCloneNamespace = (namespace: string, runId: string): string => `${routePipelineRunsNamespace(namespace)}/${routePipelineRunClone(runId)}`; -// pipeline run jobs -const globPipelineRunJob = 'pipelineRunJob'; -export const routePipelineRunJobDetails = (jobId: string): string => - `${globPipelineRunJob}/view/${jobId}`; -export const globPipelineRunJobDetails = routePipelineRunJobDetails(globPipelineRunJobId); -export const routePipelineRunJobDetailsNamespace = (namespace: string, jobId: string): string => - `${routePipelineRunsNamespace(namespace)}/${routePipelineRunJobDetails(jobId)}`; -const routePipelineRunJobClone = (jobId: string): string => `${globPipelineRun}/cloneJob/${jobId}`; -export const globPipelineRunJobClone = routePipelineRunJobClone(globPipelineRunJobId); -export const routePipelineRunJobCloneNamespace = (namespace: string, jobId: string): string => - `${routePipelineRunsNamespace(namespace)}/${routePipelineRunJobClone(jobId)}`; +// pipeline recurring runs +const globPipelineRecurringRun = 'pipelineRecurringRun'; +export const routePipelineRecurringRunDetails = (recurringRunId: string): string => + `${globPipelineRecurringRun}/view/${recurringRunId}`; +export const globPipelineRecurringRunDetails = routePipelineRecurringRunDetails( + globPipelineRecurringRunId, +); +export const routePipelineRecurringRunDetailsNamespace = ( + namespace: string, + recurringRunId: string, +): string => + `${routePipelineRunsNamespace(namespace)}/${routePipelineRecurringRunDetails(recurringRunId)}`; +const routePipelineRecurringRunClone = (recurringRunId: string): string => + `${globPipelineRun}/cloneRecurringRun/${recurringRunId}`; +export const globPipelineRecurringRunClone = routePipelineRecurringRunClone( + globPipelineRecurringRunId, +); +export const routePipelineRecurringRunCloneNamespace = ( + namespace: string, + recurringRunId: string, +): string => + `${routePipelineRunsNamespace(namespace)}/${routePipelineRecurringRunClone(recurringRunId)}`; diff --git a/frontend/src/routes/pipelines/runs.ts b/frontend/src/routes/pipelines/runs.ts index d86f555e1a..e2d9210b9b 100644 --- a/frontend/src/routes/pipelines/runs.ts +++ b/frontend/src/routes/pipelines/runs.ts @@ -2,8 +2,8 @@ import { routePipelineRunCloneNamespacePipelinesPage, routePipelineRunCreateNamespacePipelinesPage, routePipelineRunDetailsNamespacePipelinesPage, - routePipelineRunJobCloneNamespacePipelinesPage, - routePipelineRunJobDetailsNamespacePipelinesPage, + routePipelineRecurringRunCloneNamespacePipelinesPage, + routePipelineRecurringRunDetailsNamespacePipelinesPage, } from './global'; import { experimentRunDetailsRoute, @@ -21,7 +21,7 @@ export const cloneScheduleRoute = ( ): string => experimentId ? experimentsCloneScheduleRoute(namespace, experimentId, recurringRunId) - : routePipelineRunJobCloneNamespacePipelinesPage(namespace, recurringRunId); + : routePipelineRecurringRunCloneNamespacePipelinesPage(namespace, recurringRunId); export const scheduleRunRoute = ( namespace: string | undefined, @@ -46,7 +46,7 @@ export const scheduleDetailsRoute = ( ): string => experimentId ? experimentScheduleDetailsRoute(namespace, experimentId, recurringRunId) - : routePipelineRunJobDetailsNamespacePipelinesPage(namespace, recurringRunId); + : routePipelineRecurringRunDetailsNamespacePipelinesPage(namespace, recurringRunId); export const runDetailsRoute = ( namespace: string,