UNPKG

@openshift-assisted/ui-lib

Version:

React component library for the Assisted Installer UI

151 lines 9.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const React = tslib_1.__importStar(require("react")); const react_core_1 = require("@patternfly/react-core"); const formik_1 = require("formik"); const Yup = tslib_1.__importStar(require("yup")); const global_palette_blue_300_1 = require("@patternfly/react-tokens/dist/js/global_palette_blue_300"); const info_circle_icon_1 = require("@patternfly/react-icons/dist/js/icons/info-circle-icon"); const ui_1 = require("../ui"); const utils_1 = require("./utils"); const use_translation_wrapper_1 = require("../../hooks/use-translation-wrapper"); const api_1 = require("../../api"); // eslint-disable-line no-restricted-imports require("./MassChangeHostnameModal.css"); const getHostname = (host) => { const inventory = (0, utils_1.getInventory)(host); return (0, utils_1.getHostname)(host, inventory) || ''; }; const templateToHostname = (index, values) => values.hostname.replace(/{{n+}}/g, `${index + 1}`); const getNewHostnames = (values, selectedHosts, canChangeHostname) => { let index = 0; return selectedHosts.map((h) => { const [changeEnabled, reason] = canChangeHostname(h); const hostnameRes = { newHostname: changeEnabled ? templateToHostname(index, values) : undefined, reason: changeEnabled ? undefined : reason, }; if (changeEnabled) { index++; } return hostnameRes; }); }; const initialValues = { hostname: '', }; const validationSchema = (initialValues, usedHostnames, t) => Yup.object().shape({ hostname: (0, ui_1.richHostnameValidationSchema)(t, usedHostnames, initialValues.hostname).required(t('ai:Required field')), }); const updateHostnameValidationResult = (validationResult, message) => { validationResult = Object.assign(Object.assign({}, (validationResult || {})), { hostname: ((validationResult === null || validationResult === void 0 ? void 0 : validationResult.hostname) || []).concat(message) }); return validationResult; }; const withTemplate = (selectedHosts, hosts, schema, canChangeHostname, t) => (values) => tslib_1.__awaiter(void 0, void 0, void 0, function* () { const newHostnames = getNewHostnames(values, selectedHosts, canChangeHostname) .filter((h) => !h.reason) .map(({ newHostname }) => newHostname); const usedHostnames = hosts.reduce((acc, host) => { if (!selectedHosts.find((a) => a.id === host.id)) { acc.push(getHostname(host)); } return acc; }, []); let validationResult = yield (0, ui_1.getRichTextValidation)(schema)(Object.assign(Object.assign({}, values), { hostname: newHostnames[0] || '' })); if (newHostnames.some((newHostname) => usedHostnames.includes(newHostname || '')) || new Set(newHostnames).size !== newHostnames.length) { validationResult = updateHostnameValidationResult(validationResult, (0, ui_1.hostnameValidationMessages)(t).NOT_UNIQUE); } if (newHostnames.some((hostname) => ui_1.FORBIDDEN_HOSTNAMES.includes(hostname || ''))) { validationResult = updateHostnameValidationResult(validationResult, (0, ui_1.hostnameValidationMessages)(t).LOCALHOST_ERR); } return validationResult; }); const MassChangeHostnameForm = ({ selectedHosts: initHosts, isOpen, patchingHost, onClose, canChangeHostname, }) => { var _a; // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const { values, handleSubmit, isSubmitting, status, isValid } = (0, formik_1.useFormikContext)(); const hostnameInputRef = React.useRef(); const ref = React.useRef(initHosts); React.useEffect(() => { var _a; isOpen && ((_a = hostnameInputRef.current) === null || _a === void 0 ? void 0 : _a.focus()); }, [isOpen]); React.useCallback(() => { if (!isSubmitting) { ref.current = initHosts; } }, [initHosts, isSubmitting]); const selectedHosts = ref.current; const newHostnames = getNewHostnames(values, selectedHosts, canChangeHostname); const { t } = (0, use_translation_wrapper_1.useTranslation)(); return (React.createElement(react_core_1.Form, { onSubmit: handleSubmit }, React.createElement(react_core_1.ModalBoxBody, null, React.createElement(react_core_1.Stack, { hasGutter: true }, React.createElement(react_core_1.StackItem, null, React.createElement("div", null, t('ai:Rename hostnames using the custom template:')), React.createElement("div", null, React.createElement("strong", null, `{{n}}`), " ", t('ai:to add a number.'))), React.createElement(react_core_1.StackItem, null, React.createElement(ui_1.RichInputField, { name: "hostname", ref: hostnameInputRef, isRequired: true, richValidationMessages: (0, ui_1.hostnameValidationMessages)(t) }), React.createElement(react_core_1.HelperText, null, React.createElement(react_core_1.HelperTextItem, { variant: "indeterminate" }, t('ai:For example: host-{{n}}', { interpolation: { suffix: '###', prefix: '###' }, })))), React.createElement(react_core_1.StackItem, null, t('ai:Preview'), React.createElement("div", { className: "hostname-preview" }, selectedHosts.map((h, index) => { const { newHostname, reason } = newHostnames[index]; return (React.createElement(react_core_1.Split, { key: h.id || index, hasGutter: true }, React.createElement(react_core_1.SplitItem, { className: "hostname-column" }, React.createElement("div", { className: "hostname-column__text" }, React.createElement("strong", null, getHostname(h)))), React.createElement(react_core_1.SplitItem, null, React.createElement("div", null, React.createElement("strong", null, '>'))), React.createElement(react_core_1.SplitItem, { isFilled: true }, reason ? (React.createElement(react_core_1.Popover, { "aria-label": t('ai:Cannot change hostname popover'), headerContent: React.createElement("div", null, t('ai:Hostname cannot be changed')), bodyContent: React.createElement("div", null, reason) }, React.createElement(react_core_1.Button, { variant: "link", icon: React.createElement(info_circle_icon_1.InfoCircleIcon, { color: global_palette_blue_300_1.global_palette_blue_300.value }), isInline: true }, t('ai:Not changeable')))) : (newHostname || t('ai:New hostname will appear here...'))))); }))), React.createElement(react_core_1.StackItem, null, React.createElement(ui_1.ModalProgress // eslint-disable-next-line , { // eslint-disable-next-line error: status === null || status === void 0 ? void 0 : status.error, progress: isSubmitting ? (100 * (patchingHost + 1)) / selectedHosts.length : null })))), React.createElement(react_core_1.ModalBoxFooter, null, React.createElement(react_core_1.Button, { key: "submit", type: react_core_1.ButtonType.submit, isDisabled: isSubmitting || !isValid || !((_a = hostnameInputRef.current) === null || _a === void 0 ? void 0 : _a.value.trim()) }, t('ai:Change')), React.createElement(react_core_1.Button, { onClick: onClose, variant: react_core_1.ButtonVariant.secondary, isDisabled: isSubmitting }, t('ai:Cancel'))))); }; const MassChangeHostnameModal = ({ isOpen, onClose, selectedHostIDs, hosts, onChangeHostname, canChangeHostname, reloadCluster, onHostSaveError, }) => { const [patchingHost, setPatchingHost] = React.useState(0); const selectedHosts = hosts.filter((h) => selectedHostIDs.includes(h.id)); const { t } = (0, use_translation_wrapper_1.useTranslation)(); return (React.createElement(react_core_1.Modal, { "aria-label": t('ai:Change hostnames dialog'), title: t('ai:Change hostnames'), isOpen: isOpen, onClose: onClose, hasNoBodyWrapper: true, id: "mass-change-hostname-modal", variant: "small" }, React.createElement(formik_1.Formik, { initialValues: initialValues, validate: withTemplate(selectedHosts, hosts, validationSchema(initialValues, [], t), canChangeHostname, t), onSubmit: (values, formikActions) => tslib_1.__awaiter(void 0, void 0, void 0, function* () { let i = 0; try { for (const agent of selectedHosts) { setPatchingHost(i); const newHostname = templateToHostname(i, values); yield onChangeHostname(agent, newHostname); i++; } reloadCluster && reloadCluster(); onClose(); } catch (e) { formikActions.setStatus({ error: { title: t('ai:Failed to update host'), message: (0, api_1.getApiErrorMessage)(e), }, }); onHostSaveError && onHostSaveError(e); } }) }, React.createElement(MassChangeHostnameForm, { isOpen: isOpen, selectedHosts: selectedHosts, patchingHost: patchingHost, onClose: onClose, canChangeHostname: canChangeHostname })))); }; exports.default = MassChangeHostnameModal; //# sourceMappingURL=MassChangeHostnameModal.js.map