From a0da21474c67e3eeb349d7265a7e2848669ff9a6 Mon Sep 17 00:00:00 2001 From: iberdinsky-skilld Date: Tue, 10 Sep 2024 18:17:26 +0200 Subject: [PATCH] Multistep multiactions --- client/.eslintignore | 3 - client/openapi.d.ts | 7 +- .../src/pages/wizard/CustomFieldTemplate.tsx | 94 ------------- client/src/pages/wizard/FormSteps.tsx | 8 +- .../src/pages/wizard/ObjectFieldTemplate.tsx | 106 +++++++++++++++ client/src/pages/wizard/Show.tsx | 125 ++++++++++++------ client/src/pages/wizard/wizard-form.css | 29 ++-- .../platform/actions/configure-2/action.yaml | 19 --- .../platform/actions/configure-3/action.yaml | 13 -- .../actions/configure-3/ui-schema.yaml | 17 --- .../platform/actions/domainname/action.yaml | 9 ++ .../{configure-1 => platform}/action.yaml | 5 +- .../actions/platformdomains/action.yaml | 24 ++++ .../actions/platformdomains/ui-schema.yaml | 6 + multistep/platform/actions/ui-wizard.yaml | 40 ++++-- .../platform/actions/configure-1/action.yaml | 10 -- .../platform/actions/configure-2/action.yaml | 16 --- .../platform/actions/configure-3/action.yaml | 21 --- multistep2/platform/actions/ui-wizard.yaml | 24 ++-- server/api.go | 79 ++++++----- server/openapi.gen.go | 57 ++++---- server/openapi.yaml | 13 +- 22 files changed, 388 insertions(+), 337 deletions(-) delete mode 100644 client/src/pages/wizard/CustomFieldTemplate.tsx create mode 100644 client/src/pages/wizard/ObjectFieldTemplate.tsx delete mode 100644 multistep/platform/actions/configure-2/action.yaml delete mode 100644 multistep/platform/actions/configure-3/action.yaml delete mode 100644 multistep/platform/actions/configure-3/ui-schema.yaml create mode 100644 multistep/platform/actions/domainname/action.yaml rename multistep/platform/actions/{configure-1 => platform}/action.yaml (52%) create mode 100644 multistep/platform/actions/platformdomains/action.yaml create mode 100644 multistep/platform/actions/platformdomains/ui-schema.yaml delete mode 100644 multistep2/platform/actions/configure-1/action.yaml delete mode 100644 multistep2/platform/actions/configure-2/action.yaml delete mode 100644 multistep2/platform/actions/configure-3/action.yaml diff --git a/client/.eslintignore b/client/.eslintignore index 6e67e39..fc44696 100644 --- a/client/.eslintignore +++ b/client/.eslintignore @@ -6,6 +6,3 @@ node_modules/ **/**/coverage jest.config.ts openapi.d.ts - -# This is copied file from lib -src/pages/wizard/CustomFieldTemplate.tsx \ No newline at end of file diff --git a/client/openapi.d.ts b/client/openapi.d.ts index dfa9cf5..188fe70 100644 --- a/client/openapi.d.ts +++ b/client/openapi.d.ts @@ -231,7 +231,12 @@ export interface components { success: string; }; WizardFull: components["schemas"]["WizardShort"] & { - steps: components["schemas"]["ActionFull"][]; + steps: components["schemas"]["WizardStep"][]; + }; + WizardStep: { + title?: string; + description?: string; + actions?: components["schemas"]["ActionFull"][]; }; }; responses: { diff --git a/client/src/pages/wizard/CustomFieldTemplate.tsx b/client/src/pages/wizard/CustomFieldTemplate.tsx deleted file mode 100644 index b7229d6..0000000 --- a/client/src/pages/wizard/CustomFieldTemplate.tsx +++ /dev/null @@ -1,94 +0,0 @@ -import FormControl from '@mui/material/FormControl' -import Typography from '@mui/material/Typography' -import { - FieldTemplateProps, - FormContextType, - getTemplate, - getUiOptions, - RJSFSchema, - StrictRJSFSchema, -} from '@rjsf/utils' - -/** The `FieldTemplate` component is the template used by `SchemaField` to render any field. It renders the field - * content, (label, description, children, errors and help) inside of a `WrapIfAdditional` component. - * - * @param props - The `FieldTemplateProps` for this component - */ -export default function FieldTemplate< - T = any, - S extends StrictRJSFSchema = RJSFSchema, - F extends FormContextType = any, ->(props: FieldTemplateProps) { - const { - id, - children, - classNames, - style, - disabled, - displayLabel, - hidden, - label, - onDropPropertyClick, - onKeyChange, - readonly, - required, - rawErrors = [], - errors, - help, - description, - rawDescription, - schema, - uiSchema, - registry, - } = props - const uiOptions = getUiOptions(uiSchema) - const WrapIfAdditionalTemplate = getTemplate< - 'WrapIfAdditionalTemplate', - T, - S, - F - >('WrapIfAdditionalTemplate', registry, uiOptions) - - if (hidden) { - return
{children}
- } - const isField = !['root', 'root_arguments', 'root_options'].includes(id) - - return ( - - 0 ? true : false} - required={required} - className={`wizard-form__control wizard-form__control--${id}`} - > - {isField && ( - - {label} - - )} - {children} - {displayLabel && rawDescription ? ( - - {description} - - ) : null} - {errors} - {help} - - - ) -} diff --git a/client/src/pages/wizard/FormSteps.tsx b/client/src/pages/wizard/FormSteps.tsx index 1e2b79f..3817027 100644 --- a/client/src/pages/wizard/FormSteps.tsx +++ b/client/src/pages/wizard/FormSteps.tsx @@ -4,8 +4,8 @@ import Stepper from '@mui/material/Stepper' import type { FC } from 'react' interface Step { - id: string - title: string + title?: string + actions?: any } interface FormStepsProps { @@ -36,8 +36,8 @@ const FormSteps: FC = ({ return (
- {steps.map((step) => ( - + {steps.map((step, idx) => ( + {step.title} ))} diff --git a/client/src/pages/wizard/ObjectFieldTemplate.tsx b/client/src/pages/wizard/ObjectFieldTemplate.tsx new file mode 100644 index 0000000..b529c6b --- /dev/null +++ b/client/src/pages/wizard/ObjectFieldTemplate.tsx @@ -0,0 +1,106 @@ +// This is override of +// https://github.com/rjsf-team/react-jsonschema-form/blob/main/packages/mui/src/ObjectFieldTemplate/ObjectFieldTemplate.tsx + +import Grid from '@mui/material/Grid'; + +import { + FormContextType, + ObjectFieldTemplateProps, + RJSFSchema, + StrictRJSFSchema, + canExpand, + descriptionId, + getTemplate, + getUiOptions, + titleId, +} from '@rjsf/utils'; + +export default function CustomObjectFieldTemplate< + T = any, + S extends StrictRJSFSchema = RJSFSchema, + F extends FormContextType = any +>(props: ObjectFieldTemplateProps) { + const { + description, + title, + properties, + required, + disabled, + readonly, + uiSchema, + idSchema, + schema, + formData, + onAddClick, + registry, + } = props; + const uiOptions = getUiOptions(uiSchema); + const TitleFieldTemplate = getTemplate<'TitleFieldTemplate', T, S, F>('TitleFieldTemplate', registry, uiOptions); + const DescriptionFieldTemplate = getTemplate<'DescriptionFieldTemplate', T, S, F>( + 'DescriptionFieldTemplate', + registry, + uiOptions + ); + // Button templates are not overridden in the uiSchema + const { + ButtonTemplates: { AddButton }, + } = registry.templates; + + + + + if (uiOptions.CustomObjectTemplate === 'domains') { + // return (<>eee) + } + + return ( + <> + {title && ( + (idSchema)} + title={title} + required={required} + schema={schema} + uiSchema={uiSchema} + registry={registry} + /> + )} + {description && ( + (idSchema)} + description={description} + schema={schema} + uiSchema={uiSchema} + registry={registry} + /> + )} + + {properties.map((element, index) => + // Remove the if the inner element is hidden as the + // itself would otherwise still take up space. + element.hidden ? ( + element.content + ) : ( + + test + {element.content} + + ) + )} + {canExpand(schema, uiSchema, formData) && ( + + + + + + )} + + + ); +} \ No newline at end of file diff --git a/client/src/pages/wizard/Show.tsx b/client/src/pages/wizard/Show.tsx index d340b15..6d210b0 100644 --- a/client/src/pages/wizard/Show.tsx +++ b/client/src/pages/wizard/Show.tsx @@ -1,6 +1,6 @@ import './wizard-form.css' -import { Box, Button, LinearProgress, Typography } from '@mui/material' +import { Box, Button, LinearProgress, Stack, Typography } from '@mui/material' import { useApiUrl, useCustomMutation, @@ -12,7 +12,7 @@ import { } from '@refinedev/core' import { IChangeEvent, withTheme } from '@rjsf/core' import { Theme } from '@rjsf/mui' -import { DescriptionFieldProps, RJSFSchema, TitleFieldProps } from '@rjsf/utils' +import { DescriptionFieldProps, RJSFSchema, TitleFieldProps, ObjectFieldTemplateProps, getUiOptions, getTemplate, ObjectFieldTemplatePropertyType, StrictRJSFSchema, FormContextType, titleId } from '@rjsf/utils' import validator from '@rjsf/validator-ajv8' import { FC, useCallback, useContext, useEffect, useRef, useState } from 'react' @@ -21,15 +21,15 @@ import WizardBanner from '../../components/layout/WizardBanner' import { AppContext } from '../../context/AppContext' import { useThemeContext } from '../../ThemeProvider' import { IFormValues } from '../../types' -import CustomFieldTemplate from './CustomFieldTemplate' import FormSteps from './FormSteps' +import CustomObjectFieldTemplate from './ObjectFieldTemplate' const Form = withTheme(Theme) export const WizardShow: FC = () => { const { id: idFromRoute } = useResourceParams() const publish = usePublish() - const [steps, setSteps] = useState([]) + const [steps, setSteps] = useState([]) const stepsRef = useRef(steps) const [step, setStep] = useState(0) const { addAction } = useContext(AppContext) @@ -46,20 +46,22 @@ export const WizardShow: FC = () => { const title = data?.data?.title || '' const description = data?.data?.description || '' - const successText = data?.data?.success + const successText = data?.data?.success || '' useEffect(() => { if (data) { const newSteps = data.data?.steps?.map((step) => { - if (step?.jsonschema) { - delete step.jsonschema.$schema - } + step?.actions?.map((action) => { + if (action?.jsonschema) { + delete action.jsonschema.$schema + } + }) + return step }) if (newSteps) { setSteps(newSteps) - stepsRef.current = newSteps } } }, [data]) @@ -157,15 +159,13 @@ export const WizardShow: FC = () => { const TitleFieldTemplate = ({ id, title }: TitleFieldProps) => { if (id === 'root__title') { return ( - + {title} ) } return ( - - {title} - + {title} ) } @@ -199,45 +199,82 @@ export const WizardShow: FC = () => { }} > - {stepsRef.current.length <= step + 1 && ( + {steps.length < step + 1 && ( {successText} )} - {stepsRef.current[step]?.jsonschema && ( -
- {(stepsRef.current?.[step]?.id ?? '') === actionRunning && ( - - )} -
- -
- + {steps[step]?.actions?.length && ( + + + {steps[step]?.title} + + {steps[step]?.description} + + + + {steps[step]?.actions.map((action) => ( + +
+ + + +
+
+ ))} +
+
+ //
+ // {(stepsRef.current?.[step]?.id ?? '') === actionRunning && ( + // + // )} + //
+ // + //
+ // )} diff --git a/client/src/pages/wizard/wizard-form.css b/client/src/pages/wizard/wizard-form.css index c792ba9..4935f7c 100644 --- a/client/src/pages/wizard/wizard-form.css +++ b/client/src/pages/wizard/wizard-form.css @@ -1,17 +1,14 @@ -.wizard-form__control--root_arguments, -.wizard-form__control--root_options { - > .MuiGrid-container { - > .MuiGrid-item { - > .field { - > .wizard-form__control { - padding: 1.5rem; - background-color: #fff; - border-radius: 0.25rem; - border: 1px solid #E4E7EC; - display: grid; - gap: 1rem; - } - } - } +.wizard-form { + background-color: #fff; + border-radius: 0.5rem; + border: 1px solid #e4e7ec; + + > .form-group:first-child { + padding: 1.5rem; } -} \ No newline at end of file +} + +.MuiGrid-item:has(#root_arguments__title + div:empty), +.MuiGrid-item:has(#root_options__title + div:empty) { + display: none; +} diff --git a/multistep/platform/actions/configure-2/action.yaml b/multistep/platform/actions/configure-2/action.yaml deleted file mode 100644 index 6c12086..0000000 --- a/multistep/platform/actions/configure-2/action.yaml +++ /dev/null @@ -1,19 +0,0 @@ -action: - title: Configure environments - description: You can change this information later in your platform settings. - image: alpine:latest - command: ["sh", "-c", "for i in $(seq 10); do echo -e \"\\033[32m$$i\\033[0m\"; sleep 1; done"] - options: - - name: domainName - title: Define domain name - type: string - description: Enter a name to personalize your platform interface. Usually platformname.tech - - - name: mailServer - title: Define mail server - description: Enter a name to personalize your platform interface. - type: string - enum: [ Courier, Sendmail, Postfix ] - - - diff --git a/multistep/platform/actions/configure-3/action.yaml b/multistep/platform/actions/configure-3/action.yaml deleted file mode 100644 index fba3faf..0000000 --- a/multistep/platform/actions/configure-3/action.yaml +++ /dev/null @@ -1,13 +0,0 @@ -action: - title: Select app packages - description: Activate app packages needed in [Platform Name] playbooks - image: alpine:latest - command: ["sh", "-c", "for i in $(seq 10); do echo -e \"\\033[32m$$i\\033[0m\"; sleep 1; done"] - options: - - name: applications - title: Select Applications for Work - type: array - items: - type: sting - enum: ['foo', 'bar', 'fuzz', 'qux'] - default: ['foo', 'bar', 'fuzz', 'qux'] diff --git a/multistep/platform/actions/configure-3/ui-schema.yaml b/multistep/platform/actions/configure-3/ui-schema.yaml deleted file mode 100644 index e48a047..0000000 --- a/multistep/platform/actions/configure-3/ui-schema.yaml +++ /dev/null @@ -1,17 +0,0 @@ -uiSchema: - options: - applications: - 'ui:options': - orderable: false - enum: - - 'foo' - - 'bar' - - 'fuzz' - - 'qux' - # default: - # - 'ERP' - # - 'CRM' - # - 'Instant Messenger' - # - 'Mails' - # - 'Calls' - # - 'Shared docs' diff --git a/multistep/platform/actions/domainname/action.yaml b/multistep/platform/actions/domainname/action.yaml new file mode 100644 index 0000000..d88b8c9 --- /dev/null +++ b/multistep/platform/actions/domainname/action.yaml @@ -0,0 +1,9 @@ +action: + title: Define domain name + description: Enter a name to personalize your platform interface. Usually platformname.tech. + image: alpine:latest + command: ["sh", "-c", "for i in $(seq 10); do echo -e \"\\033[32m$$i\\033[0m\"; sleep 1; done"] + arguments: + - name: domainName + title: Define domain name + type: string diff --git a/multistep/platform/actions/configure-1/action.yaml b/multistep/platform/actions/platform/action.yaml similarity index 52% rename from multistep/platform/actions/configure-1/action.yaml rename to multistep/platform/actions/platform/action.yaml index 2d99ecf..5e0306f 100644 --- a/multistep/platform/actions/configure-1/action.yaml +++ b/multistep/platform/actions/platform/action.yaml @@ -1,10 +1,9 @@ action: - title: Name your platform - description: You can change this information later in your platform settings. + title: Define platform name + description: Naming your platform helps with appropriation within your organization. image: alpine:latest command: ["sh", "-c", "for i in $(seq 10); do echo -e \"\\033[32m$$i\\033[0m\"; sleep 1; done"] arguments: - name: platformName title: Define platform name type: string - description: Naming your platform helps with appropriation within your organization. diff --git a/multistep/platform/actions/platformdomains/action.yaml b/multistep/platform/actions/platformdomains/action.yaml new file mode 100644 index 0000000..2130952 --- /dev/null +++ b/multistep/platform/actions/platformdomains/action.yaml @@ -0,0 +1,24 @@ +action: + title: Setup platform domains + description: Enter a name to personalize your platform interface. + image: alpine:latest + command: ["sh", "-c", "for i in $(seq 10); do echo -e \"\\033[32m$$i\\033[0m\"; sleep 1; done"] + options: + - name: proddomain + title: Domain Name + type: string + - name: prodext + title: Domain Externsion + type: string + - name: devdomain + title: Domain Name + type: string + - name: devext + title: Domain Externsion + type: string + - name: sandboxdomain + title: Domain Name + type: string + - name: sandboxext + title: Domain Externsion + type: string diff --git a/multistep/platform/actions/platformdomains/ui-schema.yaml b/multistep/platform/actions/platformdomains/ui-schema.yaml new file mode 100644 index 0000000..75780a7 --- /dev/null +++ b/multistep/platform/actions/platformdomains/ui-schema.yaml @@ -0,0 +1,6 @@ +uiSchema: + 'ui:CustomObjectTemplate': "domains" + "ui:templateSettings": + - ["proddomain", "prodext"] + - ["devdomain", "devdext"] + - ["sandboxdomain", "sandboxext"] diff --git a/multistep/platform/actions/ui-wizard.yaml b/multistep/platform/actions/ui-wizard.yaml index cf78976..7a75c36 100644 --- a/multistep/platform/actions/ui-wizard.yaml +++ b/multistep/platform/actions/ui-wizard.yaml @@ -1,11 +1,33 @@ uiWizard: - title: "Platform Configuration" - description: "Please follow the steps below to configure your platform and prepare it for future control actions." - success: "Platform configuration finished" + title: Platform Configuration + description: Please follow the steps below to configure your platform and + prepare it for future control actions. + success: Platform configuration finished steps: - - multistep.platform:configure-1 - - multistep.platform:configure-2 - - multistep.platform:configure-3 - - multistep.platform:configure-4 - - multistep.platform:configure-5 - - multistep.platform:configure-6 + - title: Name your platform + description: You can change this information later in your platform settings. + actions: + - multistep.platform:platform + - title: Configure environments + description: You can change this information later in your platform settings. + actions: + - multistep.platform:domainname + - multistep.platform:platformdomains + - title: Select app packages + description: Activate app packages needed in [Platform Name] playbooks + actions: + - multistep.platform:platformdomains + - title: Labelize people + description: | + Labels help you build a comprehensive and intuitive ontology that mirrors your organization. They are categorized through collections: each collection represents a functional area, while each label represent the variations that can occur within such area. + For example, a typical ontology in a community-driven business would be: Roles as Label collection 1, Interests Groups as Label collection 2, Skills as Label collection 3 + actions: + - multistep.platform:platformdomains + - title: Define business entities + description: Lorem Ipsum has been the industry's standard dummy text. + actions: + - multistep.platform:platformdomains + - title: Customize branding + description: Lorem Ipsum has been the industry's standard dummy text. + actions: + - multistep.platform:platformdomains diff --git a/multistep2/platform/actions/configure-1/action.yaml b/multistep2/platform/actions/configure-1/action.yaml deleted file mode 100644 index 3cb9328..0000000 --- a/multistep2/platform/actions/configure-1/action.yaml +++ /dev/null @@ -1,10 +0,0 @@ -action: - title: Name your platform - description: You can change this information later in your platform settings. - image: alpine:latest - command: ["sh", "-c", "for i in $(seq 60); do echo -e \"\\033[32m$$i\\033[0m\"; sleep 1; done"] - arguments: - - name: platformName - title: Define platform name - type: string - description: Naming your platform helps with appropriation within your organization. diff --git a/multistep2/platform/actions/configure-2/action.yaml b/multistep2/platform/actions/configure-2/action.yaml deleted file mode 100644 index 220cc25..0000000 --- a/multistep2/platform/actions/configure-2/action.yaml +++ /dev/null @@ -1,16 +0,0 @@ -action: - title: Configure environments - description: You can change this information later in your platform settings. - image: alpine:latest - command: ["sh", "-c", "for i in $(seq 60); do echo -e \"\\033[32m$$i\\033[0m\"; sleep 1; done"] - options: - - name: domainName - title: Define domain name - type: string - description: Enter a name to personalize your platform interface. Usually platformname.tech - - name: platformDomains - title: Setup platform domains - type: string - description: Enter a name to personalize your platform interface. - - diff --git a/multistep2/platform/actions/configure-3/action.yaml b/multistep2/platform/actions/configure-3/action.yaml deleted file mode 100644 index a952843..0000000 --- a/multistep2/platform/actions/configure-3/action.yaml +++ /dev/null @@ -1,21 +0,0 @@ -action: - title: Third step - description: Third step description - image: alpine:latest - command: ["sh", "-c", "for i in $(seq 60); do echo -e \"\\033[32m$$i\\033[0m\"; sleep 1; done"] - arguments: - - name: simpleString - title: Simple inline string - type: string - default: With default value from schema - - name: stringConstrained - title: String with constraints - type: string - pattern: '^[A-Z \d\W]+$' - minLength: 2 - maxLength: 10 - description: Only UPPERCASE with 2 to 10 characters is allowed. - - name: textArea - title: Text area - description: Using UI schema options. - type: string diff --git a/multistep2/platform/actions/ui-wizard.yaml b/multistep2/platform/actions/ui-wizard.yaml index 7a88134..9dc7eba 100644 --- a/multistep2/platform/actions/ui-wizard.yaml +++ b/multistep2/platform/actions/ui-wizard.yaml @@ -1,10 +1,18 @@ uiWizard: - title: "Another Platform Configuration" - description: "Please follow the steps below to configure your platform and prepare it for future control actions." + title: Another Platform Configuration + description: Please follow the steps below to configure your platform and + prepare it for future control actions. + success: Platform configuration finished steps: - - multistep2.platform:configure-1 - - multistep2.platform:configure-2 - - multistep2.platform:configure-3 - success: "Platform configuration finished" - - + - title: Name your platform + description: You can change this information later in your platform settings. + actions: + - multistep.platform:platform + - title: Configure environments + description: You can change this information later in your platform settings. + actions: + - multistep.platform:domainname + - title: Select app packages + description: Activate app packages needed in [Platform Name] playbooks + actions: + - multistep.platform:platformdomains \ No newline at end of file diff --git a/server/api.go b/server/api.go index 528db75..c6a3ebf 100644 --- a/server/api.go +++ b/server/api.go @@ -207,19 +207,6 @@ func (l *launchrServer) GetRunningActionsByID(w http.ResponseWriter, _ *http.Req _ = json.NewEncoder(w).Encode(result) } -type uiWizard struct { - Title string `yaml:"title"` - Description string `yaml:"description"` - Success string `yaml:"success"` -} - -type uiWizardFull struct { - Title string `yaml:"title"` - Description string `yaml:"description"` - Steps []string `yaml:"steps"` - Success string `yaml:"success"` -} - func (l *launchrServer) GetWizards(w http.ResponseWriter, _ *http.Request) { var result []WizardShort @@ -242,7 +229,7 @@ func (l *launchrServer) GetWizards(w http.ResponseWriter, _ *http.Request) { } var data struct { - UIWizard uiWizard `yaml:"uiWizard"` + UIWizard WizardShort `yaml:"uiWizard"` } err = yaml.Unmarshal(content, &data) if err != nil { @@ -283,7 +270,6 @@ func (l *launchrServer) GetWizardByID(w http.ResponseWriter, _ *http.Request, id } targetPath := filepath.Join(runDir, strings.ReplaceAll(string(id), ".", string(filepath.Separator)), "ui-wizard.yaml") - fmt.Print() content, err := os.ReadFile(filepath.Clean(targetPath)) if err != nil { if os.IsNotExist(err) { @@ -294,32 +280,61 @@ func (l *launchrServer) GetWizardByID(w http.ResponseWriter, _ *http.Request, id return } + type wizardStep struct { + Actions []string `yaml:"actions"` + Description string `yaml:"description"` + Title string `yaml:"title"` + } + + type wizardShortWithSteps struct { + Description string `yaml:"description"` + Success string `yaml:"success"` + Title string `yaml:"title"` + Steps []wizardStep `yaml:"steps"` + } + var data struct { - UIWizard uiWizardFull `yaml:"uiWizard"` + UIWizard wizardShortWithSteps `yaml:"uiWizard"` } + if err := yaml.Unmarshal(content, &data); err != nil { sendError(w, http.StatusInternalServerError, err.Error()) return } - var steps []ActionFull - for _, stepID := range data.UIWizard.Steps { - a, ok := l.actionMngr.Get(string(stepID)) - if !ok { - sendError(w, http.StatusInternalServerError, fmt.Sprintf("Step action with ID %q not found", stepID)) - return - } - if err := a.EnsureLoaded(); err != nil { - sendError(w, http.StatusInternalServerError, fmt.Sprintf("Error loading step action %q", stepID)) - return - } + var steps []WizardStep - afull, err := apiActionFull(l.basePath(), a) - if err != nil { - sendError(w, http.StatusInternalServerError, fmt.Sprintf("Error building ActionFull for %q", stepID)) - return + for _, step := range data.UIWizard.Steps { + var actions []ActionFull + for _, actionID := range step.Actions { + a, ok := l.actionMngr.Get(actionID) + if !ok { + sendError(w, http.StatusInternalServerError, fmt.Sprintf("Step action with ID %q not found", actionID)) + return + } + + if err := a.EnsureLoaded(); err != nil { + sendError(w, http.StatusInternalServerError, fmt.Sprintf("Error loading step action %q", actionID)) + return + } + + afull, err := apiActionFull(l.basePath(), a) + if err != nil { + sendError(w, http.StatusInternalServerError, fmt.Sprintf("Error building ActionFull for %q", actionID)) + return + } + actions = append(actions, afull) } - steps = append(steps, afull) + + stepActions := actions + stepTitle := step.Title + stepDescription := step.Description + + steps = append(steps, WizardStep{ + Title: &stepTitle, + Description: &stepDescription, + Actions: &stepActions, + }) } wizard := WizardFull{ diff --git a/server/openapi.gen.go b/server/openapi.gen.go index af44582..64fe06b 100644 --- a/server/openapi.gen.go +++ b/server/openapi.gen.go @@ -93,7 +93,7 @@ type JSONSchema = map[string]interface{} type WizardFull struct { Description string `json:"description"` ID string `json:"id"` - Steps []ActionFull `json:"steps"` + Steps []WizardStep `json:"steps"` Success string `json:"success"` Title string `json:"title"` } @@ -106,6 +106,13 @@ type WizardShort struct { Title string `json:"title"` } +// WizardStep defines model for WizardStep. +type WizardStep struct { + Actions *[]ActionFull `json:"actions,omitempty"` + Description *string `json:"description,omitempty"` + Title *string `json:"title,omitempty"` +} + // ActionId defines model for ActionId. type ActionId = string @@ -657,30 +664,30 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "H4sIAAAAAAAC/8xZSXPjNhP9Kyx835EWZc9NN83YSSk1NZ6yksrB8QEmWxJmiGWwxFZU/O8pLNxEUqJi", - "yclJEgGiX79uPHRDO5RyKjgDphWa7ZDAElPQIN2veaoJZ4vMfs9ApZII+wDN0OI24qsIu/FI82gFOt2g", - "GBE7KLC23xmmgGaIZChGEn4YIiFDMy0NxEilG6DYrqu3ws5SWhK2RkURB6sPhi3Yig8b1xuIpGGMsHUA", - "0m9fGuvBaRA+E0p01zAz9BmkNQ45UMuZ9V2CNrIy/sOA3NbWc7dS0xrFr4QaimbX02mMKGHhV1ziIEzD", - "GqQDcr9aKRiNRH0nYgAH9wv1uN009zv5C8tsmPMXN37egBd2shKcKXBJdwsrbHJ9JyWX9nfKmQbmOMBC", - "5CTFFlLyTVlcu8bC/5ewQjP0v6RO6cSPqsSv5oy1/TIMXgWkGrIIwpwSbGML/GTy3AHI8/sVmj0eNubf", - "WW641KiId0hILkBq4v2zwDts8OdvkNrwvF6t+VUg8pfl/ZelnxkGwux6iUl3/IpQYS273aw3aIbWRG/M", - "8yTlNMmxYelGpjovvybi+zppYLL+GzIO4G+LXngUi0cf3iebXHKFU9gVLYw2U6+4CwLOrwR383yu+IQo", - "s+exyddTvAeneNrXi3aU2syTrJt/bYcWt8iGX2Nt1LGUqswu/fR93G4bhKWOAP9qVVcdgo7l2tBSpHtD", - "Eh56JZz8uhUwl2v11sQIwmp989E6BcC90OcDsMduTUiN7AjLyyqswKziPqJUAtbg5MofJChGK8KI2riH", - "XhDqVUvJaq0pAdNbrPGh6DUkrLNUyk1rpJLjuNTs3jH/pHZF6ezeOH3X2YL5zzvZh36PSDcaVxDj+qTw", - "yA6R6iXugOMtre1xfuyO1ETn0H9Ud7acn9vW+X4nPhmlOSUK7+Hr1brW5E+crcj6vLIXo+rI28+ezPm+", - "4pJi7dPgww2Ke7KCglJ4PYIpt2Y9v8tP3Dx9OtRUpcJpB6N/Z+hgVBqE12kNdKT8OvvVdkBYSrxFB06Q", - "OFjpT4gmvnfIamXSFJTqXeOtGV+v3ueqXYaE07JdD81ZNP+6sLXeZ6/Coba2OpuTFJhyqIIfc4HTDUQ3", - "kymKkZE5mqGN1kLNkuTl5WWC3fCEy3US3lXJ58Wnuy/Lu6ubyXSy0TRvOIuCSRSjP0EqD+h6Mp1MnRoK", - "YFgQNEMfJtfOoD1EHHtJiXG2Q+u+cvnBlegqwnke5W2//mDuBAGJy14H/Qx6Xjndqk1vptOTStITMrnc", - "Ffup3KlYA+6oBIbcDFczD1mqfEhaxbUrdQ2lWG4t+URpz1DJph0vqU12JCsG+ZUlv74hfN5GLjEHaP24", - "Xdy68NW95oBw1FOSqhctnt4YlLGqMkT92Zl/6GOviJHgqodreIXUaFB109um+cGweTnyJop/GFD6I8+2", - "Z2a3Lnh7KPZToqq8izDLorLA228ri04mXJ8fq+sq3i8ZpKkyobsBk7JOPbYR2xcjqm8vPvgpQen+5T15", - "glBWIRkrlZaMiIRXzrlf90keDFeyc5dQo/WzAtwTtnsGrci9MXDxyLn1ddw76O+IXXehkHaWPxbSRLkO", - "UJ24I6PytWMbc1nNe8cIH38l3EuOmOmvUt9ZIBpt+ekyUcXmonJRW+mkWLjaK0kYoxh2blT1OAN1V+s+", - "8b9YfTUADoep6epldn/Lgo1Oun9REELS4bn/kuDyid++yRiR8qnDdvbipYUj8kY8hf6fg1ENGjW5JrZN", - "P9yi+Wb9fVq09sXFUXa9s5ds0YKFJrfjOrTwD85gh+Y9/UdFRfXn0UU1onHvNMj8xTq0FntFURR/BwAA", - "//+Q/oedQB0AAA==", + "H4sIAAAAAAAC/8xZS3PixhP/Kqr5/48ywt4bN3btpEhtrbdMUjk4PoylBmZX89h5xCaUvntqHnohCUQM", + "Tk6ApjX9618/pnvYoZRTwRkwrdBshwSWmIIG6X7NU004W2T2ewYqlUTYB2iGFrcRX0XYrUeaRyvQ6QbF", + "iNhFgbX9zjAFNEMkQzGS8MMQCRmaaWkgRirdAMV2X70VVkppSdgaFUUctD4YtmArPqxcbyCShjHC1gFI", + "v35prAWnQfhMKNFdxczQZ5BWOeRALWfWdgnayEr5DwNyW2vP3U5NbRS/Emooml1PpzGihIVfcYmDMA1r", + "kA7I/WqlYDQS9Z2IARzcb9RjdlPd7+QvLLNhzl/c+nkdXlhhJThT4ILuFlbY5PpOSi7t75QzDcxxgIXI", + "SYotpOSbsrh2jY3/L2GFZuh/SR3SiV9Vid/NKWvbZRi8Ckg1ZBEEmRJsIwV+MnnuAOT5/QrNHg8r8+8s", + "N1xqVMQ7JCQXIDXx9lngHTb48zdIrXter9b8KhD5y/L+y9JLhoUgXW8x6a5fESqsZpfNeoNmaE30xjxP", + "Uk6THBuWbmSq8/JrIr6vkwYma78h4wD+tuiFR7F49O59ssElVziFXdHCaCP1ijsn4PxKcCfnY8UHRBk9", + "j02+nuI9OMXTfr1oe6nNPMm68dc2aHGLrPs11kYdC6lK7dKL7+N2aRC2OgL8q6266hB0LNeGlkW61yXh", + "oa+Ek1+3AuZyrd4aGKGwWtu8t04BcC/0+QDssVsTUiM7wvKyciswW3EfUSoBa3Dlyh8kKEYrwojauIe+", + "INS7liWrtacETG+xxoe81yhhna1SblorVTmOy5rdu+af1KYond0bV991tmD+8072od8j0q3GFcS4Pik8", + "skOk+hJ3wPBWre0xfmxGaqJz6D+qOynnZdt1vt+IT0ZpTonCe/h6a11L+BNnK7I+b9mLUXXk7UdP5mxf", + "cUmx9mHw4QbFPVFBQSm8HsGU27OW7/ITN0+fDjVVq3DawejfGToYlQbh67QGerT8hr00iDodEJYSb9GB", + "EyQOWvoDoonvHaJamTQFpXr3eGvE17sfNNXS1wk4X3PHu6LRI3VcER9la9BSV/NJONPbXducRfOvC9uR", + "fvZnRVRijlFOUmDK7RjYngucbiC6mUxRjIzM0QxttBZqliQvLy8T7JYnXK6T8K5KPi8+3X1Z3l3dTKaT", + "jaZ5AygKKlGM/gSpPKDryXQydTVbAMOCoBn6MLl2Cu1R5yhMGryu+5r6BzdIqAjneZS37fqDuXMOJC4n", + "MvQz6HlldKuDvplOT2qcT3Bymbv7CdfpqwPuqATmI8F19kOaKhuS1gjgGnJDKZZbSz5R2jNUsmnXS2qT", + "HcmKQX5lya8fW5+3kUufAVo/bhe3zn31RDxQ3mqRpJqYi6c3OmVswg1Rf3bmH/rYK2IkuOrhGl4hNRpU", + "PZq3aX4wbF6uvIniHwaU/siz7ZnZrdvyHoq9SFQ1oRFmWVS2ofvDb9GJhOvzY3Wzz/sFgzRVJHQTMCm7", + "6WOJ2L6+UX25+OBFQqX7l3PyhEJZuWRsqbRkRCS8cs583Sd50F3Jzl2Vja6fFeAet90zaHnujY6LR8rW", + "l4bvUH9HZN2FXNrZ/phLE+XmVHViRkbla8cSc1nJvaOHj78Sbk9HSPoL33cuEI3Lg9PLROWbi5aLWksn", + "xMIFZEnCmIphZaNqEhvou1q3nv/F7qsBcNhNTVMvk/0tDdY76f51RnBJh+f+q4zLB377vmVEyKcO29mb", + "lxaOyCvxFPr/N0YNaNTkmigN4vCI5ufs9xnR2tcrR9n1xl5yRAsamtyOm9DC/0yDE5q39B81FdVfXBet", + "EY3bsUHmLzahtdgriqL4OwAA//9nEuR85h0AAA==", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/server/openapi.yaml b/server/openapi.yaml index 0acc78d..cd61ca7 100644 --- a/server/openapi.yaml +++ b/server/openapi.yaml @@ -364,5 +364,14 @@ components: steps: type: array items: - $ref: '#/components/schemas/ActionFull' - + $ref: '#/components/schemas/WizardStep' + WizardStep: + properties: + title: + type: string + description: + type: string + actions: + type: array + items: + $ref: '#/components/schemas/ActionFull' \ No newline at end of file