From d435a0b0fa7af874047e5ea2a6412053dc196ac9 Mon Sep 17 00:00:00 2001 From: Oleg Vavilov Date: Thu, 15 Jan 2026 00:43:14 +0300 Subject: [PATCH 01/12] [UI] Default fleet in project wizard #373 --- frontend/src/api.ts | 1 + .../ButtonWithConfirmation/index.tsx | 20 +- .../components/ConfirmationDialog/index.tsx | 5 +- .../components/ConfirmationDialog/slice.ts | 34 ++ frontend/src/components/form/Toogle/index.tsx | 57 ++++ frontend/src/components/form/Toogle/types.ts | 11 + frontend/src/components/index.ts | 1 + frontend/src/hooks/index.ts | 1 + frontend/src/hooks/useConfirmationDialog.ts | 27 ++ frontend/src/hooks/useNotifications.ts | 1 + frontend/src/layouts/AppLayout/index.tsx | 7 + frontend/src/locale/en.json | 10 +- .../pages/Project/CreateWizard/constants.ts | 13 - .../pages/Project/CreateWizard/constants.tsx | 42 +++ .../src/pages/Project/CreateWizard/index.tsx | 299 +++++++++++------- .../src/pages/Project/CreateWizard/types.ts | 7 +- frontend/src/pages/User/Details/index.tsx | 8 +- frontend/src/pages/User/List/index.tsx | 2 + frontend/src/services/fleet.ts | 20 +- frontend/src/store.ts | 2 + frontend/src/types/fleet.d.ts | 16 +- 21 files changed, 448 insertions(+), 136 deletions(-) create mode 100644 frontend/src/components/ConfirmationDialog/slice.ts create mode 100644 frontend/src/components/form/Toogle/index.tsx create mode 100644 frontend/src/components/form/Toogle/types.ts create mode 100644 frontend/src/hooks/useConfirmationDialog.ts delete mode 100644 frontend/src/pages/Project/CreateWizard/constants.ts create mode 100644 frontend/src/pages/Project/CreateWizard/constants.tsx diff --git a/frontend/src/api.ts b/frontend/src/api.ts index d58dbc7d38..144a21bc86 100644 --- a/frontend/src/api.ts +++ b/frontend/src/api.ts @@ -99,6 +99,7 @@ export const API = { // Fleets FLEETS: (projectName: IProject['project_name']) => `${API.BASE()}/project/${projectName}/fleets/list`, FLEETS_DETAILS: (projectName: IProject['project_name']) => `${API.BASE()}/project/${projectName}/fleets/get`, + FLEETS_APPLY: (projectName: IProject['project_name']) => `${API.BASE()}/project/${projectName}/fleets/apply`, FLEETS_DELETE: (projectName: IProject['project_name']) => `${API.BASE()}/project/${projectName}/fleets/delete`, FLEET_INSTANCES_DELETE: (projectName: IProject['project_name']) => `${API.BASE()}/project/${projectName}/fleets/delete_instances`, diff --git a/frontend/src/components/ButtonWithConfirmation/index.tsx b/frontend/src/components/ButtonWithConfirmation/index.tsx index 78c2793d9c..56ae78ad59 100644 --- a/frontend/src/components/ButtonWithConfirmation/index.tsx +++ b/frontend/src/components/ButtonWithConfirmation/index.tsx @@ -1,4 +1,5 @@ import React, { useState } from 'react'; +import { useTranslation } from 'react-i18next'; import Box from '@cloudscape-design/components/box'; import { Button } from '../Button'; @@ -13,20 +14,31 @@ export const ButtonWithConfirmation: React.FC = ({ confirmButtonLabel, ...props }) => { + const { t } = useTranslation(); const [showDeleteConfirm, setShowConfirmDelete] = useState(false); const toggleDeleteConfirm = () => { setShowConfirmDelete((val) => !val); }; - const content = typeof confirmContent === 'string' ? {confirmContent} : confirmContent; - const onConfirm = () => { if (onClick) onClick(); setShowConfirmDelete(false); }; + const getContent = () => { + if (!confirmContent) { + return {t('confirm_dialog.message')}; + } + + if (typeof confirmContent === 'string') { + return {confirmContent}; + } + + return confirmContent; + }; + return ( <> } + {isAvailableProjectManaging && } ); }; @@ -137,7 +137,7 @@ export const ProjectList: React.FC = () => { {t('common.delete')} - + } + {isAvailableProjectManaging && } ); }; @@ -137,7 +137,7 @@ export const ProjectList: React.FC = () => { {t('common.delete')} - + + + - - } From ab674d7b6dba14fd1e30ad57e6aa70e2590f51e1 Mon Sep 17 00:00:00 2001 From: Oleg Vavilov Date: Tue, 20 Jan 2026 23:34:48 +0300 Subject: [PATCH 10/12] Fixes after review --- frontend/src/pages/Fleets/Add/index.tsx | 26 +++---------------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/frontend/src/pages/Fleets/Add/index.tsx b/frontend/src/pages/Fleets/Add/index.tsx index b2b0a1dd11..fb5b92446b 100644 --- a/frontend/src/pages/Fleets/Add/index.tsx +++ b/frontend/src/pages/Fleets/Add/index.tsx @@ -6,7 +6,7 @@ import { isNil } from 'lodash'; import * as yup from 'yup'; import { WizardProps } from '@cloudscape-design/components'; -import { Container, FormInput, InfoLink, KeyValuePairs, SpaceBetween, Wizard } from 'components'; +import { Container, InfoLink, KeyValuePairs, SpaceBetween, Wizard } from 'components'; import { useBreadcrumbs, useConfirmationDialog, useHelpPanel, useNotifications } from 'hooks'; import { ROUTES } from 'routes'; @@ -23,7 +23,7 @@ import { IFleetWizardForm } from './types'; const requiredFieldError = 'This is required field'; const namesFieldError = 'Only latin characters, dashes, underscores, and digits'; -const fleetStepIndex = 1; +const fleetStepIndex = 0; const fleetValidationSchema = yup.object({ project_name: yup @@ -101,10 +101,6 @@ export const FleetAdd: React.FC = () => { }, ]); - const validateName = async () => { - return await trigger(['project_name']); - }; - const validateFleet = async () => { return await trigger(['min_instances', 'max_instances', 'idle_duration']); }; @@ -118,7 +114,7 @@ export const FleetAdd: React.FC = () => { requestedStepIndex: number; reason: WizardProps.NavigationReason; }) => { - const stepValidators = [validateName, validateFleet, emptyValidator]; + const stepValidators = [validateFleet, emptyValidator]; if (reason === 'next') { stepValidators[activeStepIndex]?.().then((isValid) => { @@ -219,22 +215,6 @@ export const FleetAdd: React.FC = () => { onCancel={onCancelHandler} submitButtonText={t('projects.wizard.submit')} steps={[ - { - title: 'Project', - content: ( - - - - - - ), - }, { title: 'Settings', info: openHelpPanel(DEFAULT_FLEET_INFO)} />, From a39ce2ea9a37fc6befea009a5b4324ec3b641070 Mon Sep 17 00:00:00 2001 From: peterschmidt85 Date: Tue, 20 Jan 2026 21:43:26 +0100 Subject: [PATCH 11/12] Cosmetics --- frontend/src/pages/Fleets/Add/index.tsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/frontend/src/pages/Fleets/Add/index.tsx b/frontend/src/pages/Fleets/Add/index.tsx index fb5b92446b..075f6ce1dc 100644 --- a/frontend/src/pages/Fleets/Add/index.tsx +++ b/frontend/src/pages/Fleets/Add/index.tsx @@ -4,7 +4,7 @@ import { useTranslation } from 'react-i18next'; import { useNavigate, useParams } from 'react-router-dom'; import { isNil } from 'lodash'; import * as yup from 'yup'; -import { WizardProps } from '@cloudscape-design/components'; +import { Box, WizardProps } from '@cloudscape-design/components'; import { Container, InfoLink, KeyValuePairs, SpaceBetween, Wizard } from 'components'; @@ -217,7 +217,13 @@ export const FleetAdd: React.FC = () => { steps={[ { title: 'Settings', - info: openHelpPanel(DEFAULT_FLEET_INFO)} />, + description: ( + + At least one fleet is required to run dev environments, tasks, or services. Create it here, or + create it using the dstack apply command via the CLI.{' '} + openHelpPanel(DEFAULT_FLEET_INFO)} /> + + ), content: ( From 62db74ef0fba35b0f4996855adcf7c2df47c314c Mon Sep 17 00:00:00 2001 From: Oleg Vavilov Date: Tue, 20 Jan 2026 23:45:25 +0300 Subject: [PATCH 12/12] Fixes after review --- frontend/src/pages/Fleets/Add/index.tsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/frontend/src/pages/Fleets/Add/index.tsx b/frontend/src/pages/Fleets/Add/index.tsx index 075f6ce1dc..b661d96cb0 100644 --- a/frontend/src/pages/Fleets/Add/index.tsx +++ b/frontend/src/pages/Fleets/Add/index.tsx @@ -239,11 +239,7 @@ export const FleetAdd: React.FC = () => {