@openshift-assisted/ui-lib
Version:
React component library for the Assisted Installer UI
211 lines • 12.8 kB
JavaScript
"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