From df273185651a24f88042ef92032a4e896addbd58 Mon Sep 17 00:00:00 2001 From: Yuan Gong Date: Thu, 30 Jan 2020 14:02:01 +0800 Subject: [PATCH 1/9] Implement getting started page. --- frontend/src/components/Router.tsx | 5 ++- frontend/src/components/SideNav.tsx | 29 ++++++++++++ frontend/src/pages/GettingStarted.tsx | 64 +++++++++++++++++++++++++++ 3 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 frontend/src/pages/GettingStarted.tsx diff --git a/frontend/src/components/Router.tsx b/frontend/src/components/Router.tsx index c43dd68eb67..3a6618ef81e 100644 --- a/frontend/src/components/Router.tsx +++ b/frontend/src/components/Router.tsx @@ -43,6 +43,7 @@ import { Route, Switch, Redirect } from 'react-router-dom'; import { classes, stylesheet } from 'typestyle'; import { commonCss } from '../Css'; import NewPipelineVersion from '../pages/NewPipelineVersion'; +import { GettingStarted } from 'src/pages/GettingStarted'; export type RouteConfig = { path: string; Component: React.ComponentType; view?: any }; @@ -85,6 +86,7 @@ export const RoutePrefix = { // tslint:disable-next-line:variable-name export const RoutePage = { + START: '/start', ARCHIVE: '/archive', ARTIFACTS: '/artifacts', ARTIFACT_DETAILS: `/artifact_types/:${RouteParams.ARTIFACT_TYPE}+/artifacts/:${RouteParams.ID}`, @@ -142,6 +144,7 @@ export interface RouterProps { // This component is made as a wrapper to separate toolbar state for different pages. const Router: React.FC = ({ configs }) => { const routes: RouteConfig[] = configs || [ + { path: RoutePage.START, Component: GettingStarted }, { path: RoutePage.ARCHIVE, Component: Archive }, { path: RoutePage.ARTIFACTS, Component: ArtifactList }, { path: RoutePage.ARTIFACT_DETAILS, Component: ArtifactDetails }, @@ -170,7 +173,7 @@ const Router: React.FC = ({ configs }) => { } + render={({ ...props }) => } /> {/* Normal routes */} diff --git a/frontend/src/components/SideNav.tsx b/frontend/src/components/SideNav.tsx index 09a0b5ec8ca..ac0ae0c8afb 100644 --- a/frontend/src/components/SideNav.tsx +++ b/frontend/src/components/SideNav.tsx @@ -267,6 +267,35 @@ export default class SideNav extends React.Component )} >
+
+ + + + +
{ + public getInitialToolbarState(): ToolbarProps { + const buttons = new Buttons(this.props, this.refresh.bind(this)); + return { + actions: buttons.getToolbarActionMap(), + breadcrumbs: [], + pageTitle: 'Getting Started', + }; + } + + public async refresh() {} + + public render(): JSX.Element { + return ( +
+
+

Getting Started - Build a pipeline

+

+ Classification + + Start Here + +

+

+ The table below provides a few demo and tutorial pipelines, and also allows you to + upload your own pipelines. You can access additional samples and tutorials at + + pipelines Github Repo. + +

+
+
+ ); + } +} From 9e3a9917b80e6411dd07b8b5da7a069f16a7979c Mon Sep 17 00:00:00 2001 From: Yuan Gong Date: Thu, 30 Jan 2020 14:40:13 +0800 Subject: [PATCH 2/9] Add feature flag to only show getting started page on hosted pipelines --- frontend/server/configs.ts | 1 + frontend/server/handlers/index-html.ts | 4 ++ frontend/src/components/Router.tsx | 8 ++- frontend/src/components/SideNav.tsx | 57 ++++++++++--------- frontend/src/lib/Flags.ts | 4 ++ frontend/src/pages/GettingStarted.tsx | 4 +- .../templates/pipeline.yaml | 2 + 7 files changed, 51 insertions(+), 29 deletions(-) diff --git a/frontend/server/configs.ts b/frontend/server/configs.ts index 4e1df1e7d7c..9b4c6faec7f 100644 --- a/frontend/server/configs.ts +++ b/frontend/server/configs.ts @@ -20,6 +20,7 @@ export const apiVersionPrefix = `apis/${apiVersion}`; export enum Deployments { NOT_SPECIFIED = 'NOT_SPECIFIED', KUBEFLOW = 'KUBEFLOW', + MARKETPLACE = 'MARKETPLACE', } /** converts string to bool */ diff --git a/frontend/server/handlers/index-html.ts b/frontend/server/handlers/index-html.ts index 92c9d7fed31..63574888431 100644 --- a/frontend/server/handlers/index-html.ts +++ b/frontend/server/handlers/index-html.ts @@ -66,5 +66,9 @@ function replaceRuntimeContent(content: string | undefined, deployment: Deployme ``, ); } + if (content && deployment === Deployments.MARKETPLACE) { + return content + .replace(DEFAULT_FLAG, 'window.KFP_FLAGS.DEPLOYMENT="MARKETPLACE"') + } return content; } diff --git a/frontend/src/components/Router.tsx b/frontend/src/components/Router.tsx index 3a6618ef81e..dd5bd087af9 100644 --- a/frontend/src/components/Router.tsx +++ b/frontend/src/components/Router.tsx @@ -44,6 +44,7 @@ import { classes, stylesheet } from 'typestyle'; import { commonCss } from '../Css'; import NewPipelineVersion from '../pages/NewPipelineVersion'; import { GettingStarted } from 'src/pages/GettingStarted'; +import { KFP_FLAGS, Deployments } from 'src/lib/Flags'; export type RouteConfig = { path: string; Component: React.ComponentType; view?: any }; @@ -86,7 +87,6 @@ export const RoutePrefix = { // tslint:disable-next-line:variable-name export const RoutePage = { - START: '/start', ARCHIVE: '/archive', ARTIFACTS: '/artifacts', ARTIFACT_DETAILS: `/artifact_types/:${RouteParams.ARTIFACT_TYPE}+/artifacts/:${RouteParams.ID}`, @@ -104,6 +104,7 @@ export const RoutePage = { RECURRING_RUN: `/recurringrun/details/:${RouteParams.runId}`, RUNS: '/runs', RUN_DETAILS: `/runs/details/:${RouteParams.runId}`, + START: '/start', }; export const RoutePageFactory = { @@ -141,6 +142,9 @@ export interface RouterProps { configs?: RouteConfig[]; // only used in tests } +const DEFAULT_ROUTE = + KFP_FLAGS.DEPLOYMENT === Deployments.MARKETPLACE ? RoutePage.START : RoutePage.PIPELINES; + // This component is made as a wrapper to separate toolbar state for different pages. const Router: React.FC = ({ configs }) => { const routes: RouteConfig[] = configs || [ @@ -173,7 +177,7 @@ const Router: React.FC = ({ configs }) => { } + render={({ ...props }) => } /> {/* Normal routes */} diff --git a/frontend/src/components/SideNav.tsx b/frontend/src/components/SideNav.tsx index ac0ae0c8afb..ccc23495c4e 100644 --- a/frontend/src/components/SideNav.tsx +++ b/frontend/src/components/SideNav.tsx @@ -36,6 +36,7 @@ import { RouterProps } from 'react-router'; import { classes, stylesheet } from 'typestyle'; import { fontsize, commonCss } from '../Css'; import { logger } from '../lib/Utils'; +import { KFP_FLAGS, Deployments } from 'src/lib/Flags'; export const sideNavColors = { bg: '#f8fafb', @@ -267,35 +268,39 @@ export default class SideNav extends React.Component )} >
-
- - - - - + + + + + + )}
{ }; } - public async refresh() {} + public async refresh() { + // do nothing + } public render(): JSX.Element { return ( diff --git a/manifests/gcp_marketplace/chart/kubeflow-pipelines/templates/pipeline.yaml b/manifests/gcp_marketplace/chart/kubeflow-pipelines/templates/pipeline.yaml index e05e2be5940..c682894cc2d 100644 --- a/manifests/gcp_marketplace/chart/kubeflow-pipelines/templates/pipeline.yaml +++ b/manifests/gcp_marketplace/chart/kubeflow-pipelines/templates/pipeline.yaml @@ -557,6 +557,8 @@ spec: value: {{ .Release.Namespace }} - name: ALLOW_CUSTOM_VISUALIZATIONS value: "true" + - name: DEPLOYMENT + value: MARKETPLACE image: {{ .Values.images.frontend }} imagePullPolicy: IfNotPresent name: ml-pipeline-ui From 3dd28bdb5533f16d546b718f16fd353bb19974df Mon Sep 17 00:00:00 2001 From: Yuan Gong Date: Thu, 30 Jan 2020 15:00:49 +0800 Subject: [PATCH 3/9] Add tests --- frontend/server/app.test.ts | 39 ++++++++++++++----- frontend/server/configs.ts | 4 +- frontend/src/components/Router.tsx | 4 +- frontend/src/components/SideNav.tsx | 2 +- .../__snapshots__/Router.test.tsx.snap | 38 ++++++++++-------- frontend/src/lib/Flags.ts | 11 ++++-- 6 files changed, 64 insertions(+), 34 deletions(-) diff --git a/frontend/server/app.test.ts b/frontend/server/app.test.ts index 3f051ab3c55..8136826107e 100644 --- a/frontend/server/app.test.ts +++ b/frontend/server/app.test.ts @@ -24,7 +24,6 @@ import { Storage as GCSStorage } from '@google-cloud/storage'; import { UIServer } from './app'; import { loadConfigs } from './configs'; import * as minioHelper from './minio-helper'; -import { getTensorboardInstance } from './k8s-helper'; jest.mock('minio'); jest.mock('node-fetch'); @@ -46,15 +45,6 @@ describe('UIServer apis', () => { -`; - const expectedIndexHtml = ` - - - - - `; beforeAll(() => { @@ -92,6 +82,15 @@ describe('UIServer apis', () => { }); it('responds with a modified index.html if it is a kubeflow deployment', done => { + const expectedIndexHtml = ` + + + + + +`; const configs = loadConfigs(argv, { DEPLOYMENT: 'kubeflow' }); app = new UIServer(configs); @@ -101,6 +100,26 @@ describe('UIServer apis', () => { .expect('Content-Type', 'text/html; charset=utf-8') .expect(200, expectedIndexHtml, done); }); + + it('responds with flag DEPLOYMENT=MARKETPLACE if it is a marketplace deployment', done => { + const expectedIndexHtml = ` + + + + + +`; + const configs = loadConfigs(argv, { DEPLOYMENT: 'marketplace' }); + app = new UIServer(configs); + + const request = requests(app.start()); + request + .get('/') + .expect('Content-Type', 'text/html; charset=utf-8') + .expect(200, expectedIndexHtml, done); + }) }); describe('/apis/v1beta1/healthz', () => { diff --git a/frontend/server/configs.ts b/frontend/server/configs.ts index 9b4c6faec7f..c79854b65b5 100644 --- a/frontend/server/configs.ts +++ b/frontend/server/configs.ts @@ -133,8 +133,10 @@ export function loadConfigs( apiVersionPrefix, basePath: BASEPATH, deployment: - DEPLOYMENT_STR.toUpperCase() === 'KUBEFLOW' + DEPLOYMENT_STR.toUpperCase() === Deployments.KUBEFLOW ? Deployments.KUBEFLOW + : DEPLOYMENT_STR.toUpperCase() === Deployments.MARKETPLACE + ? Deployments.MARKETPLACE : Deployments.NOT_SPECIFIED, port, staticDir, diff --git a/frontend/src/components/Router.tsx b/frontend/src/components/Router.tsx index dd5bd087af9..9e57dd816db 100644 --- a/frontend/src/components/Router.tsx +++ b/frontend/src/components/Router.tsx @@ -43,8 +43,8 @@ import { Route, Switch, Redirect } from 'react-router-dom'; import { classes, stylesheet } from 'typestyle'; import { commonCss } from '../Css'; import NewPipelineVersion from '../pages/NewPipelineVersion'; -import { GettingStarted } from 'src/pages/GettingStarted'; -import { KFP_FLAGS, Deployments } from 'src/lib/Flags'; +import { GettingStarted } from '../pages/GettingStarted'; +import { KFP_FLAGS, Deployments } from '../lib/Flags'; export type RouteConfig = { path: string; Component: React.ComponentType; view?: any }; diff --git a/frontend/src/components/SideNav.tsx b/frontend/src/components/SideNav.tsx index ccc23495c4e..f5dabea8eaf 100644 --- a/frontend/src/components/SideNav.tsx +++ b/frontend/src/components/SideNav.tsx @@ -36,7 +36,7 @@ import { RouterProps } from 'react-router'; import { classes, stylesheet } from 'typestyle'; import { fontsize, commonCss } from '../Css'; import { logger } from '../lib/Utils'; -import { KFP_FLAGS, Deployments } from 'src/lib/Flags'; +import { KFP_FLAGS, Deployments } from '../lib/Flags'; export const sideNavColors = { bg: '#f8fafb', diff --git a/frontend/src/components/__snapshots__/Router.test.tsx.snap b/frontend/src/components/__snapshots__/Router.test.tsx.snap index 2d85c6dc018..cc2db325309 100644 --- a/frontend/src/components/__snapshots__/Router.test.tsx.snap +++ b/frontend/src/components/__snapshots__/Router.test.tsx.snap @@ -10,102 +10,108 @@ exports[`Router initial render 1`] = ` + diff --git a/frontend/src/lib/Flags.ts b/frontend/src/lib/Flags.ts index f355f386512..5772208745c 100644 --- a/frontend/src/lib/Flags.ts +++ b/frontend/src/lib/Flags.ts @@ -6,10 +6,13 @@ export enum Deployments { export const KFP_FLAGS = { DEPLOYMENT: // tslint:disable-next-line:no-string-literal - window && window['KFP_FLAGS'] && window['KFP_FLAGS']['DEPLOYMENT'] === Deployments.KUBEFLOW - ? Deployments.KUBEFLOW + window && window['KFP_FLAGS'] // tslint:disable-next-line:no-string-literal - : window['KFP_FLAGS']['DEPLOYMENT'] === Deployments.MARKETPLACE - ? Deployments.MARKETPLACE + ? window['KFP_FLAGS']['DEPLOYMENT'] === Deployments.KUBEFLOW + ? Deployments.KUBEFLOW + // tslint:disable-next-line:no-string-literal + : window['KFP_FLAGS']['DEPLOYMENT'] === Deployments.MARKETPLACE + ? Deployments.MARKETPLACE + : undefined : undefined, }; From 5cf8eee4cd8bd1063d16b7080ff8e36217fde6a0 Mon Sep 17 00:00:00 2001 From: Yuan Gong Date: Thu, 30 Jan 2020 15:15:47 +0800 Subject: [PATCH 4/9] Fix format --- frontend/server/app.test.ts | 6 +++--- frontend/server/handlers/index-html.ts | 3 +-- frontend/src/lib/Flags.ts | 8 ++++---- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/frontend/server/app.test.ts b/frontend/server/app.test.ts index 8136826107e..ff20c736916 100644 --- a/frontend/server/app.test.ts +++ b/frontend/server/app.test.ts @@ -82,7 +82,7 @@ describe('UIServer apis', () => { }); it('responds with a modified index.html if it is a kubeflow deployment', done => { - const expectedIndexHtml = ` + const expectedIndexHtml = `