From 41ea03962680ffaf5cf5a19818c9f0f572c5a851 Mon Sep 17 00:00:00 2001 From: Dipanshu Gupta <97534722+dpanshug@users.noreply.github.com> Date: Thu, 3 Oct 2024 21:05:54 +0530 Subject: [PATCH 01/12] RHOAIENG-13608 Inconsistent Default Storage Class when corrupting isDefault value (#3287) --- .../screens/spawner/storage/StorageClassSelect.tsx | 8 ++++++-- .../screens/spawner/storage/useDefaultStorageClass.ts | 6 ++++-- .../src/pages/storageClasses/StorageClassesContext.tsx | 4 ++-- .../src/pages/storageClasses/StorageClassesTableRow.tsx | 2 +- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/frontend/src/pages/projects/screens/spawner/storage/StorageClassSelect.tsx b/frontend/src/pages/projects/screens/spawner/storage/StorageClassSelect.tsx index c8eb591f90..1302f685cc 100644 --- a/frontend/src/pages/projects/screens/spawner/storage/StorageClassSelect.tsx +++ b/frontend/src/pages/projects/screens/spawner/storage/StorageClassSelect.tsx @@ -13,6 +13,7 @@ import React from 'react'; import SimpleSelect, { SimpleSelectOption } from '~/components/SimpleSelect'; import useStorageClasses from '~/concepts/k8s/useStorageClasses'; import { getStorageClassConfig } from '~/pages/storageClasses/utils'; +import useDefaultStorageClass from './useDefaultStorageClass'; type StorageClassSelectProps = { storageClassName?: string; @@ -29,9 +30,10 @@ const StorageClassSelect: React.FC = ({ }) => { const [storageClasses, storageClassesLoaded] = useStorageClasses(); const hasStorageClassConfigs = storageClasses.some((sc) => !!getStorageClassConfig(sc)); + const defaultSc = useDefaultStorageClass(); const enabledStorageClasses = storageClasses - .filter((sc) => getStorageClassConfig(sc)?.isEnabled) + .filter((sc) => getStorageClassConfig(sc)?.isEnabled === true) .toSorted((a, b) => { const aConfig = getStorageClassConfig(a); const bConfig = getStorageClassConfig(b); @@ -66,7 +68,9 @@ const StorageClassSelect: React.FC = ({ {config?.displayName || sc.metadata.name} - {config?.isDefault && ( + {/* If multiple storage classes have `isDefault` set to true, + prioritize the one returned by useDefaultStorageClass() as the default class */} + {sc.metadata.name === defaultSc?.metadata.name && ( diff --git a/frontend/src/pages/projects/screens/spawner/storage/useDefaultStorageClass.ts b/frontend/src/pages/projects/screens/spawner/storage/useDefaultStorageClass.ts index 934f6247b2..8d69ec2270 100644 --- a/frontend/src/pages/projects/screens/spawner/storage/useDefaultStorageClass.ts +++ b/frontend/src/pages/projects/screens/spawner/storage/useDefaultStorageClass.ts @@ -17,10 +17,12 @@ const useDefaultStorageClass = (): StorageClassKind | undefined => { } const enabledStorageClasses = storageClasses.filter( - (sc) => getStorageClassConfig(sc)?.isEnabled, + (sc) => getStorageClassConfig(sc)?.isEnabled === true, ); - const defaultSc = enabledStorageClasses.find((sc) => getStorageClassConfig(sc)?.isDefault); + const defaultSc = enabledStorageClasses.find( + (sc) => getStorageClassConfig(sc)?.isDefault === true, + ); if (!defaultSc && enabledStorageClasses.length > 0) { setDefaultStorageClass(enabledStorageClasses[0]); diff --git a/frontend/src/pages/storageClasses/StorageClassesContext.tsx b/frontend/src/pages/storageClasses/StorageClassesContext.tsx index 2cf7037983..de0b60992e 100644 --- a/frontend/src/pages/storageClasses/StorageClassesContext.tsx +++ b/frontend/src/pages/storageClasses/StorageClassesContext.tsx @@ -59,7 +59,7 @@ export const StorageClassContextProvider: React.FC config?.isDefault) || []; + Object.entries(storageClassConfigs).find(([, config]) => config?.isDefault === true) || []; const openshiftDefaultScName = storageClasses.find((storageClass) => isOpenshiftDefaultStorageClass(storageClass), @@ -94,7 +94,7 @@ export const StorageClassContextProvider: React.FC = ({ {isValidConfigValue('isDefault', storageClassConfig.isDefault) && ( From 9ed0a827f49f1a3980c3f536c3a9b2f0ce92ad37 Mon Sep 17 00:00:00 2001 From: Juntao Wang <37624318+DaoDaoNoCode@users.noreply.github.com> Date: Thu, 3 Oct 2024 12:04:35 -0400 Subject: [PATCH 02/12] Remove disablePipelineExperiments feature flag (#3273) --- backend/src/types.ts | 1 - backend/src/utils/constants.ts | 1 - docs/dashboard-config.md | 2 - frontend/src/__mocks__/mockDashboardConfig.ts | 3 - .../tests/mocked/pipelines/compareRuns.cy.ts | 7 +-- .../tests/mocked/pipelines/executions.cy.ts | 2 +- .../tests/mocked/pipelines/experiments.cy.ts | 2 +- .../tests/mocked/pipelines/intercepts.ts | 2 +- frontend/src/concepts/areas/const.ts | 5 -- frontend/src/concepts/areas/types.ts | 1 - .../pipelines/content/createRun/RunPage.tsx | 15 +---- .../content/createRun/RunPageFooter.tsx | 11 +--- .../ProjectAndExperimentSection.tsx | 63 ++++++++----------- .../contentSections/RunTypeSection.tsx | 16 +---- .../pipelines/content/createRun/utils.ts | 4 +- .../PipelineRecurringRunDetailsActions.tsx | 4 +- .../pipelineRun/PipelineRunDetailsActions.tsx | 6 +- .../SelectedNodeInputOutputTab.tsx | 4 +- .../artifacts/ArtifactNodeDetails.tsx | 10 +-- .../PipelineRecurringRunTable.tsx | 4 +- .../PipelineRecurringRunTableRow.tsx | 13 ++-- .../tables/pipelineRun/PipelineRunTable.tsx | 29 +++------ .../pipelineRun/PipelineRunTableRow.tsx | 21 ++----- .../PipelineRunTableRowExperiment.tsx | 7 +-- .../pipelineRun/PipelineRunTableRowTitle.tsx | 10 +-- .../pipelineRun/PipelineRunTableToolbar.tsx | 6 +- frontend/src/k8sTypes.ts | 2 - .../pipelines/global/runs/ActiveRuns.tsx | 11 +--- .../global/runs/CreateScheduleButton.tsx | 11 +--- frontend/src/utilities/NavData.tsx | 47 +++++++------- ...dhdashboardconfigs.opendatahub.io.crd.yaml | 2 - 31 files changed, 86 insertions(+), 236 deletions(-) diff --git a/backend/src/types.ts b/backend/src/types.ts index d96a0350b4..474ddfed8c 100644 --- a/backend/src/types.ts +++ b/backend/src/types.ts @@ -36,7 +36,6 @@ export type DashboardConfig = K8sResourceCommon & { disableKServeMetrics: boolean; disableModelMesh: boolean; disableAcceleratorProfiles: boolean; - disablePipelineExperiments: boolean; disableDistributedWorkloads: boolean; disableModelRegistry: boolean; disableConnectionTypes: boolean; diff --git a/backend/src/utils/constants.ts b/backend/src/utils/constants.ts index 0036a51ac7..70d35a9c52 100644 --- a/backend/src/utils/constants.ts +++ b/backend/src/utils/constants.ts @@ -61,7 +61,6 @@ export const blankDashboardCR: DashboardConfig = { disableKServeMetrics: false, disableModelMesh: false, disableAcceleratorProfiles: false, - disablePipelineExperiments: false, disableDistributedWorkloads: false, disableModelRegistry: false, disableConnectionTypes: true, diff --git a/docs/dashboard-config.md b/docs/dashboard-config.md index db7e23236a..83e3e88756 100644 --- a/docs/dashboard-config.md +++ b/docs/dashboard-config.md @@ -64,7 +64,6 @@ spec: disableKServeMetrics: false disableBiasMetrics: false disablePerformanceMetrics: false - disablePipelineExperiments: true disableDistributedWorkloads: false disableConnectionTypes: false disableStorageClasses: false @@ -162,7 +161,6 @@ spec: disableKServeMetrics: true disableBiasMetrics: false disablePerformanceMetrics: false - disablePipelineExperiments: false disableNIMModelServing: true notebookController: enabled: true diff --git a/frontend/src/__mocks__/mockDashboardConfig.ts b/frontend/src/__mocks__/mockDashboardConfig.ts index 4b96efb0d1..5096817893 100644 --- a/frontend/src/__mocks__/mockDashboardConfig.ts +++ b/frontend/src/__mocks__/mockDashboardConfig.ts @@ -22,7 +22,6 @@ type MockDashboardConfigType = { disableAcceleratorProfiles?: boolean; disablePerformanceMetrics?: boolean; disableBiasMetrics?: boolean; - disablePipelineExperiments?: boolean; disableDistributedWorkloads?: boolean; disableModelRegistry?: boolean; disableConnectionTypes?: boolean; @@ -53,7 +52,6 @@ export const mockDashboardConfig = ({ disableAcceleratorProfiles = false, disablePerformanceMetrics = false, disableBiasMetrics = false, - disablePipelineExperiments = false, disableDistributedWorkloads = false, disableModelRegistry = false, disableConnectionTypes = true, @@ -161,7 +159,6 @@ export const mockDashboardConfig = ({ disableKServeMetrics, disableModelMesh, disableAcceleratorProfiles, - disablePipelineExperiments, disableDistributedWorkloads, disableModelRegistry, disableConnectionTypes, diff --git a/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/compareRuns.cy.ts b/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/compareRuns.cy.ts index 8651dbc5ed..e9632d9b97 100644 --- a/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/compareRuns.cy.ts +++ b/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/compareRuns.cy.ts @@ -419,12 +419,7 @@ type InterceptsType = { }; const initIntercepts = ({ noMetrics }: InterceptsType) => { - cy.interceptOdh( - 'GET /api/config', - mockDashboardConfig({ - disablePipelineExperiments: false, - }), - ); + cy.interceptOdh('GET /api/config', mockDashboardConfig({})); cy.interceptK8sList( DataSciencePipelineApplicationModel, mockK8sResourceList([ diff --git a/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/executions.cy.ts b/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/executions.cy.ts index 6e582b4e87..9c5a552fe2 100644 --- a/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/executions.cy.ts +++ b/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/executions.cy.ts @@ -133,7 +133,7 @@ const shouldFilterItems = (filter: FilterArgs, query?: string) => { }; const initIntercepts = (interceptMlmd: boolean, isExecutionsEmpty?: boolean) => { - cy.interceptOdh('GET /api/config', mockDashboardConfig({ disablePipelineExperiments: false })); + cy.interceptOdh('GET /api/config', mockDashboardConfig({})); cy.interceptK8sList( DataSciencePipelineApplicationModel, mockK8sResourceList([ 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 aa78c39989..e601076f04 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 @@ -393,7 +393,7 @@ describe('Runs page for archived experiment', () => { }); const initIntercepts = () => { - cy.interceptOdh('GET /api/config', mockDashboardConfig({ disablePipelineExperiments: false })); + cy.interceptOdh('GET /api/config', mockDashboardConfig({})); cy.interceptK8sList( DataSciencePipelineApplicationModel, mockK8sResourceList([ diff --git a/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/intercepts.ts b/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/intercepts.ts index b9624c89c8..c8f6a9a929 100644 --- a/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/intercepts.ts +++ b/frontend/src/__tests__/cypress/cypress/tests/mocked/pipelines/intercepts.ts @@ -12,7 +12,7 @@ import { } from '~/__tests__/cypress/cypress/utils/models'; export const configIntercept = (): void => { - cy.interceptOdh('GET /api/config', mockDashboardConfig({ disablePipelineExperiments: false })); + cy.interceptOdh('GET /api/config', mockDashboardConfig({})); }; export const projectsIntercept = ( diff --git a/frontend/src/concepts/areas/const.ts b/frontend/src/concepts/areas/const.ts index 98c01a5df2..61c7ce27ae 100644 --- a/frontend/src/concepts/areas/const.ts +++ b/frontend/src/concepts/areas/const.ts @@ -24,7 +24,6 @@ export const allFeatureFlags: string[] = Object.keys({ disableKServeMetrics: false, disableModelMesh: false, disableAcceleratorProfiles: false, - disablePipelineExperiments: false, disableDistributedWorkloads: false, disableModelRegistry: false, disableConnectionTypes: false, @@ -107,10 +106,6 @@ export const SupportedAreasStateMap: SupportedAreasState = { requiredComponents: [StackComponent.TRUSTY_AI], reliantAreas: [SupportedArea.BIAS_METRICS], }, - [SupportedArea.PIPELINE_EXPERIMENTS]: { - featureFlags: ['disablePipelineExperiments'], - reliantAreas: [SupportedArea.DS_PIPELINES], - }, [SupportedArea.DISTRIBUTED_WORKLOADS]: { featureFlags: ['disableDistributedWorkloads'], requiredComponents: [StackComponent.KUEUE], diff --git a/frontend/src/concepts/areas/types.ts b/frontend/src/concepts/areas/types.ts index 10f2bb9588..8baa2ba47f 100644 --- a/frontend/src/concepts/areas/types.ts +++ b/frontend/src/concepts/areas/types.ts @@ -31,7 +31,6 @@ export enum SupportedArea { /* Pipelines areas */ DS_PIPELINES = 'ds-pipelines', - PIPELINE_EXPERIMENTS = 'pipeline-experiments', /* Admin areas */ BYON = 'bring-your-own-notebook', diff --git a/frontend/src/concepts/pipelines/content/createRun/RunPage.tsx b/frontend/src/concepts/pipelines/content/createRun/RunPage.tsx index 4f157d06ac..69853f4a98 100644 --- a/frontend/src/concepts/pipelines/content/createRun/RunPage.tsx +++ b/frontend/src/concepts/pipelines/content/createRun/RunPage.tsx @@ -29,7 +29,6 @@ import { ValueOf } from '~/typeHelpers'; import { useGetSearchParamValues } from '~/utilities/useGetSearchParamValues'; import { PipelineRunSearchParam } from '~/concepts/pipelines/content/types'; import { asEnumMember } from '~/utilities/utils'; -import { SupportedArea, useIsAreaAvailable } from '~/concepts/areas'; import useDefaultExperiment from '~/pages/pipelines/global/experiments/useDefaultExperiment'; type RunPageProps = { @@ -64,7 +63,6 @@ const RunPage: React.FC = ({ const triggerType = asEnumMember(triggerTypeString, ScheduledType); const isSchedule = runType === RunTypeOption.SCHEDULED; - const isExperimentsAvailable = useIsAreaAvailable(SupportedArea.PIPELINE_EXPERIMENTS).status; const [defaultExperiment] = useDefaultExperiment(); const jumpToSections = Object.values(CreateRunPageSections).filter( @@ -104,21 +102,10 @@ const RunPage: React.FC = ({ [setFormDataValue], ); - const runPageSectionTitlesEdited = isExperimentsAvailable - ? runPageSectionTitles - : { - ...runPageSectionTitles, - [CreateRunPageSections.PROJECT_AND_EXPERIMENT]: 'Project', - }; - return (
- + diff --git a/frontend/src/concepts/pipelines/content/createRun/RunPageFooter.tsx b/frontend/src/concepts/pipelines/content/createRun/RunPageFooter.tsx index a0d33ac5ec..e550772df1 100644 --- a/frontend/src/concepts/pipelines/content/createRun/RunPageFooter.tsx +++ b/frontend/src/concepts/pipelines/content/createRun/RunPageFooter.tsx @@ -2,13 +2,9 @@ import * as React from 'react'; import { Alert, Button, Split, SplitItem, Stack, StackItem } from '@patternfly/react-core'; import { useNavigate } from 'react-router-dom'; import { RunFormData, RunTypeOption } from '~/concepts/pipelines/content/createRun/types'; -import { - isFilledRunFormData, - isFilledRunFormDataExperiment, -} from '~/concepts/pipelines/content/createRun/utils'; +import { isFilledRunFormData } from '~/concepts/pipelines/content/createRun/utils'; import { handleSubmit } from '~/concepts/pipelines/content/createRun/submitUtils'; import { usePipelinesAPI } from '~/concepts/pipelines/context'; -import { SupportedArea, useIsAreaAvailable } from '~/concepts/areas'; import { isRunSchedule } from '~/concepts/pipelines/utils'; type RunPageFooterProps = { @@ -23,10 +19,7 @@ const RunPageFooter: React.FC = ({ data, contextPath }) => { const [isSubmitting, setSubmitting] = React.useState(false); const [error, setError] = React.useState(null); - const isExperimentsAvailable = useIsAreaAvailable(SupportedArea.PIPELINE_EXPERIMENTS).status; - const canSubmit = isExperimentsAvailable - ? isFilledRunFormDataExperiment(data) - : isFilledRunFormData(data); + const canSubmit = isFilledRunFormData(data); return ( diff --git a/frontend/src/concepts/pipelines/content/createRun/contentSections/ProjectAndExperimentSection.tsx b/frontend/src/concepts/pipelines/content/createRun/contentSections/ProjectAndExperimentSection.tsx index 4e232d0bc4..f91d5dcc5f 100644 --- a/frontend/src/concepts/pipelines/content/createRun/contentSections/ProjectAndExperimentSection.tsx +++ b/frontend/src/concepts/pipelines/content/createRun/contentSections/ProjectAndExperimentSection.tsx @@ -8,7 +8,6 @@ import { } from '~/concepts/pipelines/content/createRun/const'; import { ActiveExperimentSelector } from '~/concepts/pipelines/content/experiment/ExperimentSelector'; import CreateExperimentButton from '~/concepts/pipelines/content/experiment/CreateExperimentButton'; -import { SupportedArea, useIsAreaAvailable } from '~/concepts/areas'; type ProjectAndExperimentSectionProps = { projectName: string; @@ -20,41 +19,31 @@ const ProjectAndExperimentSection: React.FC = projectName, value, onChange, -}) => { - const isExperimentsAvailable = useIsAreaAvailable(SupportedArea.PIPELINE_EXPERIMENTS).status; - - return ( - - - {projectName} - - {isExperimentsAvailable && ( - - - - - - - } - onCreate={(experiment) => onChange(experiment)} - > - Create new experiment - - - - - )} - - ); -}; +}) => ( + + + {projectName} + + + + + + + + } + onCreate={(experiment) => onChange(experiment)} + > + Create new experiment + + + + + +); export default ProjectAndExperimentSection; diff --git a/frontend/src/concepts/pipelines/content/createRun/contentSections/RunTypeSection.tsx b/frontend/src/concepts/pipelines/content/createRun/contentSections/RunTypeSection.tsx index 4dc89819c5..45b28a584e 100644 --- a/frontend/src/concepts/pipelines/content/createRun/contentSections/RunTypeSection.tsx +++ b/frontend/src/concepts/pipelines/content/createRun/contentSections/RunTypeSection.tsx @@ -9,7 +9,6 @@ import { runPageSectionTitles, } from '~/concepts/pipelines/content/createRun/const'; import { createRecurringRunRoute, createRunRoute } from '~/routes'; -import { SupportedArea, useIsAreaAvailable } from '~/concepts/areas'; import { RunFormData, RunTypeOption } from '~/concepts/pipelines/content/createRun/types'; interface RunTypeSectionProps { @@ -20,19 +19,13 @@ interface RunTypeSectionProps { export const RunTypeSection: React.FC = ({ data, isCloned }) => { const { namespace, experimentId, pipelineId, pipelineVersionId } = useParams(); const [isAlertOpen, setIsAlertOpen] = React.useState(true); - const isExperimentsAvailable = useIsAreaAvailable(SupportedArea.PIPELINE_EXPERIMENTS).status; let runTypeValue = 'Run once immediately after creation'; let alertTitle = ( <> To create a schedule that executes recurring runs,{' '} @@ -48,12 +41,7 @@ export const RunTypeSection: React.FC = ({ data, isCloned } <> To create a non-recurring run,{' '} diff --git a/frontend/src/concepts/pipelines/content/createRun/utils.ts b/frontend/src/concepts/pipelines/content/createRun/utils.ts index 2cd8daa0cc..76691f1da0 100644 --- a/frontend/src/concepts/pipelines/content/createRun/utils.ts +++ b/frontend/src/concepts/pipelines/content/createRun/utils.ts @@ -48,15 +48,13 @@ export const isFilledRunFormData = (formData: RunFormData): formData is SafeRunF !!formData.nameDesc.name && !!formData.pipeline && !!formData.version && + !!formData.experiment && hasRequiredInputParams && runTypeSafeData(formData.runType) && runTypeSafeDates(formData.runType) ); }; -export const isFilledRunFormDataExperiment = (formData: RunFormData): formData is SafeRunFormData => - isFilledRunFormData(formData) && !!formData.experiment; - export const getInputDefinitionParams = ( version: PipelineVersionKFv2 | null | undefined, ): ParametersKF | undefined => { diff --git a/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRecurringRun/PipelineRecurringRunDetailsActions.tsx b/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRecurringRun/PipelineRecurringRunDetailsActions.tsx index 416e8548af..ddeb5e812b 100644 --- a/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRecurringRun/PipelineRecurringRunDetailsActions.tsx +++ b/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRecurringRun/PipelineRecurringRunDetailsActions.tsx @@ -12,7 +12,6 @@ import { import { usePipelinesAPI } from '~/concepts/pipelines/context'; import { PipelineRecurringRunKFv2, RecurringRunStatus } from '~/concepts/pipelines/kfTypes'; import { cloneRecurringRunRoute } from '~/routes'; -import { useIsAreaAvailable, SupportedArea } from '~/concepts/areas'; import { getDashboardMainContainer } from '~/utilities/utils'; type PipelineRecurringRunDetailsActionsProps = { @@ -29,7 +28,6 @@ const PipelineRecurringRunDetailsActions: React.FC = ({ const { namespace, api, refreshAllAPI } = usePipelinesAPI(); const notification = useNotification(); const [open, setOpen] = React.useState(false); - const isExperimentsAvailable = useIsAreaAvailable(SupportedArea.PIPELINE_EXPERIMENTS).status; const isRunActive = run?.storage_state === StorageStateKF.AVAILABLE; const [experiment] = useExperimentById(run?.experiment_id); const isExperimentActive = experiment?.storage_state === StorageStateKF.AVAILABLE; @@ -102,7 +100,7 @@ const PipelineRunDetailsActions: React.FC = ({ cloneRunRoute( namespace, run.run_id, - isExperimentsAvailable ? experimentId : undefined, + experimentId, pipelineId, pipelineVersionId, ), @@ -124,7 +122,7 @@ const PipelineRunDetailsActions: React.FC = ({ > Stop , - isExperimentsAvailable && experimentId && isRunActive ? ( + experimentId && isRunActive ? ( diff --git a/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/SelectedNodeInputOutputTab.tsx b/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/SelectedNodeInputOutputTab.tsx index 314a931a4d..950e0476d6 100644 --- a/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/SelectedNodeInputOutputTab.tsx +++ b/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/SelectedNodeInputOutputTab.tsx @@ -19,7 +19,6 @@ import { InputDefinitionParameterType } from '~/concepts/pipelines/kfTypes'; import { NoValue } from '~/components/NoValue'; import { executionDetailsRoute } from '~/routes'; import { usePipelinesAPI } from '~/concepts/pipelines/context'; -import { SupportedArea, useIsAreaAvailable } from '~/concepts/areas'; type SelectedNodeInputOutputTabProps = { task: PipelineTask; @@ -31,7 +30,6 @@ const SelectedNodeInputOutputTab: React.FC = ({ execution, }) => { const { namespace } = usePipelinesAPI(); - const isExperimentsAvailable = useIsAreaAvailable(SupportedArea.PIPELINE_EXPERIMENTS).status; const executionDisplayName = React.useMemo( () => @@ -115,7 +113,7 @@ const SelectedNodeInputOutputTab: React.FC = ({ return ( - {isExperimentsAvailable && execution?.id && ( + {execution?.id && ( diff --git a/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/artifacts/ArtifactNodeDetails.tsx b/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/artifacts/ArtifactNodeDetails.tsx index fc5071adca..90be3927de 100644 --- a/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/artifacts/ArtifactNodeDetails.tsx +++ b/frontend/src/concepts/pipelines/content/pipelinesDetails/pipelineRun/artifacts/ArtifactNodeDetails.tsx @@ -18,7 +18,6 @@ import { usePipelinesAPI } from '~/concepts/pipelines/context'; import { getArtifactName } from '~/pages/pipelines/global/experiments/artifacts/utils'; import PipelinesTableRowTime from '~/concepts/pipelines/content/tables/PipelinesTableRowTime'; import PipelineRunDrawerRightContent from '~/concepts/pipelines/content/pipelinesDetails/pipelineRun/PipelineRunDrawerRightContent'; -import { SupportedArea, useIsAreaAvailable } from '~/concepts/areas'; import { ArtifactUriLink } from '~/concepts/pipelines/content/artifacts/ArtifactUriLink'; type ArtifactNodeDetailsProps = Pick< @@ -34,7 +33,6 @@ export const ArtifactNodeDetails: React.FC = ({ }) => { const { namespace } = usePipelinesAPI(); const artifactName = getArtifactName(artifact); - const isExperimentsAvailable = useIsAreaAvailable(SupportedArea.PIPELINE_EXPERIMENTS).status; return ( = ({ Artifact name - {isExperimentsAvailable ? ( - - {artifactName} - - ) : ( - artifactName - )} + {artifactName} Artifact type diff --git a/frontend/src/concepts/pipelines/content/tables/pipelineRecurringRun/PipelineRecurringRunTable.tsx b/frontend/src/concepts/pipelines/content/tables/pipelineRecurringRun/PipelineRecurringRunTable.tsx index 50036f0233..f7277015bf 100644 --- a/frontend/src/concepts/pipelines/content/tables/pipelineRecurringRun/PipelineRecurringRunTable.tsx +++ b/frontend/src/concepts/pipelines/content/tables/pipelineRecurringRun/PipelineRecurringRunTable.tsx @@ -12,7 +12,6 @@ import usePipelineFilter from '~/concepts/pipelines/content/tables/usePipelineFi import SimpleMenuActions from '~/components/SimpleMenuActions'; import { useSetVersionFilter } from '~/concepts/pipelines/content/tables/useSetVersionFilter'; import { pipelineRecurringRunColumns } from '~/concepts/pipelines/content/tables/columns'; -import { SupportedArea, useIsAreaAvailable } from '~/concepts/areas'; import PipelineRecurringRunTableRow from './PipelineRecurringRunTableRow'; import PipelineRecurringRunTableToolbar from './PipelineRecurringRunTableToolbar'; @@ -47,7 +46,6 @@ const PipelineRecurringRunTable: React.FC = ({ const { refreshAllAPI } = usePipelinesAPI(); const { experimentId, pipelineVersionId } = useParams(); const { onClearFilters, ...filterToolbarProps } = usePipelineFilter(setFilter); - const isExperimentsAvailable = useIsAreaAvailable(SupportedArea.PIPELINE_EXPERIMENTS).status; const { selections, tableProps: checkboxTableProps, @@ -62,7 +60,7 @@ const PipelineRecurringRunTable: React.FC = ({ const getColumns = () => { let columns = pipelineRecurringRunColumns; - if (isExperimentsAvailable && experimentId) { + if (experimentId) { columns = columns.filter((column) => column.field !== 'experiment'); } diff --git a/frontend/src/concepts/pipelines/content/tables/pipelineRecurringRun/PipelineRecurringRunTableRow.tsx b/frontend/src/concepts/pipelines/content/tables/pipelineRecurringRun/PipelineRecurringRunTableRow.tsx index c08e61c50f..66bd802403 100644 --- a/frontend/src/concepts/pipelines/content/tables/pipelineRecurringRun/PipelineRecurringRunTableRow.tsx +++ b/frontend/src/concepts/pipelines/content/tables/pipelineRecurringRun/PipelineRecurringRunTableRow.tsx @@ -7,7 +7,6 @@ import { usePipelinesAPI } from '~/concepts/pipelines/context'; import usePipelineRunVersionInfo from '~/concepts/pipelines/content/tables/usePipelineRunVersionInfo'; import { PipelineVersionLink } from '~/concepts/pipelines/content/PipelineVersionLink'; import { cloneRecurringRunRoute, recurringRunDetailsRoute } from '~/routes'; -import { SupportedArea, useIsAreaAvailable } from '~/concepts/areas'; import { RecurringRunCreated, RecurringRunScheduled, @@ -36,9 +35,7 @@ const PipelineRecurringRunTableRow: React.FC const { experimentId, pipelineId, pipelineVersionId } = useParams(); const { namespace, api } = usePipelinesAPI(); const { version, loaded, error } = usePipelineRunVersionInfo(recurringRun); - const isExperimentsAvailable = useIsAreaAvailable(SupportedArea.PIPELINE_EXPERIMENTS).status; - const isExperimentsContext = isExperimentsAvailable && experimentId; - const pipelineRecurringExperimentId = !isExperimentsContext ? recurringRun.experiment_id : ''; + const pipelineRecurringExperimentId = !experimentId ? recurringRun.experiment_id : ''; const [pipelineRecurringExperiment, pipelineRecurringExperimentLoaded] = useExperimentById( pipelineRecurringExperimentId, ); @@ -57,7 +54,7 @@ const PipelineRecurringRunTableRow: React.FC to={recurringRunDetailsRoute( namespace, recurringRun.recurring_run_id, - isExperimentsAvailable ? experimentId : undefined, + experimentId, pipelineId, pipelineVersionId, )} @@ -69,7 +66,7 @@ const PipelineRecurringRunTableRow: React.FC descriptionAsMarkdown /> - {!isExperimentsContext && ( + {!experimentId && ( cloneRecurringRunRoute( namespace, recurringRun.recurring_run_id, - isExperimentsAvailable ? experimentId : undefined, + experimentId, pipelineId, pipelineVersionId, ), diff --git a/frontend/src/concepts/pipelines/content/tables/pipelineRun/PipelineRunTable.tsx b/frontend/src/concepts/pipelines/content/tables/pipelineRun/PipelineRunTable.tsx index 36b065c1d1..640ff3972d 100644 --- a/frontend/src/concepts/pipelines/content/tables/pipelineRun/PipelineRunTable.tsx +++ b/frontend/src/concepts/pipelines/content/tables/pipelineRun/PipelineRunTable.tsx @@ -24,7 +24,6 @@ import { ArchiveRunModal } from '~/pages/pipelines/global/runs/ArchiveRunModal'; import { RestoreRunModal } from '~/pages/pipelines/global/runs/RestoreRunModal'; import { useSetVersionFilter } from '~/concepts/pipelines/content/tables/useSetVersionFilter'; import { createRunRoute, experimentsCompareRunsRoute } from '~/routes'; -import { SupportedArea, useIsAreaAvailable } from '~/concepts/areas'; import { useContextExperimentArchived } from '~/pages/pipelines/global/experiments/ExperimentContext'; import { getArtifactProperties } from '~/concepts/pipelines/content/pipelinesDetails/pipelineRun/artifacts/utils'; import { useGetArtifactsByRuns } from '~/concepts/pipelines/apiHooks/mlmd/useGetArtifactsByRuns'; @@ -83,7 +82,6 @@ const PipelineRunTableInternal: React.FC = ({ isSelected, setSelections: setSelectedIds, } = useCheckboxTable(runs.map(({ run_id: runId }) => runId)); - const isExperimentsAvailable = useIsAreaAvailable(SupportedArea.PIPELINE_EXPERIMENTS).status; const [isDeleteModalOpen, setIsDeleteModalOpen] = React.useState(false); const [isArchiveModalOpen, setIsArchiveModalOpen] = React.useState(false); const [isRestoreModalOpen, setIsRestoreModalOpen] = React.useState(false); @@ -99,7 +97,6 @@ const PipelineRunTableInternal: React.FC = ({ }, []); const restoreButtonTooltipRef = React.useRef(null); const isExperimentArchived = useContextExperimentArchived(); - const isExperimentsEnabled = isExperimentsAvailable && experimentId; const metricsColumnNames = useMetricColumnNames(experimentId ?? '', metricsNames); const primaryToolbarAction = React.useMemo(() => { @@ -132,14 +129,7 @@ const PipelineRunTableInternal: React.FC = ({ data-testid="create-run-button" variant="primary" onClick={() => - navigate( - createRunRoute( - namespace, - isExperimentsAvailable ? experimentId : undefined, - pipelineId, - pipelineVersionId, - ), - ) + navigate(createRunRoute(namespace, experimentId, pipelineId, pipelineVersionId)) } > Create run @@ -151,14 +141,13 @@ const PipelineRunTableInternal: React.FC = ({ selectedIds.length, navigate, namespace, - isExperimentsAvailable, experimentId, pipelineId, pipelineVersionId, ]); const compareRunsAction = - isExperimentsEnabled && !isExperimentArchived ? ( + experimentId && !isExperimentArchived ? ( - { - setOpen(false); - if (experiment) { - if (onCreate) { - onCreate(experiment); + {open ? ( + { + setOpen(false); + if (experiment) { + if (onCreate) { + onCreate(experiment); + } + refreshAllAPI(); } - refreshAllAPI(); - } - }} - /> + }} + /> + ) : null} ); }; diff --git a/frontend/src/concepts/pipelines/content/experiment/CreateExperimentModal.tsx b/frontend/src/concepts/pipelines/content/experiment/CreateExperimentModal.tsx index ab073f5da6..acba31b572 100644 --- a/frontend/src/concepts/pipelines/content/experiment/CreateExperimentModal.tsx +++ b/frontend/src/concepts/pipelines/content/experiment/CreateExperimentModal.tsx @@ -20,11 +20,10 @@ import { import { CharLimitHelperText } from '~/components/CharLimitHelperText'; type CreateExperimentModalProps = { - isOpen: boolean; onClose: (experiment?: ExperimentKFv2) => void; }; -const CreateExperimentModal: React.FC = ({ isOpen, onClose }) => { +const CreateExperimentModal: React.FC = ({ onClose }) => { const { project, api, apiAvailable } = usePipelinesAPI(); const [submitting, setSubmitting] = React.useState(false); const [error, setError] = React.useState(); @@ -41,7 +40,7 @@ const CreateExperimentModal: React.FC = ({ isOpen, o return ( onBeforeClose()} actions={[ diff --git a/frontend/src/concepts/pipelines/content/import/ImportPipelineButton.tsx b/frontend/src/concepts/pipelines/content/import/ImportPipelineButton.tsx index b1136975f3..8182cfd024 100644 --- a/frontend/src/concepts/pipelines/content/import/ImportPipelineButton.tsx +++ b/frontend/src/concepts/pipelines/content/import/ImportPipelineButton.tsx @@ -28,19 +28,20 @@ const ImportPipelineButton: React.FC = ({ > {children || 'Import pipeline'} - { - setOpen(false); - if (pipeline) { - if (onCreate) { - onCreate(pipeline); + {open ? ( + { + setOpen(false); + if (pipeline) { + if (onCreate) { + onCreate(pipeline); + } + refreshAllAPI(); } - refreshAllAPI(); - } - }} - /> + }} + /> + ) : null} ); }; diff --git a/frontend/src/concepts/pipelines/content/import/ImportPipelineSplitButton.tsx b/frontend/src/concepts/pipelines/content/import/ImportPipelineSplitButton.tsx index 2a57b3c1ce..20f3764a09 100644 --- a/frontend/src/concepts/pipelines/content/import/ImportPipelineSplitButton.tsx +++ b/frontend/src/concepts/pipelines/content/import/ImportPipelineSplitButton.tsx @@ -82,18 +82,19 @@ const ImportPipelineSplitButton: React.FC = ({ - { - setPipelineModalOpen(false); - if (pipeline) { - if (onImportPipeline) { - onImportPipeline(pipeline); + {isPipelineModalOpen ? ( + { + setPipelineModalOpen(false); + if (pipeline) { + if (onImportPipeline) { + onImportPipeline(pipeline); + } + refreshAllAPI(); } - refreshAllAPI(); - } - }} - /> + }} + /> + ) : null} {isPipelineVersionModalOpen && ( { diff --git a/frontend/src/concepts/pipelines/content/import/PipelineImportModal.tsx b/frontend/src/concepts/pipelines/content/import/PipelineImportModal.tsx index dbcc61d840..0e19c7c0bb 100644 --- a/frontend/src/concepts/pipelines/content/import/PipelineImportModal.tsx +++ b/frontend/src/concepts/pipelines/content/import/PipelineImportModal.tsx @@ -29,13 +29,11 @@ import PipelineUploadRadio from './PipelineUploadRadio'; import { PipelineUploadOption, extractKindFromPipelineYAML } from './utils'; type PipelineImportModalProps = { - isOpen: boolean; onClose: (pipeline?: PipelineKFv2) => void; redirectAfterImport?: boolean; }; const PipelineImportModal: React.FC = ({ - isOpen, redirectAfterImport = true, onClose, }) => { @@ -152,7 +150,7 @@ const PipelineImportModal: React.FC = ({ return ( onBeforeClose()} actions={[ , - , - ]} - showClose - > -
- {deployInfoError ? ( - - {deployInfoError.message} - - ) : !deployInfoLoaded ? ( - - ) : ( - - - - )} - -
- ); - } - - if (platform === ServingRuntimePlatform.SINGLE) { - return ( - onClose(false)} + actions={[ + , + , + ]} + showClose + > +
+ {deployInfoError ? ( + + {deployInfoError.message} + + ) : !deployInfoLoaded ? ( + + ) : ( + + + )} - shouldFormHidden={!!error} - registeredModelDeployInfo={registeredModelDeployInfo} - projectContext={{ currentProject: selectedProject, dataConnections }} - projectSection={ - - } - /> - ); - } - // platform === ServingRuntimePlatform.MULTI + + + ); + } + + if (platform === ServingRuntimePlatform.SINGLE) { return ( - = ({ /> ); } - return null; + // platform === ServingRuntimePlatform.MULTI + return ( + + } + /> + ); }; export default DeployRegisteredModelModal; diff --git a/frontend/src/pages/modelRegistry/screens/components/ModelLabels.tsx b/frontend/src/pages/modelRegistry/screens/components/ModelLabels.tsx index 37e84e51de..4c8c56b9a1 100644 --- a/frontend/src/pages/modelRegistry/screens/components/ModelLabels.tsx +++ b/frontend/src/pages/modelRegistry/screens/components/ModelLabels.tsx @@ -69,11 +69,11 @@ const ModelLabels: React.FC = ({ name, customProperties }) => ); - const labelModal = ( + const labelModal = isLabelModalOpen ? ( setIsLabelModalOpen(false)} description={ @@ -104,7 +104,7 @@ const ModelLabels: React.FC = ({ name, customProperties }) => {labelsComponent(filteredLabels, '50ch')} - ); + ) : null; if (Object.keys(customProperties).length === 0) { return '-'; diff --git a/frontend/src/pages/modelRegistry/screens/components/RestoreModelVersionModal.tsx b/frontend/src/pages/modelRegistry/screens/components/RestoreModelVersionModal.tsx index dedfcc9270..cd81c2795c 100644 --- a/frontend/src/pages/modelRegistry/screens/components/RestoreModelVersionModal.tsx +++ b/frontend/src/pages/modelRegistry/screens/components/RestoreModelVersionModal.tsx @@ -6,14 +6,12 @@ import useNotification from '~/utilities/useNotification'; interface RestoreModelVersionModalProps { onCancel: () => void; onSubmit: () => void; - isOpen: boolean; modelVersionName: string; } export const RestoreModelVersionModal: React.FC = ({ onCancel, onSubmit, - isOpen, modelVersionName, }) => { const notification = useNotification(); @@ -42,7 +40,7 @@ export const RestoreModelVersionModal: React.FC = return ( void; onSubmit: () => void; - isOpen: boolean; registeredModelName: string; } export const RestoreRegisteredModelModal: React.FC = ({ onCancel, onSubmit, - isOpen, registeredModelName, }) => { const notification = useNotification(); @@ -42,7 +40,7 @@ export const RestoreRegisteredModelModal: React.FC Date: Sun, 6 Oct 2024 17:49:14 +0200 Subject: [PATCH 09/12] chore(quality): add data-testid for the Launch standalone notebook server button (#3294) * https://github.com/red-hat-data-services/ods-ci/pull/1880#issuecomment-2387950341 --- .../src/pages/projects/screens/projects/LaunchJupyterButton.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/pages/projects/screens/projects/LaunchJupyterButton.tsx b/frontend/src/pages/projects/screens/projects/LaunchJupyterButton.tsx index c1ec904725..e250bf596d 100644 --- a/frontend/src/pages/projects/screens/projects/LaunchJupyterButton.tsx +++ b/frontend/src/pages/projects/screens/projects/LaunchJupyterButton.tsx @@ -17,6 +17,7 @@ const LaunchJupyterButton: React.FC = () => { content="Launch a notebook server to create a standalone notebook outside of a project." >