Skip to content

Commit

Permalink
Merge pull request opendatahub-io#2873 from DaoDaoNoCode/jira-rhoaien…
Browse files Browse the repository at this point in the history
…g-7543

Refine logic actions for runs on an archived experiment page
  • Loading branch information
openshift-merge-bot[bot] authored Jun 5, 2024
2 parents ac0fc61 + ce61bac commit 2d7ae79
Show file tree
Hide file tree
Showing 27 changed files with 421 additions and 174 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,15 @@ import {
buildMockPipelines,
mockProjectK8sResource,
mockRouteK8sResource,
buildMockRunKF,
buildMockJobKF,
} from '~/__mocks__';
import {
archivedRunsTable,
archiveExperimentModal,
bulkArchiveExperimentModal,
bulkRestoreExperimentModal,
pipelineRunJobTable,
pipelineRunsGlobal,
restoreExperimentModal,
} from '~/__tests__/cypress/cypress/pages/pipelines';
Expand All @@ -23,6 +27,7 @@ import {
ProjectModel,
RouteModel,
} from '~/__tests__/cypress/cypress/utils/models';
import { RecurringRunStatus, StorageStateKF } from '~/concepts/pipelines/kfTypes';

const projectName = 'test-project-name';
const initialMockPipeline = buildMockPipelineV2({ display_name: 'Test pipeline' });
Expand Down Expand Up @@ -199,7 +204,7 @@ describe('Experiments', () => {
});
});

