Skip to content

Commit

Permalink
refactor pipelines and experiments routes
Browse files Browse the repository at this point in the history
  • Loading branch information
DaoDaoNoCode committed Jul 2, 2024
1 parent 5274af0 commit b99da85
Show file tree
Hide file tree
Showing 76 changed files with 1,636 additions and 1,086 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ describe('Experiments', () => {

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

it('has "Experiment" value pre-filled when on the "Create run" page', () => {
Expand Down Expand Up @@ -311,7 +311,7 @@ describe('Runs page for archived experiment', () => {

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

it('has empty state on active runs tab', () => {
Expand Down
5 changes: 0 additions & 5 deletions frontend/src/app/AppRoutes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
globArtifactsAll,
globExecutionsAll,
globExperimentsAll,
globPipelineRunsAll,
globPipelinesAll,
} from '~/routes';
import { useCheckJupyterEnabled } from '~/utilities/notebookControllerUtils';
Expand All @@ -33,9 +32,6 @@ const NotebookController = React.lazy(
);

const GlobalPipelinesRoutes = React.lazy(() => import('../pages/pipelines/GlobalPipelinesRoutes'));
const GlobalPipelineRunsRoutes = React.lazy(
() => import('../pages/pipelines/GlobalPipelineRunsRoutes'),
);
const GlobalPipelineExperimentRoutes = React.lazy(
() => import('../pages/pipelines/GlobalPipelineExperimentsRoutes'),
);
Expand Down Expand Up @@ -115,7 +111,6 @@ const AppRoutes: React.FC = () => {
<Route path="/modelRegistry/*" element={<ModelRegistryRoutes />} />

<Route path={globPipelinesAll} element={<GlobalPipelinesRoutes />} />
<Route path={globPipelineRunsAll} element={<GlobalPipelineRunsRoutes />} />
<Route path={globExperimentsAll} element={<GlobalPipelineExperimentRoutes />} />
<Route path={globArtifactsAll} element={<GlobalArtifactsRoutes />} />
<Route path={globExecutionsAll} element={<GlobalPipelineExecutionsRoutes />} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Link } from 'react-router-dom';
import { Skeleton, Tooltip } from '@patternfly/react-core';
import { usePipelinesAPI } from '~/concepts/pipelines/context';
import { PipelineVersionKFv2 } from '~/concepts/pipelines/kfTypes';
import { routePipelineDetailsNamespace } from '~/routes';
import { pipelineVersionDetailsRoute } from '~/routes';
import { NoRunContent } from './tables/renderUtils';

interface PipelineVersionLinkProps {
Expand Down Expand Up @@ -41,11 +41,7 @@ export const PipelineVersionLink: React.FC<PipelineVersionLinkProps> = ({

return (
<Link
to={routePipelineDetailsNamespace(
namespace,
version.pipeline_id,
version.pipeline_version_id,
)}
to={pipelineVersionDetailsRoute(namespace, version.pipeline_id, version.pipeline_version_id)}
>
{version.display_name}
</Link>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,15 @@ const CompareRunTableRow: React.FC<CompareRunTableRowProps> = ({
<TableRowTitleDescription
title={
<TableText wrapModifier="truncate">
<Link to={runDetailsRoute(namespace, run.run_id, run.experiment_id)}>
<Link
to={runDetailsRoute(
namespace,
run.run_id,
run.experiment_id,
version?.pipeline_id,
version?.pipeline_version_id,
)}
>
{run.display_name}
</Link>
</TableText>
Expand Down
57 changes: 40 additions & 17 deletions frontend/src/concepts/pipelines/content/createRun/CloneRunPage.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,60 @@
import React from 'react';
import { Breadcrumb, BreadcrumbItem } from '@patternfly/react-core';
import { Breadcrumb, BreadcrumbItem, Truncate } from '@patternfly/react-core';

import { useParams, Link } from 'react-router-dom';
import RunPage from '~/concepts/pipelines/content/createRun/RunPage';
import ApplicationsPage from '~/pages/ApplicationsPage';
import useCloneRunData from '~/concepts/pipelines/content/createRun/useCloneRunData';
import { PathProps, PipelineRunSearchParam } from '~/concepts/pipelines/content/types';
import { useGetSearchParamValues } from '~/utilities/useGetSearchParamValues';
import { PipelineRunType } from '~/pages/pipelines/global/runs';
import { asEnumMember } from '~/utilities/utils';
import { runTypeCategory } from './types';
import { PathProps } from '~/concepts/pipelines/content/types';
import { ExperimentKFv2, PipelineKFv2, PipelineVersionKFv2 } from '~/concepts/pipelines/kfTypes';
import usePipelineRunById from '~/concepts/pipelines/apiHooks/usePipelineRunById';
import { RunTypeOption } from './types';

const CloneRunPage: React.FC<PathProps> = ({ breadcrumbPath, contextPath }) => {
const [run, loaded, error] = useCloneRunData();
const { runType: runTypeString } = useGetSearchParamValues([PipelineRunSearchParam.RunType]);
const runType = asEnumMember(runTypeString, PipelineRunType);
const title = `Duplicate ${runTypeCategory[runType || PipelineRunType.ACTIVE]}`;
type CloneRunPageProps = {
detailsRedirect: (runId: string) => string;
contextExperiment?: ExperimentKFv2 | null;
contextPipeline?: PipelineKFv2 | null;
contextPipelineVersion?: PipelineVersionKFv2 | null;
};

const CloneRunPage: React.FC<PathProps & CloneRunPageProps> = ({
breadcrumbPath,
contextPath,
detailsRedirect,
...props
}) => {
const { runId } = useParams();
const [run, loaded, error] = usePipelineRunById(runId);

return (
<ApplicationsPage
title={title}
title="Duplicate run"
breadcrumb={
<Breadcrumb>
{breadcrumbPath(runType)}
<BreadcrumbItem isActive>
{run ? `Duplicate of ${run.display_name}` : 'Duplicate'}
{breadcrumbPath}
<BreadcrumbItem isActive style={{ maxWidth: 300 }}>
{run ? (
<Link to={detailsRedirect(run.run_id)}>
{/* TODO: Remove the custom className after upgrading to PFv6 */}
<Truncate content={run.display_name} className="truncate-no-min-width" />
</Link>
) : (
'Loading...'
)}
</BreadcrumbItem>
<BreadcrumbItem isActive>Duplicate run</BreadcrumbItem>
</Breadcrumb>
}
loaded={loaded}
loadError={error}
empty={false}
>
<RunPage cloneRun={run} contextPath={contextPath} testId="clone-run-page" />
<RunPage
cloneRun={run}
contextPath={contextPath}
runType={RunTypeOption.ONE_TRIGGER}
testId="clone-run-page"
{...props}
/>
</ApplicationsPage>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import React from 'react';
import { Breadcrumb, BreadcrumbItem, Truncate } from '@patternfly/react-core';

import { useParams, Link } from 'react-router-dom';
import RunPage from '~/concepts/pipelines/content/createRun/RunPage';
import ApplicationsPage from '~/pages/ApplicationsPage';
import { PathProps } from '~/concepts/pipelines/content/types';
import { ExperimentKFv2, PipelineKFv2, PipelineVersionKFv2 } from '~/concepts/pipelines/kfTypes';
import usePipelineRunJobById from '~/concepts/pipelines/apiHooks/usePipelineRunJobById';
import { RunTypeOption } from './types';

type CloneSchedulePageProps = {
detailsRedirect: (jobId: string) => string;
contextExperiment?: ExperimentKFv2 | null;
contextPipeline?: PipelineKFv2 | null;
contextPipelineVersion?: PipelineVersionKFv2 | null;
};

const CloneSchedulePage: React.FC<PathProps & CloneSchedulePageProps> = ({
breadcrumbPath,
contextPath,
detailsRedirect,
...props
}) => {
const { recurringRunId } = useParams();
const [job, loaded, error] = usePipelineRunJobById(recurringRunId);

return (
<ApplicationsPage
title="Duplicate schedule"
breadcrumb={
<Breadcrumb>
{breadcrumbPath}
<BreadcrumbItem isActive style={{ maxWidth: 300 }}>
{job ? (
<Link to={detailsRedirect(job.recurring_run_id)}>
{/* TODO: Remove the custom className after upgrading to PFv6 */}
<Truncate content={job.display_name} className="truncate-no-min-width" />
</Link>
) : (
'Loading...'
)}
</BreadcrumbItem>
<BreadcrumbItem isActive>Duplicate schedule</BreadcrumbItem>
</Breadcrumb>
}
loaded={loaded}
loadError={error}
empty={false}
>
<RunPage
cloneRun={job}
contextPath={contextPath}
runType={RunTypeOption.SCHEDULED}
testId="clone-run-page"
{...props}
/>
</ApplicationsPage>
);
};

export default CloneSchedulePage;
29 changes: 19 additions & 10 deletions frontend/src/concepts/pipelines/content/createRun/CreateRunPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,39 @@ import * as React from 'react';
import { Breadcrumb, BreadcrumbItem } from '@patternfly/react-core';

import RunPage from '~/concepts/pipelines/content/createRun/RunPage';
import { PathProps, PipelineRunSearchParam } from '~/concepts/pipelines/content/types';
import { PathProps } from '~/concepts/pipelines/content/types';
import ApplicationsPage from '~/pages/ApplicationsPage';
import { PipelineRunType } from '~/pages/pipelines/global/runs';
import { useGetSearchParamValues } from '~/utilities/useGetSearchParamValues';
import { RunTypeOption } from '~/concepts/pipelines/content/createRun/types';
import { ExperimentKFv2, PipelineKFv2, PipelineVersionKFv2 } from '~/concepts/pipelines/kfTypes';

const CreateRunPage: React.FC<PathProps> = ({ breadcrumbPath, contextPath }) => {
const { runType } = useGetSearchParamValues([PipelineRunSearchParam.RunType]);
const title = `${runType === PipelineRunType.SCHEDULED ? 'Schedule' : 'Create'} run`;
type CreateRunPageProps = {
runType: RunTypeOption;
contextExperiment?: ExperimentKFv2 | null;
contextPipeline?: PipelineKFv2 | null;
contextPipelineVersion?: PipelineVersionKFv2 | null;
};

const CreateRunPage: React.FC<PathProps & CreateRunPageProps> = ({
breadcrumbPath,
contextPath,
runType,
...props
}) => {
const title = `Create ${runType === RunTypeOption.SCHEDULED ? 'schedule' : 'run'}`;

return (
<ApplicationsPage
title={title}
breadcrumb={
<Breadcrumb>
{breadcrumbPath(
runType === PipelineRunType.SCHEDULED ? PipelineRunType.SCHEDULED : undefined,
)}
{breadcrumbPath}
<BreadcrumbItem isActive>{title}</BreadcrumbItem>
</Breadcrumb>
}
loaded
empty={false}
>
<RunPage contextPath={contextPath} testId="create-run-page" />
<RunPage contextPath={contextPath} testId="create-run-page" runType={runType} {...props} />
</ApplicationsPage>
);
};
Expand Down
18 changes: 10 additions & 8 deletions frontend/src/concepts/pipelines/content/createRun/RunForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,29 @@ import NameDescriptionField from '~/concepts/k8s/NameDescriptionField';
import { RunFormData, RunTypeOption } from '~/concepts/pipelines/content/createRun/types';
import { ValueOf } from '~/typeHelpers';
import { ParamsSection } from '~/concepts/pipelines/content/createRun/contentSections/ParamsSection';
import { useLatestPipelineVersion } from '~/concepts/pipelines/apiHooks/useLatestPipelineVersion';
import RunTypeSectionScheduled from '~/concepts/pipelines/content/createRun/contentSections/RunTypeSectionScheduled';
import { PipelineVersionKFv2, RuntimeConfigParameters } from '~/concepts/pipelines/kfTypes';
import { PipelineRunType } from '~/pages/pipelines/global/runs';
import ProjectAndExperimentSection from '~/concepts/pipelines/content/createRun/contentSections/ProjectAndExperimentSection';
import { getDisplayNameFromK8sResource } from '~/concepts/k8s/utils';
import { useLatestPipelineVersion } from '~/concepts/pipelines/apiHooks/useLatestPipelineVersion';
import PipelineSection from './contentSections/PipelineSection';
import { RunTypeSection } from './contentSections/RunTypeSection';
import { CreateRunPageSections, RUN_NAME_CHARACTER_LIMIT, runPageSectionTitles } from './const';
import { getInputDefinitionParams } from './utils';

type RunFormProps = {
data: RunFormData;
runType: PipelineRunType;
onValueChange: (key: keyof RunFormData, value: ValueOf<RunFormData>) => void;
isCloned: boolean;
};

const RunForm: React.FC<RunFormProps> = ({ data, runType, onValueChange }) => {
const RunForm: React.FC<RunFormProps> = ({ data, onValueChange, isCloned }) => {
const [latestVersion] = useLatestPipelineVersion(data.pipeline?.pipeline_id);
// Use this state to avoid the pipeline version being set as the latest version at the initial load
const [initialLoadedState, setInitialLoadedState] = React.useState(true);
const selectedVersion = data.version || latestVersion;
const paramsRef = React.useRef(data.params);
const isSchedule = runType === PipelineRunType.SCHEDULED;
const isSchedule = data.runType.type === RunTypeOption.SCHEDULED;

const updateInputParams = React.useCallback(
(version: PipelineVersionKFv2 | undefined) =>
Expand All @@ -43,15 +44,15 @@ const RunForm: React.FC<RunFormProps> = ({ data, runType, onValueChange }) => {
);

React.useEffect(() => {
if (latestVersion) {
if (!initialLoadedState && latestVersion) {
onValueChange('version', latestVersion);
updateInputParams(latestVersion);
}
}, [latestVersion, onValueChange, updateInputParams]);
}, [initialLoadedState, latestVersion, onValueChange, updateInputParams]);

return (
<Form onSubmit={(e) => e.preventDefault()} maxWidth="500px">
<RunTypeSection runType={runType} />
<RunTypeSection data={data} isCloned={isCloned} />

<ProjectAndExperimentSection
projectName={getDisplayNameFromK8sResource(data.project)}
Expand Down Expand Up @@ -91,6 +92,7 @@ const RunForm: React.FC<RunFormProps> = ({ data, runType, onValueChange }) => {
version={selectedVersion}
onValueChange={onValueChange}
updateInputParams={updateInputParams}
setInitialLoadedState={setInitialLoadedState}
/>

<ParamsSection
Expand Down
Loading

0 comments on commit b99da85

Please sign in to comment.