UNPKG

@openshift-assisted/ui-lib

Version:

React component library for the Assisted Installer UI

211 lines 12.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useHostsSelectionFormik = void 0; const tslib_1 = require("tslib"); const react_1 = tslib_1.__importDefault(require("react")); const Yup = tslib_1.__importStar(require("yup")); const formik_1 = require("formik"); const react_core_1 = require("@patternfly/react-core"); const common_1 = require("../../../common"); const ClusterDeploymentHostsSelection_1 = tslib_1.__importDefault(require("./ClusterDeploymentHostsSelection")); const validationSchemas_1 = require("./validationSchemas"); const helpers_1 = require("../helpers"); const wizardTransition_1 = require("./wizardTransition"); const use_translation_wrapper_1 = require("../../../common/hooks/use-translation-wrapper"); const ValidationSection_1 = require("./components/ValidationSection"); const ClusterDeploymentWizardContext_1 = require("./ClusterDeploymentWizardContext"); const getInitialValues = ({ agents, clusterDeployment, agentClusterInstall, }) => { var _a, _b, _c, _d, _e, _f, _g; const isSNOCluster = (0, helpers_1.getIsSNOCluster)(agentClusterInstall); const cdName = (_a = clusterDeployment === null || clusterDeployment === void 0 ? void 0 : clusterDeployment.metadata) === null || _a === void 0 ? void 0 : _a.name; const cdNamespace = (_b = clusterDeployment === null || clusterDeployment === void 0 ? void 0 : clusterDeployment.metadata) === null || _b === void 0 ? void 0 : _b.namespace; let hostCount = (((_d = (_c = agentClusterInstall === null || agentClusterInstall === void 0 ? void 0 : agentClusterInstall.spec) === null || _c === void 0 ? void 0 : _c.provisionRequirements) === null || _d === void 0 ? void 0 : _d.controlPlaneAgents) || 0) + (((_f = (_e = agentClusterInstall === null || agentClusterInstall === void 0 ? void 0 : agentClusterInstall.spec) === null || _e === void 0 ? void 0 : _e.provisionRequirements) === null || _f === void 0 ? void 0 : _f.workerAgents) || 0); if (isSNOCluster) { hostCount = 1; } else if (hostCount === 2 || hostCount === 0) { hostCount = 3; } else if (hostCount === 4) { hostCount = 5; } const agentSelector = (0, helpers_1.getAgentSelectorFieldsFromAnnotations)((_g = clusterDeployment === null || clusterDeployment === void 0 ? void 0 : clusterDeployment.metadata) === null || _g === void 0 ? void 0 : _g.annotations); const selectedIds = agents .filter((agent) => { var _a, _b, _c, _d; return ((_b = (_a = agent.spec) === null || _a === void 0 ? void 0 : _a.clusterDeploymentName) === null || _b === void 0 ? void 0 : _b.name) === cdName && ((_d = (_c = agent.spec) === null || _c === void 0 ? void 0 : _c.clusterDeploymentName) === null || _d === void 0 ? void 0 : _d.namespace) === cdNamespace; }) .map((agent) => { var _a; return (_a = agent.metadata) === null || _a === void 0 ? void 0 : _a.uid; }); const autoSelectHosts = agentSelector.autoSelect; return { autoSelectHosts, hostCount, useMastersAsWorkers: hostCount === 1 || hostCount === 3, agentLabels: (agentSelector === null || agentSelector === void 0 ? void 0 : agentSelector.labels) || [], locations: (agentSelector === null || agentSelector === void 0 ? void 0 : agentSelector.locations) || [], selectedHostIds: selectedIds, autoSelectedHostIds: selectedIds, }; }; const getValidationSchema = (agentClusterInstall, t) => { const isSNOCluster = (0, helpers_1.getIsSNOCluster)(agentClusterInstall); return Yup.lazy((values) => { return Yup.object({ hostCount: isSNOCluster ? Yup.number() : (0, validationSchemas_1.hostCountValidationSchema)(t), useMastersAsWorkers: Yup.boolean().required(t('ai:Required field')), autoSelectedHostIds: values.autoSelectHosts ? Yup.array(Yup.string()).min(values.hostCount).max(values.hostCount) : Yup.array(Yup.string()), selectedHostIds: values.autoSelectHosts ? Yup.array(Yup.string()) : isSNOCluster ? Yup.array(Yup.string()) .min(1, t('ai:Please select one host for the cluster.')) .max(1, t('ai:Please select one host for the cluster.')) // TODO(jtomasek): replace this with Yup.array().length() after updating Yup : Yup.array(Yup.string()).min(3, t('ai:Please select at least 3 hosts for the cluster.')), }); }); }; const useHostsSelectionFormik = ({ agents, clusterDeployment, agentClusterInstall, t, }) => { const initialValues = react_1.default.useMemo(() => getInitialValues({ agents, clusterDeployment, agentClusterInstall }), [agentClusterInstall, agents, clusterDeployment]); const validationSchema = react_1.default.useMemo(() => getValidationSchema(agentClusterInstall, t), [agentClusterInstall, t]); return [initialValues, validationSchema]; }; exports.useHostsSelectionFormik = useHostsSelectionFormik; const getSelectedAgents = (agents, values) => { const selectedHostIds = values.autoSelectHosts ? values.autoSelectedHostIds : values.selectedHostIds; return agents.filter((agent) => { var _a; return selectedHostIds.includes(((_a = agent.metadata) === null || _a === void 0 ? void 0 : _a.uid) || ''); }); }; const HostSelectionForm = ({ agents, agentClusterInstall, clusterDeployment, aiConfigMap, onEditRole: onEditRoleInit, onSetInstallationDiskId, isNutanix, }) => { const { activeStep, goToNextStep, goToPrevStep, close } = (0, react_core_1.useWizardContext)(); const { syncError } = react_1.default.useContext(ClusterDeploymentWizardContext_1.ClusterDeploymentWizardContext); const { alerts } = (0, common_1.useAlerts)(); const [showClusterErrors, setShowClusterErrors] = react_1.default.useState(false); const { values, isValid, isValidating, isSubmitting, touched, errors, validateForm, setTouched, submitForm, setSubmitting, } = (0, formik_1.useFormikContext)(); const [nextRequested, setNextRequested] = react_1.default.useState(false); const [showFormErrors, setShowFormErrors] = react_1.default.useState(false); const selectedAgents = getSelectedAgents(agents, values); const { t } = (0, use_translation_wrapper_1.useTranslation)(); const onEditRole = react_1.default.useCallback((agent, role) => tslib_1.__awaiter(void 0, void 0, void 0, function* () { setNextRequested(false); setShowClusterErrors(false); setSubmitting(true); const response = yield (onEditRoleInit === null || onEditRoleInit === void 0 ? void 0 : onEditRoleInit(agent, role)); setSubmitting(false); return response; }), [onEditRoleInit, setSubmitting]); const onAutoSelectChange = react_1.default.useCallback(() => { setNextRequested(false); setShowClusterErrors(false); setShowFormErrors(false); }, []); const onHostSelect = react_1.default.useCallback(() => { setNextRequested(false); setShowClusterErrors(false); }, []); const onNext = react_1.default.useCallback(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () { if (!showFormErrors) { setShowFormErrors(true); const errors = yield validateForm(); setTouched(Object.keys(errors).reduce((acc, curr) => { acc[curr] = true; return acc; }, {})); if (Object.keys(errors).length) { return; } } void submitForm(); setNextRequested(true); }), [setTouched, showFormErrors, submitForm, validateForm]); react_1.default.useEffect(() => { if (nextRequested && !isSubmitting) { const agentStatuses = selectedAgents.map((agent) => (0, helpers_1.getWizardStepAgentStatus)(agent, 'hosts-selection', t).status.key); if (agentStatuses.some((status) => ['disconnected', 'disabled', 'error', 'insufficient', 'cancelled'].includes(status))) { setNextRequested(false); } else if (!!selectedAgents.length && selectedAgents.every((agent) => (0, helpers_1.getWizardStepAgentStatus)(agent, 'hosts-selection', t).status.key === 'known')) { setShowClusterErrors(true); if ((0, wizardTransition_1.canNextFromHostSelectionStep)(agentClusterInstall, selectedAgents)) { void goToNextStep(); } } } }, [nextRequested, selectedAgents, agentClusterInstall, isSubmitting, t, goToNextStep]); const submittingText = react_1.default.useMemo(() => { if (isSubmitting) { return t('ai:Saving changes...'); } else if (nextRequested && !showClusterErrors) { return t('ai:Binding hosts...'); } return undefined; }, [isSubmitting, nextRequested, showClusterErrors, t]); react_1.default.useEffect(() => { if (syncError) { setNextRequested(false); } }, [syncError]); const errorsSection = (react_1.default.createElement(ValidationSection_1.ValidationSection, { currentStepId: 'cluster-details', hosts: [] }, syncError && (react_1.default.createElement(react_core_1.Alert, { variant: react_core_1.AlertVariant.danger, title: t('ai:An error occured'), isInline: true }, syncError)))); const footer = react_1.default.useMemo(() => (react_1.default.createElement(react_core_1.WizardFooter, { activeStep: activeStep, onNext: onNext, isNextDisabled: nextRequested || isSubmitting || (showFormErrors ? !isValid || isValidating : false) // || , nextButtonText: submittingText || t('ai:Next'), nextButtonProps: { isLoading: !!submittingText }, onBack: goToPrevStep, onClose: close })), [ activeStep, onNext, nextRequested, isSubmitting, showFormErrors, isValid, isValidating, submittingText, t, goToPrevStep, close, ]); (0, react_core_1.useWizardFooter)(footer); return (react_1.default.createElement(react_core_1.Grid, { hasGutter: true }, react_1.default.createElement(react_core_1.GridItem, null, react_1.default.createElement(common_1.ClusterWizardStepHeader, null, t('ai:Cluster hosts'))), react_1.default.createElement(react_core_1.GridItem, null, react_1.default.createElement(ClusterDeploymentHostsSelection_1.default, { agentClusterInstall: agentClusterInstall, agents: agents, clusterDeployment: clusterDeployment, aiConfigMap: aiConfigMap, onEditRole: onEditRole, onSetInstallationDiskId: onSetInstallationDiskId, onAutoSelectChange: onAutoSelectChange, onHostSelect: onHostSelect, isNutanix: isNutanix })), (showClusterErrors || showFormErrors) && !!alerts.length && (react_1.default.createElement(react_core_1.GridItem, null, react_1.default.createElement(common_1.Alerts, null))), syncError && react_1.default.createElement(react_core_1.GridItem, null, errorsSection), showFormErrors && errors.selectedHostIds && touched.selectedHostIds && (react_1.default.createElement(react_core_1.GridItem, null, react_1.default.createElement(react_core_1.Alert, { variant: react_core_1.AlertVariant.danger, title: t('ai:Provided cluster configuration is not valid'), isInline: true }, errors.selectedHostIds))))); }; const ClusterDeploymentHostSelectionStep = (_a) => { var { onSaveHostsSelection } = _a, rest = tslib_1.__rest(_a, ["onSaveHostsSelection"]); const { t } = (0, use_translation_wrapper_1.useTranslation)(); const { addAlert } = (0, common_1.useAlerts)(); const { agents, clusterDeployment, agentClusterInstall } = rest; const [initialValues, validationSchema] = (0, exports.useHostsSelectionFormik)({ agents, clusterDeployment, agentClusterInstall, t, }); const handleSubmit = (values, { setSubmitting }) => tslib_1.__awaiter(void 0, void 0, void 0, function* () { try { yield onSaveHostsSelection(values); } catch (e) { const error = e; addAlert({ title: t('ai:Failed to save host selection.'), message: error.message, }); } finally { setSubmitting(false); } }); return (react_1.default.createElement(formik_1.Formik, { initialValues: initialValues, validationSchema: validationSchema, onSubmit: handleSubmit }, react_1.default.createElement(HostSelectionForm, Object.assign({}, rest)))); }; exports.default = ClusterDeploymentHostSelectionStep; //# sourceMappingURL=ClusterDeploymentHostSelectionStep.js.map