mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-10-03 17:54:05 +00:00
139 lines
4.7 KiB
TypeScript
139 lines
4.7 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect, useRef, useState } from "react";
|
|
|
|
import {
|
|
ConnectAccountForm,
|
|
ConnectAccountSuccessData,
|
|
} from "@/components/providers/workflow/forms";
|
|
import { endActiveTour } from "@/lib/tours/use-driver-tour";
|
|
import { useProviderWizardStore } from "@/store/provider-wizard/store";
|
|
import { useUIStore } from "@/store/ui/store";
|
|
import { ORGANIZATION_TYPE, OrgFlowType } from "@/types/organizations";
|
|
import { PROVIDER_WIZARD_MODE } from "@/types/provider-wizard";
|
|
import { ProviderType } from "@/types/providers";
|
|
|
|
import { AwsConnectStep } from "./aws/aws-connect-step";
|
|
import { AWS_CONNECT_ACTION_KIND, type AwsConnectUiState } from "./aws/types";
|
|
import {
|
|
WIZARD_FOOTER_ACTION_TYPE,
|
|
WizardFooterConfig,
|
|
} from "./footer-controls";
|
|
|
|
interface ConnectStepProps {
|
|
onNext: () => void;
|
|
/** AWS registers, stores and tests the account in this step, so it skips ahead. */
|
|
onCredentialsSaved: () => void;
|
|
/** AWS offers it as the footer action once a teammate has been invited instead. */
|
|
onClose: () => void;
|
|
onSelectOrganizations: (orgType: OrgFlowType) => void;
|
|
onFooterChange: (config: WizardFooterConfig) => void;
|
|
onProviderTypeChange: (providerType: ProviderType | null) => void;
|
|
/** Provider the user was already working with, e.g. when returning from the AWS organization flow. */
|
|
initialProviderType?: ProviderType | null;
|
|
}
|
|
|
|
export function ConnectStep({
|
|
onNext,
|
|
onCredentialsSaved,
|
|
onClose,
|
|
onSelectOrganizations,
|
|
onFooterChange,
|
|
onProviderTypeChange,
|
|
initialProviderType = null,
|
|
}: ConnectStepProps) {
|
|
const { setProvider, setVia, setSecretId, setMode } =
|
|
useProviderWizardStore();
|
|
const backHandlerRef = useRef<(() => void) | null>(null);
|
|
// The modal hands over a fresh `onClose` every render; the footer effect
|
|
// keeps one closure and reads the latest through the ref, as LaunchStep does.
|
|
const closeHandlerRef = useRef(onClose);
|
|
closeHandlerRef.current = onClose;
|
|
// Local state needed: AWS swaps the generic account form for its one-step form.
|
|
const [isAwsFlow, setIsAwsFlow] = useState(initialProviderType === "aws");
|
|
const [uiState, setUiState] = useState<AwsConnectUiState>({
|
|
showBack: false,
|
|
showAction: false,
|
|
actionLabel: "Next",
|
|
actionDisabled: true,
|
|
isLoading: false,
|
|
});
|
|
|
|
const formId = "provider-wizard-connect-form";
|
|
|
|
const handleSuccess = (data: ConnectAccountSuccessData) => {
|
|
setProvider({
|
|
id: data.id,
|
|
type: data.providerType,
|
|
uid: data.uid,
|
|
alias: data.alias,
|
|
});
|
|
setVia(null);
|
|
setSecretId(null);
|
|
setMode(PROVIDER_WIZARD_MODE.ADD);
|
|
// The layout only re-counts providers on a server render; flip the shared flag now.
|
|
useUIStore.getState().setHasProviders(true);
|
|
onNext();
|
|
};
|
|
|
|
useEffect(() => {
|
|
// The footer sits outside the tour's spotlight, so once the user can continue
|
|
// the tour has done its job and gets out of the way. No-op off-onboarding.
|
|
if (uiState.showAction && !uiState.actionDisabled && !uiState.isLoading) {
|
|
endActiveTour();
|
|
}
|
|
// Nothing left to submit once a teammate has been invited: the action closes.
|
|
const closes = uiState.actionKind === AWS_CONNECT_ACTION_KIND.CLOSE;
|
|
onFooterChange({
|
|
showBack: uiState.showBack,
|
|
backLabel: "Back",
|
|
backDisabled: uiState.isLoading,
|
|
// Leaving AWS remounts the generic form on a fresh provider list.
|
|
onBack: isAwsFlow
|
|
? () => setIsAwsFlow(false)
|
|
: () => backHandlerRef.current?.(),
|
|
showAction: uiState.showAction,
|
|
actionLabel: uiState.actionLabel,
|
|
actionLoading: uiState.isLoading,
|
|
actionDisabled: uiState.actionDisabled || uiState.isLoading,
|
|
actionType: closes
|
|
? WIZARD_FOOTER_ACTION_TYPE.BUTTON
|
|
: WIZARD_FOOTER_ACTION_TYPE.SUBMIT,
|
|
actionFormId: closes ? undefined : formId,
|
|
onAction: closes ? () => closeHandlerRef.current() : undefined,
|
|
});
|
|
}, [isAwsFlow, onFooterChange, uiState]);
|
|
|
|
const handleProviderTypeChange = (providerType: ProviderType | null) => {
|
|
onProviderTypeChange(providerType);
|
|
if (providerType === "aws") setIsAwsFlow(true);
|
|
};
|
|
|
|
if (isAwsFlow) {
|
|
return (
|
|
<AwsConnectStep
|
|
formId={formId}
|
|
onConnected={onCredentialsSaved}
|
|
onSelectOrganizations={() =>
|
|
onSelectOrganizations(ORGANIZATION_TYPE.AWS)
|
|
}
|
|
onUiStateChange={setUiState}
|
|
/>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<ConnectAccountForm
|
|
formId={formId}
|
|
hideNavigation
|
|
onSuccess={handleSuccess}
|
|
onSelectOrganizations={onSelectOrganizations}
|
|
onProviderTypeChange={handleProviderTypeChange}
|
|
onUiStateChange={setUiState}
|
|
onBackHandlerChange={(handler) => {
|
|
backHandlerRef.current = handler;
|
|
}}
|
|
/>
|
|
);
|
|
}
|