Refactor: improve code modularity
This commit is contained in:
@@ -0,0 +1,234 @@
|
||||
// Path: Frontend/src/components/bootstrap/BootstrapWizard/BootstrapWizardDialog.tsx
|
||||
|
||||
import { Show, type JSX } from "solid-js";
|
||||
import { Portal } from "solid-js/web";
|
||||
import {
|
||||
type AdminForm,
|
||||
type BootstrapPersona,
|
||||
bootstrapPersonaDefinitions,
|
||||
type BootstrapStepDefinition,
|
||||
type BootstrapStepKey,
|
||||
type InstanceForm,
|
||||
type ModeForm,
|
||||
type StructureForm,
|
||||
} from "./BootstrapWizard.data";
|
||||
import { type BootstrapSubmissionState, type FieldTooltipState, type MaterializationState } from "./BootstrapWizard.hook";
|
||||
import {
|
||||
BootstrapAdminStep,
|
||||
BootstrapFinishingState,
|
||||
BootstrapInstanceStep,
|
||||
BootstrapModeStep,
|
||||
BootstrapPersonaStep,
|
||||
BootstrapStructureStep,
|
||||
BootstrapWizardProgress,
|
||||
} from "./BootstrapWizard.parts";
|
||||
import styles from "./BootstrapWizard.module.scss";
|
||||
|
||||
export type BootstrapWizardDialogProps = {
|
||||
isOpen: boolean;
|
||||
currentStep: BootstrapStepDefinition;
|
||||
currentStepState: BootstrapSubmissionState;
|
||||
activeWizardSteps: readonly BootstrapStepDefinition[];
|
||||
currentWizardStepIndex: number;
|
||||
stepState: Record<BootstrapStepKey, BootstrapSubmissionState>;
|
||||
bootstrapStepCount: number;
|
||||
wizardProgressFillWidth: string;
|
||||
showBootstrapFinishingState: boolean;
|
||||
materializationState: MaterializationState;
|
||||
materializationStatusLabel: string;
|
||||
materializationMessage: string;
|
||||
isMaterializationInFlight: boolean;
|
||||
hasMaterializationFailed: boolean;
|
||||
instanceForm: InstanceForm;
|
||||
modeForm: ModeForm;
|
||||
adminForm: AdminForm;
|
||||
structureForm: StructureForm;
|
||||
selectedPersona: BootstrapPersona;
|
||||
hasChosenPersona: boolean;
|
||||
selectedPersonaIsAvailable: boolean;
|
||||
usesCondensedBootstrapFlow: boolean;
|
||||
bootstrapNamePlaceholder: string;
|
||||
isFirstStep: boolean;
|
||||
canDismissWizard: boolean;
|
||||
fieldTooltip: FieldTooltipState | null;
|
||||
onClose: () => void;
|
||||
onCloseFinishingState: () => void;
|
||||
onSubmit: JSX.EventHandlerUnion<HTMLFormElement, SubmitEvent>;
|
||||
onSelectPersona: (persona: BootstrapPersona) => void;
|
||||
onProtocolChange: (value: InstanceForm["protocol"]) => void;
|
||||
onAccessChange: (value: InstanceForm["access"]) => void;
|
||||
onHostChange: (value: string) => void;
|
||||
onModeNameChange: (value: string) => void;
|
||||
onProjectNameChange: (value: string) => void;
|
||||
onTeamNameChange: (value: string) => void;
|
||||
onAdminDisplayNameChange: (value: string) => void;
|
||||
onAdminEmailChange: (value: string) => void;
|
||||
onAdminPasswordChange: (value: string) => void;
|
||||
onDepartmentNameChange: (value: string) => void;
|
||||
onShowTooltip: (target: HTMLElement, text: string) => void;
|
||||
onHideTooltip: () => void;
|
||||
statusLabel: (state: BootstrapSubmissionState) => string;
|
||||
stepStatusLabel: (step: BootstrapStepDefinition) => string;
|
||||
onNavigateBack: () => void;
|
||||
onSelectStep: (index: number) => void;
|
||||
};
|
||||
|
||||
export const BootstrapWizardDialog = (props: BootstrapWizardDialogProps): JSX.Element => (
|
||||
<Show when={props.isOpen}>
|
||||
<Portal>
|
||||
<div class={styles.wizardLayer} data-ui="bootstrap-wizard" data-step={props.currentStep.id}>
|
||||
<div class={styles.wizardBackdrop} aria-hidden="true" />
|
||||
|
||||
<section class={styles.wizardPanel} role="dialog" aria-modal="true" aria-labelledby="bootstrap-wizard-title" data-slot="bootstrap-wizard-panel">
|
||||
<header class={styles.wizardHeader} data-slot="bootstrap-wizard-header">
|
||||
<div class={styles.wizardHeaderCopy}>
|
||||
<h2 id="bootstrap-wizard-title" class={styles.wizardTitle}>
|
||||
Bootstrap Server
|
||||
</h2>
|
||||
</div>
|
||||
<Show when={props.canDismissWizard}>
|
||||
<button type="button" class={styles.wizardCloseButton} onClick={props.onClose}>
|
||||
Close
|
||||
</button>
|
||||
</Show>
|
||||
</header>
|
||||
|
||||
<Show
|
||||
when={!props.showBootstrapFinishingState}
|
||||
fallback={
|
||||
<BootstrapFinishingState
|
||||
materializationState={props.materializationState}
|
||||
statusLabel={props.materializationStatusLabel}
|
||||
message={props.materializationMessage}
|
||||
isInFlight={props.isMaterializationInFlight}
|
||||
hasFailed={props.hasMaterializationFailed}
|
||||
onClose={props.onCloseFinishingState}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<div class={styles.wizardBody}>
|
||||
<Show when={props.currentStep.id !== "persona"}>
|
||||
<BootstrapWizardProgress
|
||||
steps={props.activeWizardSteps}
|
||||
currentStepId={props.currentStep.id}
|
||||
currentWizardStepIndex={props.currentWizardStepIndex}
|
||||
stepState={props.stepState}
|
||||
bootstrapStepCount={props.bootstrapStepCount}
|
||||
wizardProgressFillWidth={props.wizardProgressFillWidth}
|
||||
stepStatusLabel={props.stepStatusLabel}
|
||||
onSelectStep={props.onSelectStep}
|
||||
/>
|
||||
</Show>
|
||||
|
||||
<div class={styles.wizardStepPanel} data-slot="bootstrap-wizard-step-panel">
|
||||
<Show when={props.currentStep.id !== "persona" || props.statusLabel(props.currentStepState)}>
|
||||
<div class={styles.sectionHeader}>
|
||||
<Show when={props.currentStep.id !== "persona"}>
|
||||
<div>
|
||||
<span class={styles.wizardStepEyebrow}>{`Step ${props.currentWizardStepIndex + 1} of ${props.bootstrapStepCount}`}</span>
|
||||
</div>
|
||||
</Show>
|
||||
<Show when={props.statusLabel(props.currentStepState)}>
|
||||
<div class={styles.statusBadge} data-status={props.currentStepState.status}>
|
||||
{props.statusLabel(props.currentStepState)}
|
||||
</div>
|
||||
</Show>
|
||||
</div>
|
||||
</Show>
|
||||
|
||||
<form class={styles.form} onSubmit={props.onSubmit}>
|
||||
<Show when={props.currentStep.id === "persona"}>
|
||||
<BootstrapPersonaStep
|
||||
personas={bootstrapPersonaDefinitions}
|
||||
hasChosenPersona={props.hasChosenPersona}
|
||||
selectedPersona={props.selectedPersona}
|
||||
selectedPersonaIsAvailable={props.selectedPersonaIsAvailable}
|
||||
onSelectPersona={props.onSelectPersona}
|
||||
/>
|
||||
</Show>
|
||||
|
||||
<Show when={props.currentStep.id === "instance"}>
|
||||
<BootstrapInstanceStep
|
||||
instanceForm={props.instanceForm}
|
||||
onProtocolChange={props.onProtocolChange}
|
||||
onAccessChange={props.onAccessChange}
|
||||
onHostChange={props.onHostChange}
|
||||
onShowTooltip={props.onShowTooltip}
|
||||
onHideTooltip={props.onHideTooltip}
|
||||
/>
|
||||
</Show>
|
||||
|
||||
<Show when={props.currentStep.id === "mode"}>
|
||||
<BootstrapModeStep
|
||||
modeForm={props.modeForm}
|
||||
structureForm={props.structureForm}
|
||||
usesCondensedBootstrapFlow={props.usesCondensedBootstrapFlow}
|
||||
selectedPersona={props.selectedPersona}
|
||||
namePlaceholder={props.bootstrapNamePlaceholder}
|
||||
onNameChange={props.onModeNameChange}
|
||||
onProjectNameChange={props.onProjectNameChange}
|
||||
onTeamNameChange={props.onTeamNameChange}
|
||||
onShowTooltip={props.onShowTooltip}
|
||||
onHideTooltip={props.onHideTooltip}
|
||||
/>
|
||||
</Show>
|
||||
|
||||
<Show when={props.currentStep.id === "admin"}>
|
||||
<BootstrapAdminStep
|
||||
adminForm={props.adminForm}
|
||||
onDisplayNameChange={props.onAdminDisplayNameChange}
|
||||
onEmailChange={props.onAdminEmailChange}
|
||||
onPasswordChange={props.onAdminPasswordChange}
|
||||
/>
|
||||
</Show>
|
||||
|
||||
<Show when={props.currentStep.id === "structure"}>
|
||||
<BootstrapStructureStep
|
||||
mode={props.modeForm.mode}
|
||||
structureForm={props.structureForm}
|
||||
onDepartmentNameChange={props.onDepartmentNameChange}
|
||||
onTeamNameChange={props.onTeamNameChange}
|
||||
onProjectNameChange={props.onProjectNameChange}
|
||||
onShowTooltip={props.onShowTooltip}
|
||||
onHideTooltip={props.onHideTooltip}
|
||||
/>
|
||||
</Show>
|
||||
|
||||
<Show when={props.currentStep.id !== "persona"}>
|
||||
<div class={styles.wizardFormActions}>
|
||||
<button type="button" class={styles.secondaryButton} disabled={props.isFirstStep} onClick={props.onNavigateBack}>
|
||||
Back
|
||||
</button>
|
||||
<button type="submit" class={styles.primaryButton} disabled={props.currentStepState.status === "submitting"}>
|
||||
{props.currentStep.buttonLabel}
|
||||
</button>
|
||||
</div>
|
||||
</Show>
|
||||
</form>
|
||||
|
||||
<Show when={props.currentStepState.error}>
|
||||
<p class={styles.errorText}>{props.currentStepState.error}</p>
|
||||
</Show>
|
||||
</div>
|
||||
</div>
|
||||
</Show>
|
||||
</section>
|
||||
|
||||
<Show when={props.fieldTooltip}>
|
||||
{(tooltip): JSX.Element => (
|
||||
<div
|
||||
class={styles.fieldTooltip}
|
||||
data-placement={tooltip().placement}
|
||||
style={{
|
||||
left: `${tooltip().left}px`,
|
||||
top: `${tooltip().top}px`,
|
||||
}}
|
||||
>
|
||||
<div class={styles.fieldTooltipBubble}>{tooltip().text}</div>
|
||||
</div>
|
||||
)}
|
||||
</Show>
|
||||
</div>
|
||||
</Portal>
|
||||
</Show>
|
||||
);
|
||||
Reference in New Issue
Block a user