diff --git a/src/fireedge/src/client/components/Dialogs/DialogConfirmation.js b/src/fireedge/src/client/components/Dialogs/DialogConfirmation.js index b6f95b5d51..4a86ef9395 100644 --- a/src/fireedge/src/client/components/Dialogs/DialogConfirmation.js +++ b/src/fireedge/src/client/components/Dialogs/DialogConfirmation.js @@ -105,9 +105,11 @@ const DialogConfirmation = memo( >
- - {typeof title === 'string' ? Tr(title) : title} - + {title && ( + + {typeof title === 'string' ? Tr(title) : title} + + )} {subheader && ( {typeof subheader === 'string' ? Tr(subheader) : subheader} @@ -152,7 +154,7 @@ export const DialogPropTypes = { title: PropTypes.oneOfType([ PropTypes.string, PropTypes.node - ]).isRequired, + ]), subheader: PropTypes.string, contentProps: PropTypes.object, handleAccept: PropTypes.func, diff --git a/src/fireedge/src/client/components/Forms/ButtonToTriggerForm.js b/src/fireedge/src/client/components/Forms/ButtonToTriggerForm.js index fb381f629e..baa30c773e 100644 --- a/src/fireedge/src/client/components/Forms/ButtonToTriggerForm.js +++ b/src/fireedge/src/client/components/Forms/ButtonToTriggerForm.js @@ -47,7 +47,7 @@ const ButtonToTriggerForm = ({ const open = Boolean(anchorEl) const { display, show, hide, values: Form } = useDialog() - const { onSubmit: handleSubmit, form, isConfirmDialog = true } = Form ?? {} + const { onSubmit: handleSubmit, form, isConfirmDialog = false } = Form ?? {} const formConfig = useMemo(() => form?.() ?? {}, [form]) const { steps, defaultValues, resolver, fields, transformBeforeSubmit } = formConfig diff --git a/src/fireedge/src/client/components/Forms/Provider/CreateForm/Steps/BasicConfiguration/index.js b/src/fireedge/src/client/components/Forms/Provider/CreateForm/Steps/BasicConfiguration/index.js index f8578bfe35..85d8786d41 100644 --- a/src/fireedge/src/client/components/Forms/Provider/CreateForm/Steps/BasicConfiguration/index.js +++ b/src/fireedge/src/client/components/Forms/Provider/CreateForm/Steps/BasicConfiguration/index.js @@ -14,26 +14,35 @@ * limitations under the License. * * ------------------------------------------------------------------------- */ /* eslint-disable jsdoc/require-jsdoc */ -import { useCallback } from 'react' +import PropTypes from 'prop-types' import FormWithSchema from 'client/components/Forms/FormWithSchema' +import { FORM_FIELDS, STEP_FORM_SCHEMA } from 'client/components/Forms/Provider/CreateForm/Steps/BasicConfiguration/schema' import { T } from 'client/constants' -import { - FORM_FIELDS, STEP_FORM_SCHEMA -} from 'client/components/Forms/Provider/CreateForm/Steps/BasicConfiguration/schema' - export const STEP_ID = 'configuration' +const Content = ({ isUpdate }) => { + return ( + + ) +} + const BasicConfiguration = ({ isUpdate }) => ({ id: STEP_ID, label: T.ProviderOverview, resolver: () => STEP_FORM_SCHEMA({ isUpdate }), optionsValidate: { abortEarly: false }, - content: useCallback( - () => , - [] - ) + content: () => Content({ isUpdate }) }) +Content.propTypes = { + isUpdate: PropTypes.bool +} + +export * from 'client/components/Forms/Provider/CreateForm/Steps/BasicConfiguration/schema' export default BasicConfiguration diff --git a/src/fireedge/src/client/components/Forms/Provider/CreateForm/Steps/Connection/index.js b/src/fireedge/src/client/components/Forms/Provider/CreateForm/Steps/Connection/index.js index 6750789853..82f09eaa93 100644 --- a/src/fireedge/src/client/components/Forms/Provider/CreateForm/Steps/Connection/index.js +++ b/src/fireedge/src/client/components/Forms/Provider/CreateForm/Steps/Connection/index.js @@ -14,7 +14,8 @@ * limitations under the License. * * ------------------------------------------------------------------------- */ /* eslint-disable jsdoc/require-jsdoc */ -import { useCallback, useEffect, useState } from 'react' +import { useEffect, useState } from 'react' +import PropTypes from 'prop-types' import { useFormContext } from 'react-hook-form' import { useAuth } from 'client/features/Auth' @@ -25,56 +26,57 @@ import { getConnectionEditable } from 'client/models/ProviderTemplate' import { sentenceCase } from 'client/utils' import { T } from 'client/constants' -import { - FORM_FIELDS, STEP_FORM_SCHEMA -} from 'client/components/Forms/Provider/CreateForm/Steps/Connection/schema' - -import { - STEP_ID as TEMPLATE_ID -} from 'client/components/Forms/Provider/CreateForm/Steps/Template' +import { FORM_FIELDS, STEP_FORM_SCHEMA } from 'client/components/Forms/Provider/CreateForm/Steps/Connection/schema' +import { STEP_ID as TEMPLATE_ID } from 'client/components/Forms/Provider/CreateForm/Steps/Template' export const STEP_ID = 'connection' let connection = {} let fileCredentials = false +const Content = ({ isUpdate }) => { + const [fields, setFields] = useState([]) + const { providerConfig } = useAuth() + const { watch } = useFormContext() + + useEffect(() => { + const { + [TEMPLATE_ID]: templateSelected, + [STEP_ID]: currentConnection = {} + } = watch() + + const template = templateSelected?.[0] ?? {} + + fileCredentials = Boolean(providerConfig?.[template?.provider]?.file_credentials) + + connection = isUpdate + // when is updating, connections have the name as input label + ? Object.keys(currentConnection) + .reduce((res, name) => ({ ...res, [name]: sentenceCase(name) }), {}) + // set connections from template, to take values as input labels + : getConnectionEditable(template, providerConfig) + + setFields(FORM_FIELDS({ connection, fileCredentials })) + }, []) + + return (fields?.length === 0) ? ( + + ) : ( + + ) +} + const Connection = ({ isUpdate }) => ({ id: STEP_ID, label: T.ConfigureConnection, resolver: () => STEP_FORM_SCHEMA({ connection, fileCredentials }), optionsValidate: { abortEarly: false }, - content: useCallback(() => { - const [fields, setFields] = useState([]) - const { providerConfig } = useAuth() - const { watch } = useFormContext() - - useEffect(() => { - const { - [TEMPLATE_ID]: templateSelected, - [STEP_ID]: currentConnection = {} - } = watch() - - const template = templateSelected?.[0] ?? {} - - fileCredentials = Boolean(providerConfig?.[template?.provider]?.file_credentials) - - connection = isUpdate - // when is updating, connections have the name as input label - ? Object.keys(currentConnection) - .reduce((res, name) => ({ ...res, [name]: sentenceCase(name) }), {}) - // set connections from template, to take values as input labels - : getConnectionEditable(template, providerConfig) - - setFields(FORM_FIELDS({ connection, fileCredentials })) - }, []) - - return (fields?.length === 0) ? ( - - ) : ( - - ) - }, []) + content: () => Content({ isUpdate }) }) +Content.propTypes = { + isUpdate: PropTypes.bool +} + export * from 'client/components/Forms/Provider/CreateForm/Steps/Connection/schema' export default Connection diff --git a/src/fireedge/src/client/components/Forms/Provider/CreateForm/Steps/Template/index.js b/src/fireedge/src/client/components/Forms/Provider/CreateForm/Steps/Template/index.js index 119bfb18e6..5dec56d069 100644 --- a/src/fireedge/src/client/components/Forms/Provider/CreateForm/Steps/Template/index.js +++ b/src/fireedge/src/client/components/Forms/Provider/CreateForm/Steps/Template/index.js @@ -14,7 +14,8 @@ * limitations under the License. * * ------------------------------------------------------------------------- */ /* eslint-disable jsdoc/require-jsdoc */ -import { useState, useCallback, useEffect, useMemo } from 'react' +import { useState, useEffect, useMemo } from 'react' +import PropTypes from 'prop-types' import { Divider, Select, Breadcrumbs, InputLabel, FormControl } from '@material-ui/core' import { NavArrowRight } from 'iconoir-react' import Marked from 'marked' @@ -35,172 +36,179 @@ import { STEP_ID as CONNECTION_ID } from 'client/components/Forms/Provider/Creat export const STEP_ID = 'template' +const Content = ({ data, setFormData }) => { + const provisionTemplates = useProvisionTemplate() + const { providerConfig } = useAuth() + const templateSelected = data?.[0] + + const provisionTypes = useMemo(() => [ + ...new Set( + Object.values(providerConfig) + .map(provider => provider?.provision_type).flat() + ) + ], []) + + const provisionTypeSelected = useMemo(() => ( + getProvisionTypeFromTemplate(provisionTemplates, templateSelected) + ), []) + + const [provisionSelected, setProvision] = useState(() => provisionTypeSelected ?? provisionTypes[0]) + const [providerSelected, setProvider] = useState(() => templateSelected?.provider) + + const [templatesByProvisionSelected, providerTypes, description] = useMemo(() => { + const templates = Object.values(provisionTemplates[provisionSelected]?.providers).flat() + const types = [...new Set(templates.map(({ provider }) => provider))] + const provisionDescription = provisionTemplates?.[provisionSelected]?.description + + return [templates, types, provisionDescription] + }, [provisionSelected]) + + const templatesAvailable = useMemo(() => ( + templatesByProvisionSelected.filter(({ provider }) => providerSelected === provider) + ), [providerSelected]) + + useEffect(() => { + // set first provision type + !provisionSelected && setProvision(provisionTypes[0]) + }, []) + + useEffect(() => { + // set first provider type + provisionSelected && !providerSelected && setProvider(providerTypes[0]) + }, [provisionSelected]) + + const { handleSelect, handleUnselect, handleClear } = useListForm({ + key: STEP_ID, + list: data, + setList: setFormData, + getItemId: item => item.name + }) + + const handleChangeProvision = evt => { + setProvision(evt.target.value) + setProvider(undefined) + templateSelected && handleClear() + } + + const handleChangeProvider = evt => { + setProvider(evt.target.value) + templateSelected && handleClear() + } + + const handleClick = (template, isSelected) => { + const { name, description } = template + + // reset rest of form when change template + setFormData({ + [CONFIGURATION_ID]: { name, description }, + [CONNECTION_ID]: {} + }) + + isSelected + ? handleUnselect(name) + : handleSelect(template) + } + + const RenderDescription = ({ description = '' }) => { + const renderer = new Marked.Renderer() + + renderer.link = (href, title, text) => ( + `${text}` + ) + + const html = Marked(sanitize`${description}`, { renderer }) + return
+ } + + return ( + <> + {/* -- SELECTORS -- */} + }> + + + {'Provision type'} + + + + + + {'Provider type'} + + + + + + {/* -- DESCRIPTION -- */} + {useMemo(() => description && , [description])} + + + + {/* -- LIST -- */} + { + const isSelected = data?.some(selected => selected.name === value.name) + const isValid = isValidProviderTemplate(value, providerConfig) + const image = providerConfig?.[value.provider]?.image + + return { + image, + isProvider: true, + isSelected, + isValid, + handleClick: () => handleClick(value, isSelected) + } + }} + /> + + ) +} + const Template = () => ({ id: STEP_ID, label: T.ProviderTemplate, resolver: () => STEP_FORM_SCHEMA, - content: useCallback( - ({ data, setFormData }) => { - const provisionTemplates = useProvisionTemplate() - const { providerConfig } = useAuth() - const templateSelected = data?.[0] - - const provisionTypes = useMemo(() => [ - ...new Set( - Object.values(providerConfig) - .map(provider => provider?.provision_type).flat() - ) - ], []) - - const provisionTypeSelected = useMemo(() => ( - getProvisionTypeFromTemplate(provisionTemplates, templateSelected) - ), []) - - const [provisionSelected, setProvision] = useState(() => provisionTypeSelected ?? provisionTypes[0]) - const [providerSelected, setProvider] = useState(() => templateSelected?.provider) - - const [templatesByProvisionSelected, providerTypes, description] = useMemo(() => { - const templates = Object.values(provisionTemplates[provisionSelected]?.providers).flat() - const types = [...new Set(templates.map(({ provider }) => provider))] - const provisionDescription = provisionTemplates?.[provisionSelected]?.description - - return [templates, types, provisionDescription] - }, [provisionSelected]) - - const templatesAvailable = useMemo(() => ( - templatesByProvisionSelected.filter(({ provider }) => providerSelected === provider) - ), [providerSelected]) - - useEffect(() => { - // set first provision type - !provisionSelected && setProvision(provisionTypes[0]) - }, []) - - useEffect(() => { - // set first provider type - provisionSelected && !providerSelected && setProvider(providerTypes[0]) - }, [provisionSelected]) - - const { handleSelect, handleUnselect, handleClear } = useListForm({ - key: STEP_ID, - list: data, - setList: setFormData, - getItemId: item => item.name - }) - - const handleChangeProvision = evt => { - setProvision(evt.target.value) - setProvider(undefined) - templateSelected && handleClear() - } - - const handleChangeProvider = evt => { - setProvider(evt.target.value) - templateSelected && handleClear() - } - - const handleClick = (template, isSelected) => { - const { name, description } = template - - // reset rest of form when change template - setFormData({ - [CONFIGURATION_ID]: { name, description }, - [CONNECTION_ID]: {} - }) - - isSelected - ? handleUnselect(name) - : handleSelect(template) - } - - const RenderDescription = ({ description = '' }) => { - const renderer = new Marked.Renderer() - - renderer.link = (href, title, text) => ( - `${text}` - ) - - const html = Marked(sanitize`${description}`, { renderer }) - return
- } - - return ( - <> - {/* -- SELECTORS -- */} - }> - - - {'Provision type'} - - - - - - {'Provider type'} - - - - - - {/* -- DESCRIPTION -- */} - {useMemo(() => description && , [description])} - - - - {/* -- LIST -- */} - { - const isSelected = data?.some(selected => selected.name === value.name) - const isValid = isValidProviderTemplate(value, providerConfig) - const image = providerConfig?.[value.provider]?.image - - return { - image, - isProvider: true, - isSelected, - isValid, - handleClick: () => handleClick(value, isSelected) - } - }} - /> - - ) - }, []) + content: Content }) +Content.propTypes = { + data: PropTypes.any, + setFormData: PropTypes.func +} + +export * from 'client/components/Forms/Provider/CreateForm/Steps/Template/schema' export default Template diff --git a/src/fireedge/src/client/components/Forms/Provider/CreateForm/Steps/index.js b/src/fireedge/src/client/components/Forms/Provider/CreateForm/Steps/index.js index 0f93f8786d..d022e30b7d 100644 --- a/src/fireedge/src/client/components/Forms/Provider/CreateForm/Steps/index.js +++ b/src/fireedge/src/client/components/Forms/Provider/CreateForm/Steps/index.js @@ -13,10 +13,10 @@ * See the License for the specific language governing permissions and * * limitations under the License. * * ------------------------------------------------------------------------- */ -/* eslint-disable jsdoc/require-jsdoc */ -import Template from 'client/components/Forms/Provider/CreateForm/Steps/Template' -import BasicConfiguration from 'client/components/Forms/Provider/CreateForm/Steps/BasicConfiguration' -import Connection from 'client/components/Forms/Provider/CreateForm/Steps/Connection' +import Template, { STEP_ID as TEMPLATE_ID } from 'client/components/Forms/Provider/CreateForm/Steps/Template' +import BasicConfiguration, { STEP_ID as BASIC_ID } from 'client/components/Forms/Provider/CreateForm/Steps/BasicConfiguration' +import Connection, { STEP_ID as CONNECTION_ID } from 'client/components/Forms/Provider/CreateForm/Steps/Connection' +import { getConnectionEditable, getConnectionFixed } from 'client/models/ProviderTemplate' import { createSteps, deepmerge } from 'client/utils' const Steps = createSteps(stepProps => { @@ -28,11 +28,31 @@ const Steps = createSteps(stepProps => { Connection ].filter(Boolean) }, { - transformBeforeSubmit: formData => { - const { template, configuration, connection } = formData - const templateSelected = template?.[0] + transformInitialValue: ({ provider, connection, providerConfig } = {}) => { + const { description, ...currentBodyTemplate } = provider?.TEMPLATE?.PROVISION_BODY ?? {} - return deepmerge(templateSelected, { ...configuration, connection }) + // overwrite decrypted connection + const fakeProviderTemplate = { ...currentBodyTemplate, connection } + const connectionEditable = getConnectionEditable(fakeProviderTemplate, providerConfig) + + return { + [TEMPLATE_ID]: [fakeProviderTemplate], + [CONNECTION_ID]: connectionEditable, + [BASIC_ID]: { description } + } + }, + transformBeforeSubmit: (formData, providerConfig) => { + const { + [TEMPLATE_ID]: [templateSelected] = [], + [CONNECTION_ID]: connection = {}, + [BASIC_ID]: configuration = {} + } = formData ?? {} + + const connectionFixed = getConnectionFixed(templateSelected, providerConfig) + const allConnections = { ...connection, ...connectionFixed } + const editedData = { ...configuration, connection: allConnections } + + return deepmerge(templateSelected, editedData) } }) diff --git a/src/fireedge/src/client/components/Forms/Provider/CreateForm/index.js b/src/fireedge/src/client/components/Forms/Provider/CreateForm/index.js index 281b7a416e..cb8c263cb3 100644 --- a/src/fireedge/src/client/components/Forms/Provider/CreateForm/index.js +++ b/src/fireedge/src/client/components/Forms/Provider/CreateForm/index.js @@ -14,21 +14,26 @@ * limitations under the License. * * ------------------------------------------------------------------------- */ /* eslint-disable jsdoc/require-jsdoc */ +import { useEffect, useMemo } from 'react' import PropTypes from 'prop-types' +import { Redirect } from 'react-router' import { useForm, FormProvider } from 'react-hook-form' import { yupResolver } from '@hookform/resolvers/yup' -import FormStepper from 'client/components/FormStepper' +import { useFetchAll } from 'client/hooks' +import { useAuth } from 'client/features/Auth' +import { useProviderApi } from 'client/features/One' +import FormStepper, { SkeletonStepsForm } from 'client/components/FormStepper' import Steps from 'client/components/Forms/Provider/CreateForm/Steps' +import { PATH } from 'client/apps/provision/routes' -const CreateForm = ({ stepProps, initialValues, onSubmit }) => { - const { - steps, - defaultValues, - resolver, - transformBeforeSubmit - } = Steps(stepProps, initialValues) +const CreateForm = ({ provider, providerConfig, connection, onSubmit }) => { + const initialValues = provider && { provider, connection, providerConfig } + const stepProps = { isUpdate: !!initialValues } + + const stepsForm = useMemo(() => Steps(stepProps, initialValues), []) + const { steps, defaultValues, resolver, transformBeforeSubmit } = stepsForm const methods = useForm({ mode: 'onSubmit', @@ -41,18 +46,51 @@ const CreateForm = ({ stepProps, initialValues, onSubmit }) => { onSubmit(transformBeforeSubmit?.(data) ?? data)} + onSubmit={data => + onSubmit(transformBeforeSubmit?.(data, providerConfig) ?? data) + } /> ) } -CreateForm.propTypes = { - stepProps: PropTypes.shape({ - isUpdate: PropTypes.bool - }), - initialValues: PropTypes.object, +const PreFetchingForm = ({ providerId, onSubmit }) => { + const { providerConfig } = useAuth() + const { getProvider, getProviderConnection } = useProviderApi() + const { data, fetchRequestAll, error } = useFetchAll() + const [provider, connection] = data ?? [] + + useEffect(() => { + providerId && fetchRequestAll([ + getProvider(providerId), + getProviderConnection(providerId) + ]) + }, []) + + if (error) { + return + } + + return (providerId && !data) + ? + : +} + +PreFetchingForm.propTypes = { + providerId: PropTypes.string, onSubmit: PropTypes.func } -export default CreateForm +CreateForm.propTypes = { + provider: PropTypes.object, + connection: PropTypes.object, + providerConfig: PropTypes.object, + onSubmit: PropTypes.func +} + +export default PreFetchingForm diff --git a/src/fireedge/src/client/components/Forms/Vm/AttachNicForm/Steps/AdvancedOptions/schema.js b/src/fireedge/src/client/components/Forms/Vm/AttachNicForm/Steps/AdvancedOptions/schema.js index c08dcf920c..159f2e24d4 100644 --- a/src/fireedge/src/client/components/Forms/Vm/AttachNicForm/Steps/AdvancedOptions/schema.js +++ b/src/fireedge/src/client/components/Forms/Vm/AttachNicForm/Steps/AdvancedOptions/schema.js @@ -50,8 +50,9 @@ const ALIAS_FIELD = ({ nics = [] } = {}) => ({ .filter(({ NAME }) => NAME !== name || !name) // filter it self .map(nic => { const { NAME, IP = '', NETWORK = '', NIC_ID = '' } = nic + const text = [NAME ?? NIC_ID, NETWORK, IP].filter(Boolean).join(' - ') - return { text: `${NAME ?? NIC_ID} - ${NETWORK} ${IP}`, value: NAME } + return { text, value: NAME } }) ], validation: yup diff --git a/src/fireedge/src/client/components/Forms/VmTemplate/InstantiateForm/Steps/ExtraConfiguration/booting.js b/src/fireedge/src/client/components/Forms/VmTemplate/InstantiateForm/Steps/ExtraConfiguration/booting.js index 90278a1397..2cb05baf30 100644 --- a/src/fireedge/src/client/components/Forms/VmTemplate/InstantiateForm/Steps/ExtraConfiguration/booting.js +++ b/src/fireedge/src/client/components/Forms/VmTemplate/InstantiateForm/Steps/ExtraConfiguration/booting.js @@ -68,7 +68,7 @@ export const reorder = (newBootOrder, setFormData) => { const Booting = ({ data, setFormData }) => { const classes = useStyles() const { watch } = useFormContext() - const bootOrder = data?.OS?.BOOT?.split(',').filter(Boolean) + const bootOrder = data?.OS?.BOOT?.split(',').filter(Boolean) ?? [] const disks = useMemo(() => { const templateSeleted = watch(`${TEMPLATE_ID}[0]`) @@ -95,12 +95,13 @@ const Booting = ({ data, setFormData }) => { }, []) const nics = data?.[NIC_ID] + ?.map((nic, idx) => ({ ...nic, NAME: nic?.NAME ?? `NIC${idx}` })) ?.map((nic, idx) => ({ ID: `nic${idx}`, NAME: ( <> - {`NIC ${idx}: ${nic.NETWORK}`} + {[nic?.NAME ?? `NIC${idx}`, nic.NETWORK].filter(Boolean).join(': ')} ) })) ?? [] @@ -173,7 +174,7 @@ const Booting = ({ data, setFormData }) => {
)} - + {restOfItems.length > 0 && } {restOfItems.map(({ ID, NAME }) => (
{ const classes = useStyles() const nics = data?.[TAB_ID] - ?.map((nic, idx) => ({ ...nic, NAME: `NIC${idx}` })) + ?.map((nic, idx) => ({ ...nic, NAME: nic?.NAME ?? `NIC${idx}` })) const { handleRemove, handleSave } = useListForm({ parent: EXTRA_ID, key: TAB_ID, list: nics, setList: setFormData, - getItemId: (item) => item.NAME, + getItemId: (item) => item.NAME ?? `NIC${data.length + 1}`, addItemId: (item, id) => ({ ...item, NAME: id }) }) @@ -100,7 +100,7 @@ const Networking = ({ data, setFormData }) => { return ( {Object .entries({ RDP, SSH, ALIAS: PARENT, EXTERNAL }) diff --git a/src/fireedge/src/client/components/Forms/VmTemplate/InstantiateForm/index.js b/src/fireedge/src/client/components/Forms/VmTemplate/InstantiateForm/index.js index c2a619a5ed..f2046533c4 100644 --- a/src/fireedge/src/client/components/Forms/VmTemplate/InstantiateForm/index.js +++ b/src/fireedge/src/client/components/Forms/VmTemplate/InstantiateForm/index.js @@ -20,14 +20,14 @@ import PropTypes from 'prop-types' import { useForm, FormProvider } from 'react-hook-form' import { yupResolver } from '@hookform/resolvers/yup' -import { useUserApi, useVmGroupApi, useVmTemplateApi } from 'client/features/One' import { useFetch } from 'client/hooks' +import { useUserApi, useVmGroupApi, useVmTemplateApi } from 'client/features/One' import FormStepper, { SkeletonStepsForm } from 'client/components/FormStepper' import Steps from 'client/components/Forms/VmTemplate/InstantiateForm/Steps' const InstantiateForm = ({ template, onSubmit }) => { - const stepProps = useMemo(() => Steps(template, template), []) - const { steps, defaultValues, resolver, transformBeforeSubmit } = stepProps + const stepsForm = useMemo(() => Steps(template, template), []) + const { steps, defaultValues, resolver, transformBeforeSubmit } = stepsForm const methods = useForm({ mode: 'onSubmit', @@ -46,7 +46,7 @@ const InstantiateForm = ({ template, onSubmit }) => { ) } -const PreFetchingForm = ({ templateId, ...props }) => { +const PreFetchingForm = ({ templateId, onSubmit }) => { const { getUsers } = useUserApi() const { getVmGroups } = useVmGroupApi() const { getVmTemplate } = useVmTemplateApi() @@ -62,7 +62,7 @@ const PreFetchingForm = ({ templateId, ...props }) => { return (templateId && !data) ? - : + : } PreFetchingForm.propTypes = { diff --git a/src/fireedge/src/client/components/Tabs/Common/Ownership.js b/src/fireedge/src/client/components/Tabs/Common/Ownership.js index f1952ebb06..8a5c926be0 100644 --- a/src/fireedge/src/client/components/Tabs/Common/Ownership.js +++ b/src/fireedge/src/client/components/Tabs/Common/Ownership.js @@ -59,7 +59,7 @@ const Ownership = memo(({ link: PATH.SYSTEM.USERS.DETAIL.replace(':id', userId), canEdit: actions?.includes?.(ACTIONS.CHANGE_OWNER), handleGetOptionList: getUserOptions, - handleEdit: user => handleEdit?.({ user }) + handleEdit: (_, user) => handleEdit?.({ user }) }, { name: T.Group, @@ -68,7 +68,7 @@ const Ownership = memo(({ link: PATH.SYSTEM.GROUPS.DETAIL.replace(':id', groupId), canEdit: actions?.includes?.(ACTIONS.CHANGE_GROUP), handleGetOptionList: getGroupOptions, - handleEdit: group => handleEdit?.({ group }) + handleEdit: (_, group) => handleEdit?.({ group }) } ] diff --git a/src/fireedge/src/client/components/Tabs/Vm/Info/index.js b/src/fireedge/src/client/components/Tabs/Vm/Info/index.js index dc90e00626..85252be47e 100644 --- a/src/fireedge/src/client/components/Tabs/Vm/Info/index.js +++ b/src/fireedge/src/client/components/Tabs/Vm/Info/index.js @@ -58,7 +58,7 @@ const VmInfoTab = ({ tabProps = {} }) => { String(response) === String(ID) && await handleRefetch?.() } - const handleRename = async newName => { + const handleRename = async (_, newName) => { const response = await rename(ID, newName) String(response) === String(ID) && await handleRefetch?.() } diff --git a/src/fireedge/src/client/components/Tabs/VmTemplate/Info/index.js b/src/fireedge/src/client/components/Tabs/VmTemplate/Info/index.js index ed1abace16..232ec48554 100644 --- a/src/fireedge/src/client/components/Tabs/VmTemplate/Info/index.js +++ b/src/fireedge/src/client/components/Tabs/VmTemplate/Info/index.js @@ -44,7 +44,7 @@ const VmTemplateInfoTab = ({ tabProps = {} }) => { String(response) === String(ID) && await handleRefetch?.() } - const handleRename = async newName => { + const handleRename = async (_, newName) => { const response = await rename(ID, newName) String(response) === String(ID) && await handleRefetch?.() } diff --git a/src/fireedge/src/client/components/Tabs/VmTemplate/Info/information.js b/src/fireedge/src/client/components/Tabs/VmTemplate/Info/information.js index 223ce65e5e..8365cc2686 100644 --- a/src/fireedge/src/client/components/Tabs/VmTemplate/Info/information.js +++ b/src/fireedge/src/client/components/Tabs/VmTemplate/Info/information.js @@ -19,14 +19,19 @@ import PropTypes from 'prop-types' import { List } from 'client/components/Tabs/Common' import * as Helper from 'client/models/Helper' -import { T } from 'client/constants' +import { T, VM_TEMPLATE_ACTIONS } from 'client/constants' -const InformationPanel = ({ template = {} }) => { +const InformationPanel = ({ template = {}, handleRename, actions }) => { const { ID, NAME, REGTIME, LOCK } = template const info = [ { name: T.ID, value: ID }, - { name: T.Name, value: NAME }, + { + name: T.Name, + value: NAME, + canEdit: actions?.includes?.(VM_TEMPLATE_ACTIONS.RENAME), + handleEdit: handleRename + }, { name: T.StartTime, value: Helper.timeToString(REGTIME) @@ -45,6 +50,8 @@ const InformationPanel = ({ template = {} }) => { InformationPanel.displayName = 'InformationPanel' InformationPanel.propTypes = { + actions: PropTypes.arrayOf(PropTypes.string), + handleRename: PropTypes.func, template: PropTypes.object } diff --git a/src/fireedge/src/client/containers/Providers/Create.js b/src/fireedge/src/client/containers/Providers/Create.js index 56210fbf0d..f06e2141bb 100644 --- a/src/fireedge/src/client/containers/Providers/Create.js +++ b/src/fireedge/src/client/containers/Providers/Create.js @@ -14,50 +14,37 @@ * limitations under the License. * * ------------------------------------------------------------------------- */ /* eslint-disable jsdoc/require-jsdoc */ -import { useEffect, useState } from 'react' -import { Redirect, useParams, useHistory } from 'react-router' +import { useParams, useHistory } from 'react-router' +import { Container } from '@material-ui/core' -import { Container, LinearProgress } from '@material-ui/core' - -import { useFetchAll } from 'client/hooks' import { useAuth } from 'client/features/Auth' import { useGeneralApi } from 'client/features/General' import { useProviderApi } from 'client/features/One' import { CreateForm } from 'client/components/Forms/Provider' -import { isValidProviderTemplate, getConnectionEditable, getConnectionFixed } from 'client/models/ProviderTemplate' +import { isValidProviderTemplate } from 'client/models/ProviderTemplate' import { PATH } from 'client/apps/provision/routes' -import { isDevelopment, deepmerge } from 'client/utils' +import { isDevelopment } from 'client/utils' function ProviderCreateForm () { - const [initialValues, setInitialValues] = useState(null) const history = useHistory() const { id } = useParams() const { providerConfig } = useAuth() const { enqueueSuccess, enqueueError } = useGeneralApi() - const { getProvider, getProviderConnection, createProvider, updateProvider } = useProviderApi() - const { data: preloadedData, fetchRequestAll, loading, error } = useFetchAll() + const { createProvider, updateProvider } = useProviderApi() const onSubmit = async formData => { try { if (id !== undefined) { - const [provider = {}, connection = []] = preloadedData ?? [] - const providerId = provider?.ID - - const formatData = deepmerge({ connection }, formData) - - await updateProvider(id, formatData) - enqueueSuccess(`Provider updated - ID: ${providerId}`) + await updateProvider(id, formData) + enqueueSuccess(`Provider updated - ID: ${id}`) } else { if (!isValidProviderTemplate(formData, providerConfig)) { enqueueError('The template selected has a bad format. Ask your cloud administrator') history.push(PATH.PROVIDERS.LIST) } - const connectionFixed = getConnectionFixed(formData, providerConfig) - const formatData = deepmerge(formData, { connection: connectionFixed }) - - const responseId = await createProvider(formatData) + const responseId = await createProvider(formData) enqueueSuccess(`Provider created - ID: ${responseId}`) } @@ -67,51 +54,9 @@ function ProviderCreateForm () { } } - useEffect(() => { - const preloadFetchData = async () => { - const data = await fetchRequestAll([ - getProvider(id), - getProviderConnection(id) - ]) - - if (data) { - const [provider = {}, connection = []] = data - - const { - PLAIN: { provider: plainProvider } = {}, - // remove encrypted connection from body template - PROVISION_BODY: { description, connection: _, ...currentBodyTemplate } - } = provider?.TEMPLATE - - const connectionEditable = getConnectionEditable( - { provider: plainProvider, connection }, - providerConfig - ) - - setInitialValues({ - template: [currentBodyTemplate], - connection: connectionEditable, - configuration: { description } - }) - } - } - - id && preloadFetchData() - }, []) - - if (error) { - return - } - - return (id && !initialValues) || loading ? ( - - ) : ( + return ( - + ) } diff --git a/src/fireedge/src/client/features/Auth/provision.js b/src/fireedge/src/client/features/Auth/provision.js index 16c759aa19..26c3919dd4 100644 --- a/src/fireedge/src/client/features/Auth/provision.js +++ b/src/fireedge/src/client/features/Auth/provision.js @@ -30,8 +30,6 @@ export const getProviderConfig = createAsyncThunk( return { providerConfig: config } } catch (error) { - console.log({ error }) - error?.status === httpCodes.unauthorized.id && dispatch(logout(T.SessionExpired)) } diff --git a/src/fireedge/src/client/models/ProviderTemplate.js b/src/fireedge/src/client/models/ProviderTemplate.js index 53a41fd3c8..57ba8efe39 100644 --- a/src/fireedge/src/client/models/ProviderTemplate.js +++ b/src/fireedge/src/client/models/ProviderTemplate.js @@ -20,7 +20,6 @@ * @property {string} provider - Provider type * @property {object} plain - Information in plain format * @property {string} plain.provider - Provider type - * @property {string|string[]} plain.location_key - Location key/s * @property {object} connection - Connections * @property {Array} inputs - Inputs to provision form */