Skip to content

Commit e9d863c

Browse files
[UI] Project wizard (#3103)
* [UI] Project wizard dstackai/dstack-cloud#323 * [UI] Project wizard #323 * [UI] Project wizard #323 Cosmetics * [UI] Project wizard #323 * [UI] Project wizard #323 * [UI] Project wizard #323 * [UI] Project wizard #323 * [UI] Project wizard #323 Captions --------- Co-authored-by: peterschmidt85 <andrey.cheptsov@gmail.com>
1 parent 6d9b016 commit e9d863c

File tree

22 files changed

+750
-27
lines changed

22 files changed

+750
-27
lines changed

frontend/package-lock.json

Lines changed: 12 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,15 @@
104104
"@cloudscape-design/global-styles": "^1.0.45",
105105
"@hookform/resolvers": "^2.9.10",
106106
"@reduxjs/toolkit": "^1.9.1",
107+
"@types/yup": "^0.29.14",
107108
"ace-builds": "^1.36.3",
108109
"classnames": "^2.5.1",
109110
"css-minimizer-webpack-plugin": "^4.2.2",
110111
"date-fns": "^2.29.3",
111112
"i18next": "^24.0.2",
112113
"lodash": "^4.17.21",
113114
"openai": "^4.33.1",
114-
"prismjs": "^1.29.0",
115+
"prismjs": "^1.30.0",
115116
"rc-tooltip": "^5.2.2",
116117
"react": "^18.3.1",
117118
"react-avatar": "^5.0.3",

frontend/src/App/Login/LoginByGithubCallback/index.tsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { UnauthorizedLayout } from 'layouts/UnauthorizedLayout';
88
import { useAppDispatch } from 'hooks';
99
import { ROUTES } from 'routes';
1010
import { useGithubCallbackMutation } from 'services/auth';
11+
import { useLazyGetProjectsQuery } from 'services/project';
1112

1213
import { AuthErrorMessage } from 'App/AuthErrorMessage';
1314
import { Loading } from 'App/Loading';
@@ -22,13 +23,24 @@ export const LoginByGithubCallback: React.FC = () => {
2223
const dispatch = useAppDispatch();
2324

2425
const [githubCallback] = useGithubCallbackMutation();
26+
const [getProjects] = useLazyGetProjectsQuery();
2527

2628
const checkCode = () => {
2729
if (code) {
2830
githubCallback({ code })
2931
.unwrap()
30-
.then(({ creds: { token } }) => {
32+
.then(async ({ creds: { token } }) => {
3133
dispatch(setAuthData({ token }));
34+
35+
if (process.env.UI_VERSION === 'sky') {
36+
const result = await getProjects().unwrap();
37+
38+
if (result?.length === 0) {
39+
navigate(ROUTES.PROJECT.ADD);
40+
return;
41+
}
42+
}
43+
3244
navigate('/');
3345
})
3446
.catch(() => {

frontend/src/App/slice.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ const getInitialState = (): IAppState => {
6161
},
6262

6363
tutorialPanel: {
64+
createProjectCompleted: false,
6465
billingCompleted: false,
6566
configureCLICompleted: false,
6667
discordCompleted: false,

frontend/src/App/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export interface IAppState {
3232
};
3333

3434
tutorialPanel: {
35+
createProjectCompleted: boolean;
3536
billingCompleted: boolean;
3637
configureCLICompleted: boolean;
3738
discordCompleted: boolean;

frontend/src/api.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ export const API = {
5858
BASE: () => `${API.BASE()}/projects`,
5959
LIST: () => `${API.PROJECTS.BASE()}/list`,
6060
CREATE: () => `${API.PROJECTS.BASE()}/create`,
61+
CREATE_WIZARD: () => `${API.PROJECTS.BASE()}/create_wizard`,
6162
DELETE: () => `${API.PROJECTS.BASE()}/delete`,
6263
DETAILS: (name: IProject['project_name']) => `${API.PROJECTS.BASE()}/${name}`,
6364
DETAILS_INFO: (name: IProject['project_name']) => `${API.PROJECTS.DETAILS(name)}/get`,
@@ -112,6 +113,7 @@ export const API = {
112113
BACKENDS: {
113114
BASE: () => `${API.BASE()}/backends`,
114115
LIST_TYPES: () => `${API.BACKENDS.BASE()}/list_types`,
116+
LIST_BASE_TYPES: () => `${API.BACKENDS.BASE()}/list_base_types`,
115117
CONFIG_VALUES: () => `${API.BACKENDS.BASE()}/config_values`,
116118
},
117119

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import React from 'react';
2+
import { Controller, FieldValues } from 'react-hook-form';
3+
import Cards from '@cloudscape-design/components/cards';
4+
import { CardsProps } from '@cloudscape-design/components/cards';
5+
6+
import { FormCardsProps } from './types';
7+
8+
export const FormCards = <T extends FieldValues>({
9+
name,
10+
control,
11+
onSelectionChange: onSelectionChangeProp,
12+
...props
13+
}: FormCardsProps<T>) => {
14+
return (
15+
<Controller
16+
name={name}
17+
control={control}
18+
render={({ field: { onChange, ...fieldRest } }) => {
19+
const onSelectionChange: CardsProps['onSelectionChange'] = (event) => {
20+
onChange(event.detail.selectedItems.map(({ value }) => value));
21+
onSelectionChangeProp?.(event);
22+
};
23+
24+
const selectedItems = props.items.filter((item) => fieldRest.value?.includes(item.value));
25+
26+
return (
27+
<Cards
28+
onSelectionChange={onSelectionChange}
29+
trackBy="value"
30+
{...fieldRest}
31+
{...props}
32+
selectedItems={selectedItems}
33+
/>
34+
);
35+
}}
36+
/>
37+
);
38+
};
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { Control, FieldValues, Path } from 'react-hook-form';
2+
import { CardsProps } from '@cloudscape-design/components/cards';
3+
4+
export type FormCardsProps<T extends FieldValues> = CardsProps & {
5+
control: Control<T, object>;
6+
name: Path<T>;
7+
};

frontend/src/components/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@ export type { LineChartProps } from '@cloudscape-design/components/line-chart/in
6161
export type { ModalProps } from '@cloudscape-design/components/modal';
6262
export { default as AnchorNavigation } from '@cloudscape-design/components/anchor-navigation';
6363
export { default as ExpandableSection } from '@cloudscape-design/components/expandable-section';
64+
export { default as KeyValuePairs } from '@cloudscape-design/components/key-value-pairs';
6465
export { I18nProvider } from '@cloudscape-design/components/i18n';
66+
export { default as Wizard } from '@cloudscape-design/components/wizard';
6567

6668
// custom components
6769
export { NavigateLink } from './NavigateLink';
@@ -80,6 +82,8 @@ export type { FormMultiselectOptions, FormMultiselectProps } from './form/Multis
8082
export { FormS3BucketSelector } from './form/S3BucketSelector';
8183
export type { FormTilesProps } from './form/Tiles/types';
8284
export { FormTiles } from './form/Tiles';
85+
export type { FormCardsProps } from './form/Cards/types';
86+
export { FormCards } from './form/Cards';
8387
export { Notifications } from './Notifications';
8488
export { ConfirmationDialog } from './ConfirmationDialog';
8589
export { FileUploader } from './FileUploader';

frontend/src/index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ const container = document.getElementById('root');
1919

2020
const theme: Theme = {
2121
tokens: {
22-
fontFamilyBase: 'metro-web, Metro, -apple-system, "system-ui", "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif',
22+
fontFamilyBase:
23+
'metro-web, Metro, -apple-system, "system-ui", "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif',
2324
fontSizeHeadingS: '15px',
2425
fontSizeHeadingL: '19px',
2526
fontSizeHeadingXl: '22px',

0 commit comments

Comments
 (0)