describe('Runs page', () => {
describe('Runs page for active experiment', () => {
const activeExperimentsTable = experimentsTabs.getActiveExperimentsTable();
const [mockExperiment] = mockExperiments;

Expand Down Expand Up @@ -240,6 +245,67 @@ describe('Experiments', () => {
});
});

describe('Runs page for archived experiment', () => {
const archivedExperimentsTable = experimentsTabs.getArchivedExperimentsTable();
const mockExperiment = { ...mockExperiments[0], storage_state: StorageStateKF.ARCHIVED };

beforeEach(() => {
initIntercepts();
cy.interceptOdh(
'GET /api/service/pipelines/:namespace/:serviceName/apis/v2beta1/experiments/:experimentId',
{
path: {
namespace: projectName,
serviceName: 'dspa',
experimentId: mockExperiment.experiment_id,
},
},
mockExperiment,
);
cy.interceptOdh(
'GET /api/service/pipelines/:namespace/:serviceName/apis/v2beta1/runs',
{
path: { namespace: projectName, serviceName: 'dspa' },
},
{ runs: [buildMockRunKF({ storage_state: StorageStateKF.ARCHIVED })] },
);

cy.interceptOdh(
'GET /api/service/pipelines/:namespace/:serviceName/apis/v2beta1/recurringruns',
{
path: { namespace: projectName, serviceName: 'dspa' },
},
{ recurringRuns: [buildMockJobKF({ status: RecurringRunStatus.DISABLED })] },
);
experimentsTabs.mockGetExperiments(projectName, [], mockExperiments);
experimentsTabs.visit(projectName);
experimentsTabs.findArchivedTab().click();
archivedExperimentsTable.getRowByName(mockExperiment.display_name).find().find('a').click();
});

it('navigates to the runs page when clicking an experiment name', () => {
verifyRelativeURL(`/experiments/${projectName}/${mockExperiment.experiment_id}/runs`);
cy.findByLabelText('Breadcrumb').findByText('Experiments');
});

it('has empty state on active runs tab', () => {
pipelineRunsGlobal.findActiveRunsTab().click();
cy.findByTestId('experiment-archived-empty-state').should('be.visible');
});

it('has restore button disabled on archived runs tab', () => {
pipelineRunsGlobal.findArchivedRunsTab().click();
archivedRunsTable.getRowByName('Test run').findCheckbox().click();
pipelineRunsGlobal.findRestoreRunButton().should('have.class', 'pf-m-aria-disabled');
});

it('has create schedule button disabled on schedules tab', () => {
pipelineRunsGlobal.findSchedulesTab().click();
pipelineRunJobTable.getRowByName('Test job').findCheckbox().click();
pipelineRunsGlobal.findScheduleRunButton().should('have.class', 'pf-m-aria-disabled');
});
});

const initIntercepts = () => {
cy.interceptOdh('GET /api/config', mockDashboardConfig({ disablePipelineExperiments: false }));
cy.interceptK8sList(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -976,7 +976,7 @@ describe('Pipelines', () => {
pipelineRow.findExpandButton().click();
pipelineRow
.getPipelineVersionRowById(initialMockPipelineVersion.pipeline_version_id)
.findKebabAction('Schedule run')
.findKebabAction('Create schedule')
.click();

verifyRelativeURL(`/pipelines/${projectName}/pipelineRun/create?runType=scheduled`);
Expand Down Expand Up @@ -1193,7 +1193,7 @@ export const runScheduleRunPageNavTest = (visitPipelineProjects: () => void): vo
pipelinesTable.find();
pipelinesTable
.getRowById(initialMockPipeline.pipeline_id)
.findKebabAction('Schedule run')
.findKebabAction('Create schedule')
.click();

verifyRelativeURL(`/pipelines/${projectName}/pipelineRun/create?runType=scheduled`);
Expand All @@ -1213,10 +1213,10 @@ export const viewPipelineServerDetailsTest = (visitPipelineProjects: () => void)
}),
);
visitPipelineProjects();
viewPipelinelineDetails();
viewPipelineDetails();
};

const viewPipelinelineDetails = (
const viewPipelineDetails = (
accessKey = 'sdsd',
secretKey = 'sdsd',
endpoint = 'https://s3.amazonaws.com',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ describe('Pipeline topology', () => {
});

it('navigates to "Schedule run" page on "Schedule run" click', () => {
pipelineDetails.selectActionDropdownItem('Schedule run');
pipelineDetails.selectActionDropdownItem('Create schedule');
verifyRelativeURL(`/pipelineRuns/${projectId}/pipelineRun/create?runType=scheduled`);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ const RunForm: React.FC<RunFormProps> = ({ data, runType, onValueChange }) => {
projectName={getProjectDisplayName(data.project)}
value={data.experiment}
onChange={(experiment) => onValueChange('experiment', experiment)}
isSchedule={isSchedule}
/>

<FormSection
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,25 @@ import {
CreateRunPageSections,
runPageSectionTitles,
} from '~/concepts/pipelines/content/createRun/const';
import ExperimentSelector from '~/concepts/pipelines/content/experiment/ExperimentSelector';
import {
ActiveExperimentSelector,
AllExperimentSelector,
} from '~/concepts/pipelines/content/experiment/ExperimentSelector';
import CreateExperimentButton from '~/concepts/pipelines/content/experiment/CreateExperimentButton';
import { SupportedArea, useIsAreaAvailable } from '~/concepts/areas';

type ExperimentSectionProps = {
type ProjectAndExperimentSectionProps = {
projectName: string;
value: ExperimentKFv2 | null;
onChange: (experiment: ExperimentKFv2) => void;
isSchedule: boolean;
};

const ProjectAndExperimentSection: React.FC<ExperimentSectionProps> = ({
const ProjectAndExperimentSection: React.FC<ProjectAndExperimentSectionProps> = ({
projectName,
value,
onChange,
isSchedule,
}) => {
const isExperimentsAvailable = useIsAreaAvailable(SupportedArea.PIPELINE_EXPERIMENTS).status;

Expand All @@ -39,7 +44,11 @@ const ProjectAndExperimentSection: React.FC<ExperimentSectionProps> = ({
<FormGroup label="Experiment" aria-label="Experiment" isRequired>
<Stack hasGutter>
<StackItem>
<ExperimentSelector selection={value?.display_name} onSelect={onChange} />
{isSchedule ? (
<AllExperimentSelector selection={value?.display_name} onSelect={onChange} />
) : (
<ActiveExperimentSelector selection={value?.display_name} onSelect={onChange} />
)}
</StackItem>
<StackItem>
<CreateExperimentButton
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
PipelineVersionKFv2,
RecurringRunMode,
RuntimeConfigParameters,
StorageStateKF,
} from '~/concepts/pipelines/kfTypes';
import { PipelineAPIs } from '~/concepts/pipelines/types';
import {
Expand Down Expand Up @@ -97,7 +98,10 @@ const createJob = async (
: undefined,
},
max_concurrency: String(formData.runType.data.maxConcurrency),
mode: RecurringRunMode.ENABLE,
mode:
formData.experiment?.storage_state === StorageStateKF.ARCHIVED
? RecurringRunMode.DISABLE
: RecurringRunMode.ENABLE,
no_catchup: !formData.runType.data.catchUp,
service_account: '',
experiment_id: formData.experiment?.experiment_id || '',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
PipelineRunJobKFv2,
PipelineRunKFv2,
PipelineVersionKFv2,
StorageStateKF,
} from '~/concepts/pipelines/kfTypes';

import { UpdateObjectAtPropAndValue } from '~/pages/projects/types';
Expand Down Expand Up @@ -98,10 +99,25 @@ const useUpdateExperimentFormData = (
const [formData, setFormValue] = formState;

React.useEffect(() => {
if (!formData.experiment && experiment) {
// on create run page, we always check the experiment archived state
// no matter it's duplicated or carried from the create schedules pages
if (formData.runType.type === RunTypeOption.ONE_TRIGGER) {
if (formData.experiment) {
if (formData.experiment.storage_state === StorageStateKF.ARCHIVED) {
setFormValue('experiment', null);
}
} else if (experiment) {
if (experiment.storage_state === StorageStateKF.ARCHIVED) {
setFormValue('experiment', null);
} else {
setFormValue('experiment', experiment);
}
}
} else if (!formData.experiment && experiment) {
// else, on create schedules page, we do what we did before
setFormValue('experiment', experiment);
}
}, [formData.experiment, setFormValue, experiment]);
}, [formData.experiment, setFormValue, experiment, formData.runType.type]);
};

const useUpdatePipelineFormData = (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,34 @@ import { TableBase, getTableColumnSort } from '~/components/table';
import { ExperimentKFv2 } from '~/concepts/pipelines/kfTypes';
import PipelineViewMoreFooterRow from '~/concepts/pipelines/content/tables/PipelineViewMoreFooterRow';
import DashboardEmptyTableView from '~/concepts/dashboard/DashboardEmptyTableView';
import { useExperimentSelector } from '~/concepts/pipelines/content/pipelineSelector/useCreateSelectors';
import {
useActiveExperimentSelector,
useAllExperimentSelector,
} from '~/concepts/pipelines/content/pipelineSelector/useCreateSelectors';
import { experimentSelectorColumns } from '~/concepts/pipelines/content/experiment/columns';

type ExperimentSelectorProps = {
selection?: string;
onSelect: (experiment: ExperimentKFv2) => void;
};

const ExperimentSelector: React.FC<ExperimentSelectorProps> = ({ selection, onSelect }) => {
const InnerExperimentSelector: React.FC<
ReturnType<typeof useAllExperimentSelector> & ExperimentSelectorProps
> = ({
fetchedSize,
totalSize,
searchProps,
onSearchClear,
onLoadMore,
sortProps,
loaded,
initialLoaded,
data: experiments,
selection,
onSelect,
}) => {
const [isOpen, setOpen] = React.useState(false);

const {
fetchedSize,
totalSize,
searchProps,
onSearchClear,
onLoadMore,
sortProps,
loaded,
initialLoaded,
data: experiments,
} = useExperimentSelector();

const toggleRef = React.useRef(null);
const menuRef = React.useRef(null);

Expand Down Expand Up @@ -140,4 +145,12 @@ const ExperimentSelector: React.FC<ExperimentSelectorProps> = ({ selection, onSe
);
};

export default ExperimentSelector;
export const AllExperimentSelector: React.FC<ExperimentSelectorProps> = (props) => {
const selectorProps = useAllExperimentSelector();
return <InnerExperimentSelector {...props} {...selectorProps} />;
};

export const ActiveExperimentSelector: React.FC<ExperimentSelectorProps> = (props) => {
const selectorProps = useActiveExperimentSelector();
return <InnerExperimentSelector {...props} {...selectorProps} />;
};
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import * as React from 'react';
import { useSelectorSearch } from '~/concepts/pipelines/content/pipelineSelector/utils';
import useExperimentTable from '~/concepts/pipelines/content/tables/experiment/useExperimentTable';
import useExperimentTable, {
useActiveExperimentTable,
} from '~/concepts/pipelines/content/tables/experiment/useExperimentTable';
import usePipelinesTable from '~/concepts/pipelines/content/tables/pipeline/usePipelinesTable';
import {
LoadMoreProps,
Expand Down Expand Up @@ -35,14 +37,19 @@ type UsePipelineSelectorData<DataType> = {
};
};

export const useExperimentSelector = (): UsePipelineSelectorData<ExperimentKFv2> => {
const experimentsTable = useExperimentTable();
const [[{ items: initialData, nextPageToken: initialPageToken }, loaded]] = experimentsTable;
return useCreateSelector<ExperimentKFv2>(
experimentsTable,
useExperimentLoadMore({ initialData, initialPageToken, loaded }),
);
};
export const getExperimentSelector =
(useTable: typeof useExperimentTable) => (): UsePipelineSelectorData<ExperimentKFv2> => {
const experimentsTable = useTable();
const [[{ items: initialData, nextPageToken: initialPageToken }, loaded]] = experimentsTable;
return useCreateSelector<ExperimentKFv2>(
experimentsTable,
useExperimentLoadMore({ initialData, initialPageToken, loaded }),
);
};

export const useAllExperimentSelector = getExperimentSelector(useExperimentTable);

export const useActiveExperimentSelector = getExperimentSelector(useActiveExperimentTable);

export const usePipelineSelector = (): UsePipelineSelectorData<PipelineKFv2> => {
const pipelinesTable = usePipelinesTable();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ const PipelineDetailsActions: React.FC<PipelineDetailsActionsProps> = ({
)
}
>
Schedule run
Create schedule
</DropdownItem>,
<DropdownSeparator key="separator-view" />,
<DropdownItem
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import useExperiments from '~/concepts/pipelines/apiHooks/useExperiments';
import useExperiments, { useActiveExperiments } from '~/concepts/pipelines/apiHooks/useExperiments';
import createUsePipelineTable from '~/concepts/pipelines/content/tables/usePipelineTable';

export const useActiveExperimentTable = createUsePipelineTable(useActiveExperiments);

export default createUsePipelineTable(useExperiments);
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ const PipelinesTableRow: React.FC<PipelinesTableRowProps> = ({
},
},
{
title: 'Schedule run',
title: 'Create schedule',
onClick: () => {
navigate(
{
Expand Down
Loading

0 comments on commit 2d7ae79

Please sign in to comment.