diff --git a/src/fireedge/src/client/components/Consoles/HeaderVmInfo.js b/src/fireedge/src/client/components/Consoles/HeaderVmInfo.js
index 68914030ba..7ffe309c61 100644
--- a/src/fireedge/src/client/components/Consoles/HeaderVmInfo.js
+++ b/src/fireedge/src/client/components/Consoles/HeaderVmInfo.js
@@ -40,7 +40,7 @@ const HeaderVmInfo = ({ id, type }) => {
const { push: redirectTo } = useHistory()
const { enqueueError } = useGeneralApi()
- const { data: vm, isSuccess, isLoading, isError } = useGetVmQuery(id)
+ const { data: vm, isSuccess, isLoading, isError } = useGetVmQuery({ id })
const [getService, { data: serviceFlow }] = useLazyGetServiceQuery()
const ips = getIps(vm)
diff --git a/src/fireedge/src/client/components/Tables/VmTemplates/actions.js b/src/fireedge/src/client/components/Tables/VmTemplates/actions.js
index 73eb632150..206d27683c 100644
--- a/src/fireedge/src/client/components/Tables/VmTemplates/actions.js
+++ b/src/fireedge/src/client/components/Tables/VmTemplates/actions.js
@@ -13,9 +13,9 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
-/* eslint-disable jsdoc/require-jsdoc */
import { useMemo } from 'react'
import { useHistory } from 'react-router-dom'
+import { Typography } from '@mui/material'
import {
AddSquare,
Import,
@@ -32,40 +32,64 @@ import {
useUnlockTemplateMutation,
useCloneTemplateMutation,
useRemoveTemplateMutation,
+ useChangeTemplateOwnershipMutation,
+ useChangeTemplatePermissionsMutation,
} from 'client/features/OneApi/vmTemplate'
-import { Tr, Translate } from 'client/components/HOC'
+import { ChangeUserForm, ChangeGroupForm } from 'client/components/Forms/Vm'
import { CloneForm } from 'client/components/Forms/VmTemplate'
-import { createActions } from 'client/components/Tables/Enhanced/Utils'
-import { PATH } from 'client/apps/sunstone/routesOne'
+import {
+ createActions,
+ GlobalAction,
+} from 'client/components/Tables/Enhanced/Utils'
+import { Tr, Translate } from 'client/components/HOC'
+import { PATH } from 'client/apps/sunstone/routesOne'
import { T, VM_TEMPLATE_ACTIONS, RESOURCE_NAMES } from 'client/constants'
-const MessageToConfirmAction = (rows) => {
- const names = rows?.map?.(({ original }) => original?.NAME)
+const ListVmTemplateNames = ({ rows = [] }) =>
+ rows?.map?.(({ id, original }) => {
+ const { ID, NAME } = original
- return (
- <>
-
-
- {`: ${names.join(', ')}`}
-
-
-
-
- >
- )
-}
+ return (
+
+ {`#${ID} ${NAME}`}
+
+ )
+ })
+
+const SubHeader = (rows) =>
+
+const MessageToConfirmAction = (rows, description) => (
+ <>
+
+ {description && }
+
+ >
+)
MessageToConfirmAction.displayName = 'MessageToConfirmAction'
+/**
+ * Generates the actions to operate resources on VM Template table.
+ *
+ * @returns {GlobalAction} - Actions
+ */
const Actions = () => {
const history = useHistory()
const { view, getResourceView } = useViews()
+
const [lock] = useLockTemplateMutation()
const [unlock] = useUnlockTemplateMutation()
const [clone] = useCloneTemplateMutation()
const [remove] = useRemoveTemplateMutation()
+ const [changeOwnership] = useChangeTemplateOwnershipMutation()
+ const [changePermissions] = useChangeTemplatePermissionsMutation()
return useMemo(
() =>
@@ -183,30 +207,72 @@ const Actions = () => {
{
accessor: VM_TEMPLATE_ACTIONS.CHANGE_OWNER,
name: T.ChangeOwner,
- disabled: true,
- isConfirmDialog: true,
- onSubmit: () => undefined,
+ dialogProps: {
+ title: T.ChangeOwner,
+ subheader: SubHeader,
+ dataCy: `modal-${VM_TEMPLATE_ACTIONS.CHANGE_OWNER}`,
+ },
+ form: ChangeUserForm,
+ onSubmit: (rows) => (newOwnership) => {
+ rows?.map?.(({ original }) =>
+ changeOwnership({ id: original?.ID, ...newOwnership })
+ )
+ },
+ // onSubmit: (rows) => async (newOwnership) => {
+ // const ids = rows?.map?.(({ original }) => original?.ID)
+ // await Promise.all(
+ // ids.map((id) => changeOwnership({ id, ...newOwnership }))
+ // )
+ // },
},
{
accessor: VM_TEMPLATE_ACTIONS.CHANGE_GROUP,
name: T.ChangeGroup,
- disabled: true,
- isConfirmDialog: true,
- onSubmit: () => undefined,
+ dialogProps: {
+ title: T.ChangeGroup,
+ subheader: SubHeader,
+ dataCy: `modal-${VM_TEMPLATE_ACTIONS.CHANGE_GROUP}`,
+ },
+ form: ChangeGroupForm,
+ onSubmit: (rows) => async (newOwnership) => {
+ const ids = rows?.map?.(({ original }) => original?.ID)
+ await Promise.all(
+ ids.map((id) => changeOwnership({ id, ...newOwnership }))
+ )
+ },
},
{
accessor: VM_TEMPLATE_ACTIONS.SHARE,
- disabled: true,
name: T.Share,
isConfirmDialog: true,
- onSubmit: () => undefined,
+ dialogProps: {
+ title: T.Share,
+ children: (rows) =>
+ MessageToConfirmAction(rows, T.ShareVmTemplateDescription),
+ },
+ onSubmit: (rows) => () => {
+ rows?.map?.(({ original }) =>
+ changePermissions({ id: original?.ID, groupUse: '1' })
+ )
+ },
},
{
accessor: VM_TEMPLATE_ACTIONS.UNSHARE,
- disabled: true,
name: T.Unshare,
isConfirmDialog: true,
- onSubmit: () => undefined,
+ dialogProps: {
+ title: T.Unshare,
+ children: (rows) =>
+ MessageToConfirmAction(
+ rows,
+ T.UnshareVmTemplateDescription
+ ),
+ },
+ onSubmit: (rows) => () => {
+ rows?.map?.(({ original }) =>
+ changePermissions({ id: original?.ID, groupUse: '0' })
+ )
+ },
},
],
},
@@ -239,7 +305,7 @@ const Actions = () => {
},
onSubmit: (rows) => async () => {
const ids = rows?.map?.(({ original }) => original?.ID)
- await Promise.all(ids.map((id) => unlock(id)))
+ await Promise.all(ids.map((id) => unlock({ id })))
},
},
],
diff --git a/src/fireedge/src/client/components/Tables/Vms/actions.js b/src/fireedge/src/client/components/Tables/Vms/actions.js
index 1a4cacec58..53f13474b1 100644
--- a/src/fireedge/src/client/components/Tables/Vms/actions.js
+++ b/src/fireedge/src/client/components/Tables/Vms/actions.js
@@ -582,7 +582,7 @@ const Actions = () => {
},
onSubmit: (rows) => async () => {
const ids = rows?.map?.(({ original }) => original?.ID)
- await Promise.all(ids.map((id) => unlock(id)))
+ await Promise.all(ids.map((id) => unlock({ id })))
},
},
],
diff --git a/src/fireedge/src/client/components/Tabs/Vm/Capacity/index.js b/src/fireedge/src/client/components/Tabs/Vm/Capacity/index.js
index 4f80552322..1913db4f19 100644
--- a/src/fireedge/src/client/components/Tabs/Vm/Capacity/index.js
+++ b/src/fireedge/src/client/components/Tabs/Vm/Capacity/index.js
@@ -33,7 +33,7 @@ import { getActionsAvailable, jsonToXml } from 'client/models/Helper'
*/
const VmCapacityTab = ({ tabProps: { actions } = {}, id }) => {
const [resizeCapacity] = useResizeMutation()
- const { data: vm = {} } = useGetVmQuery(id)
+ const { data: vm = {} } = useGetVmQuery({ id })
const actionsAvailable = useMemo(() => {
const hypervisor = getHypervisor(vm)
diff --git a/src/fireedge/src/client/components/Tabs/Vm/Configuration.js b/src/fireedge/src/client/components/Tabs/Vm/Configuration.js
index 6f2667afa5..b5feedf5d3 100644
--- a/src/fireedge/src/client/components/Tabs/Vm/Configuration.js
+++ b/src/fireedge/src/client/components/Tabs/Vm/Configuration.js
@@ -30,7 +30,7 @@ import { T } from 'client/constants'
* @returns {ReactElement} Configuration tab
*/
const VmConfigurationTab = ({ id }) => {
- const { data: vm = {} } = useGetVmQuery(id)
+ const { data: vm = {} } = useGetVmQuery({ id })
const { TEMPLATE, USER_TEMPLATE } = vm
return (
diff --git a/src/fireedge/src/client/components/Tabs/Vm/History/index.js b/src/fireedge/src/client/components/Tabs/Vm/History/index.js
index 7091988cb2..f9a16bf648 100644
--- a/src/fireedge/src/client/components/Tabs/Vm/History/index.js
+++ b/src/fireedge/src/client/components/Tabs/Vm/History/index.js
@@ -36,7 +36,7 @@ import { getActionsAvailable } from 'client/models/Helper'
* @returns {ReactElement} History tab
*/
const VmHistoryTab = ({ tabProps: { actions } = {}, id }) => {
- const { data: vm = {} } = useGetVmQuery(id)
+ const { data: vm = {} } = useGetVmQuery({ id })
const [records, actionsAvailable] = useMemo(() => {
const hypervisor = getHypervisor(vm)
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 f2d0fe7dc8..446b6c0421 100644
--- a/src/fireedge/src/client/components/Tabs/Vm/Info/index.js
+++ b/src/fireedge/src/client/components/Tabs/Vm/Info/index.js
@@ -67,7 +67,7 @@ const VmInfoTab = ({ tabProps = {}, id }) => {
attributes_panel: attributesPanel,
} = tabProps
- const { data: vm = {} } = useGetVmQuery(id)
+ const { data: vm = {} } = useGetVmQuery({ id })
const [changeVmOwnership] = useChangeVmOwnershipMutation()
const [changeVmPermissions] = useChangeVmPermissionsMutation()
const [updateUserTemplate] = useUpdateUserTemplateMutation()
diff --git a/src/fireedge/src/client/components/Tabs/Vm/Network/index.js b/src/fireedge/src/client/components/Tabs/Vm/Network/index.js
index 5f5e432c09..3acaa7bf70 100644
--- a/src/fireedge/src/client/components/Tabs/Vm/Network/index.js
+++ b/src/fireedge/src/client/components/Tabs/Vm/Network/index.js
@@ -47,7 +47,7 @@ const { ATTACH_NIC, DETACH_NIC, ATTACH_SEC_GROUP, DETACH_SEC_GROUP } =
* @returns {ReactElement} Networks tab
*/
const VmNetworkTab = ({ tabProps: { actions } = {}, id }) => {
- const { data: vm } = useGetVmQuery(id)
+ const { data: vm } = useGetVmQuery({ id })
const [nics, hypervisor, actionsAvailable] = useMemo(() => {
const groupedNics = getNics(vm, {
diff --git a/src/fireedge/src/client/components/Tabs/Vm/SchedActions.js b/src/fireedge/src/client/components/Tabs/Vm/SchedActions.js
index 99e1ddbab2..893446ddc0 100644
--- a/src/fireedge/src/client/components/Tabs/Vm/SchedActions.js
+++ b/src/fireedge/src/client/components/Tabs/Vm/SchedActions.js
@@ -59,7 +59,7 @@ const VmSchedulingTab = ({ tabProps: { actions } = {}, id }) => {
const [addScheduledAction] = useAddScheduledActionMutation()
const [updateScheduledAction] = useUpdateScheduledActionMutation()
const [deleteScheduledAction] = useDeleteScheduledActionMutation()
- const { data: vm = {} } = useGetVmQuery(id)
+ const { data: vm = {} } = useGetVmQuery({ id })
const [scheduling, actionsAvailable] = useMemo(() => {
const hypervisor = getHypervisor(vm)
diff --git a/src/fireedge/src/client/components/Tabs/Vm/Snapshot/index.js b/src/fireedge/src/client/components/Tabs/Vm/Snapshot/index.js
index 4e97f0d9f2..539f71ca5c 100644
--- a/src/fireedge/src/client/components/Tabs/Vm/Snapshot/index.js
+++ b/src/fireedge/src/client/components/Tabs/Vm/Snapshot/index.js
@@ -45,7 +45,7 @@ const { SNAPSHOT_CREATE, SNAPSHOT_REVERT, SNAPSHOT_DELETE } = VM_ACTIONS
* @returns {ReactElement} Snapshots tab
*/
const VmSnapshotTab = ({ tabProps: { actions } = {}, id }) => {
- const { data: vm = {} } = useGetVmQuery(id)
+ const { data: vm = {} } = useGetVmQuery({ id })
const [snapshots, actionsAvailable] = useMemo(() => {
const hypervisor = getHypervisor(vm)
diff --git a/src/fireedge/src/client/components/Tabs/Vm/Storage/index.js b/src/fireedge/src/client/components/Tabs/Vm/Storage/index.js
index 949de22cb7..a2fe7aace0 100644
--- a/src/fireedge/src/client/components/Tabs/Vm/Storage/index.js
+++ b/src/fireedge/src/client/components/Tabs/Vm/Storage/index.js
@@ -60,7 +60,7 @@ const {
* @returns {ReactElement} Storage tab
*/
const VmStorageTab = ({ tabProps: { actions } = {}, id }) => {
- const { data: vm = {} } = useGetVmQuery(id)
+ const { data: vm = {} } = useGetVmQuery({ id })
const [disks, hypervisor, actionsAvailable] = useMemo(() => {
const hyperV = getHypervisor(vm)
diff --git a/src/fireedge/src/client/components/Tabs/Vm/index.js b/src/fireedge/src/client/components/Tabs/Vm/index.js
index b27aca9823..f7f3458611 100644
--- a/src/fireedge/src/client/components/Tabs/Vm/index.js
+++ b/src/fireedge/src/client/components/Tabs/Vm/index.js
@@ -46,9 +46,10 @@ const getTabComponent = (tabName) =>
const VmTabs = memo(({ id }) => {
const { view, getResourceView } = useViews()
- const { isLoading, isError, error } = useGetVmQuery(id, {
- refetchOnMountOrArgChange: 10,
- })
+ const { isLoading, isError, error } = useGetVmQuery(
+ { id },
+ { refetchOnMountOrArgChange: 10 }
+ )
const tabsAvailable = useMemo(() => {
const resource = RESOURCE_NAMES.VM
diff --git a/src/fireedge/src/client/components/Tabs/index.js b/src/fireedge/src/client/components/Tabs/index.js
index 64bfccda4a..f30c4bc751 100644
--- a/src/fireedge/src/client/components/Tabs/index.js
+++ b/src/fireedge/src/client/components/Tabs/index.js
@@ -53,7 +53,7 @@ const Content = ({
key={`tab-${id ?? name}`}
data-cy={`tab-content-${id ?? name}`}
hidden={hidden}
- border={addBorder}
+ border={addBorder ? 'true' : undefined}
>
diff --git a/src/fireedge/src/client/constants/translates.js b/src/fireedge/src/client/constants/translates.js
index 5f91e94ca1..09b8047cd0 100644
--- a/src/fireedge/src/client/constants/translates.js
+++ b/src/fireedge/src/client/constants/translates.js
@@ -741,6 +741,12 @@ module.exports = {
CloneWithImagesConcept: `
You can also clone any Image referenced inside this Template.
They will be cloned to a new Image, and made persistent`,
+ ShareVmTemplateDescription: `
+ The VM Template(s), along with any image referenced by it, will
+ be shared with the group's users. Permission changed: GROUP USE`,
+ UnshareVmTemplateDescription: `
+ The VM Template(s), along with any image referenced by it, will
+ be unshared with the group's users. Permission changed: GROUP USE`,
/* Virtual Network schema - network */
IP: 'IP',
diff --git a/src/fireedge/src/client/features/OneApi/common.js b/src/fireedge/src/client/features/OneApi/common.js
new file mode 100644
index 0000000000..4ff6fd9213
--- /dev/null
+++ b/src/fireedge/src/client/features/OneApi/common.js
@@ -0,0 +1,257 @@
+/* ------------------------------------------------------------------------- *
+ * Copyright 2002-2022, OpenNebula Project, OpenNebula Systems *
+ * *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may *
+ * not use this file except in compliance with the License. You may obtain *
+ * a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, software *
+ * distributed under the License is distributed on an "AS IS" BASIS, *
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
+ * See the License for the specific language governing permissions and *
+ * limitations under the License. *
+ * ------------------------------------------------------------------------- */
+import { Draft, ThunkAction } from '@reduxjs/toolkit'
+
+import userApi from 'client/features/OneApi/user'
+import groupApi from 'client/features/OneApi/group'
+import { LockLevel, Permission, User, Group } from 'client/constants'
+import { xmlToJson } from 'client/models/Helper'
+
+/**
+ * Update the pool of resources with the new data.
+ *
+ * @param {string} params - The parameters from query
+ * @param {string} [params.id] - The id of the resource
+ * @param {string} [params.resourceFromQuery] - The resource from query (user, group, ...)
+ * @returns {function(Draft):ThunkAction} - Dispatches the action
+ */
+export const updateResourceOnPool =
+ ({ id: resourceId, resourceFromQuery }) =>
+ (draft) => {
+ if (resourceId !== undefined && Array.isArray(draft)) return
+
+ const index = draft.findIndex(({ ID }) => +ID === +resourceId)
+ index !== -1 && (draft[index] = resourceFromQuery)
+ }
+
+/**
+ * Remove the resource from the pool.
+ *
+ * @param {string} params - The parameters from query
+ * @param {string} [params.id] - The id of the resource
+ * @returns {function(Draft):ThunkAction} - Dispatches the action
+ */
+export const removeResourceOnPool =
+ ({ id: resourceId }) =>
+ (draft) => {
+ if (resourceId !== undefined && Array.isArray(draft)) return
+
+ draft.filter(({ ID }) => +ID !== +resourceId)
+ }
+
+/**
+ * Update the name of a resource in the store.
+ *
+ * @param {string} params - The parameters from query
+ * @param {string} [params.id] - The id of the resource
+ * @param {string} [params.name] - The name of the resource
+ * @returns {function(Draft):ThunkAction} - Dispatches the action
+ */
+export const updateNameOnResource =
+ ({ id: resourceId, name: newName }) =>
+ (draft) => {
+ const updatePool = resourceId !== undefined && Array.isArray(draft)
+
+ const resource = updatePool
+ ? draft.find(({ ID }) => +ID === +resourceId)
+ : draft
+
+ if ((updatePool && !resource) || newName !== undefined) return
+
+ resource.NAME = newName
+ }
+
+/**
+ * Update the lock level of a resource in the store.
+ *
+ * @param {string} params - The parameters from query
+ * @param {string} [params.id] - The id of the resource
+ * @param {LockLevel} [params.level] - The new lock level
+ * @returns {function(Draft):ThunkAction} - Dispatches the action
+ */
+export const updateLockLevelOnResource =
+ ({ id: resourceId, level = '4' }) =>
+ (draft) => {
+ const updatePool = resourceId !== undefined && Array.isArray(draft)
+
+ const resource = updatePool
+ ? draft.find(({ ID }) => +ID === +resourceId)
+ : draft
+
+ if (updatePool && !resource) return
+
+ resource.LOCK = { LOCKED: level }
+ }
+
+/**
+ * Update to unlock a resource in the store.
+ *
+ * @param {string} params - The parameters from query
+ * @param {string} [params.id] - The id of the resource
+ * @param {string} [params.level] - The new lock level
+ * @returns {function(Draft):ThunkAction} - Dispatches the action
+ */
+export const removeLockLevelOnResource =
+ ({ id: resourceId }) =>
+ (draft) => {
+ const updatePool = resourceId !== undefined && Array.isArray(draft)
+
+ const resource = updatePool
+ ? draft.find(({ ID }) => +ID === +resourceId)
+ : draft
+
+ if (updatePool && !resource) return
+
+ resource.LOCK = undefined
+ }
+
+/**
+ * Update the permissions of a resource in the store.
+ *
+ * @param {object} params - Request parameters
+ * @param {string} params.id - The id of the resource
+ * @param {Permission|'-1'} params.ownerUse - User use
+ * @param {Permission|'-1'} params.ownerManage - User manage
+ * @param {Permission|'-1'} params.ownerAdmin - User administrator
+ * @param {Permission|'-1'} params.groupUse - Group use
+ * @param {Permission|'-1'} params.groupManage - Group manage
+ * @param {Permission|'-1'} params.groupAdmin - Group administrator
+ * @param {Permission|'-1'} params.otherUse - Other use
+ * @param {Permission|'-1'} params.otherManage - Other manage
+ * @param {Permission|'-1'} params.otherAdmin - Other administrator
+ * @returns {function(Draft):ThunkAction} - Dispatches the action
+ */
+export const updatePermissionOnResource =
+ ({ id: resourceId, ...permissions }) =>
+ (draft) => {
+ const updatePool = resourceId !== undefined && Array.isArray(draft)
+
+ const resource = updatePool
+ ? draft.find(({ ID }) => +ID === +resourceId)
+ : draft
+
+ if (updatePool && !resource) return
+
+ Object.entries(permissions)
+ .filter(([_, value]) => value !== '-1')
+ .forEach(([name, value]) => {
+ const ensuredName = {
+ ownerUse: 'OWNER_U',
+ ownerManage: 'OWNER_M',
+ ownerAdmin: 'OWNER_A',
+ groupUse: 'GROUP_U',
+ groupManage: 'GROUP_M',
+ groupAdmin: 'GROUP_A',
+ otherUse: 'OTHER_U',
+ otherManage: 'OTHER_M',
+ otherAdmin: 'OTHER_A',
+ }[name]
+
+ resource.PERMISSIONS[ensuredName] = value
+ })
+ }
+
+/**
+ * Select the users and groups from the current state.
+ * - If `options.userId` is provided, only the user with the given id will be selected.
+ * - If `options.groupId` is provided, only the group with the given id will be selected.
+ *
+ * @param {object} state - The current state
+ * @param {string} options - The options to filter the users and groups
+ * @param {string} options.userId - The user id
+ * @param {string} options.groupId - The group id
+ * @returns {
+ * { users: User[], groups: Group[] } | { user: User, group: Group }
+ * } - The users and groups or the user and group by id
+ */
+export const selectOwnershipFromState = (state, { userId, groupId } = {}) => {
+ const { data: users } = userApi.endpoints.getUsers.select()(state)
+ const { data: groups } = groupApi.endpoints.getGroups.select()(state)
+
+ if (!userId && !groupId) return { users, groups }
+
+ const user = users.find(({ ID }) => +ID === +userId)
+ const group = groups.find(({ ID }) => +ID === +groupId)
+
+ return { user, group }
+}
+
+/**
+ * Update the ownership of a resource in the store.
+ *
+ * @param {object} state - The current state
+ * @param {string} [params] - The parameters from query
+ * @param {string} [params.id] - The id of the resource
+ * @param {string} [params.user] - The user id to update
+ * @param {string} [params.group] - The group id to update
+ * @returns {function(Draft):ThunkAction} - Dispatches the action
+ */
+export const updateOwnershipOnResource = (
+ state,
+ { id: resourceId, user: userId, group: groupId } = {}
+) => {
+ const { user, group } = selectOwnershipFromState(state, { userId, groupId })
+
+ return (draft) => {
+ const updatePool = resourceId !== undefined && Array.isArray(draft)
+
+ const resource = updatePool
+ ? draft.find(({ ID }) => +ID === +resourceId)
+ : draft
+
+ if (updatePool && !resource) return
+
+ user?.ID > -1 && (resource.UID = user.ID)
+ user?.NAME !== undefined && (resource.UNAME = user.NAME)
+
+ group?.ID > -1 && (resource.GID = group.ID)
+ group?.NAME !== undefined && (resource.GNAME = group.NAME)
+ }
+}
+
+/**
+ * Update the template or user template of a resource in the store.
+ *
+ * @param {object} params - Request params
+ * @param {number|string} params.id - The id of the resource
+ * @param {string} params.template - The new user template contents on XML format
+ * @param {0|1} params.replace
+ * - Update type:
+ * ``0``: Replace the whole template.
+ * ``1``: Merge new template with the existing one.
+ * @param {string} [userTemplateAttribute] - The attribute name of the user template. By default is `USER_TEMPLATE`.
+ * @returns {function(Draft):ThunkAction} - Dispatches the action
+ */
+export const updateUserTemplateOnResource =
+ (
+ { id: resourceId, template: xml, replace = 0 },
+ userTemplateAttribute = 'USER_TEMPLATE'
+ ) =>
+ (draft) => {
+ const updatePool = resourceId !== undefined && Array.isArray(draft)
+ const newTemplateJson = xmlToJson(xml)
+
+ const resource = updatePool
+ ? draft.find(({ ID }) => +ID === +resourceId)
+ : draft
+
+ if (updatePool && !resource) return
+
+ resource[userTemplateAttribute] =
+ +replace === 0
+ ? newTemplateJson
+ : { ...resource[userTemplateAttribute], ...newTemplateJson }
+ }
diff --git a/src/fireedge/src/client/features/OneApi/socket.js b/src/fireedge/src/client/features/OneApi/socket.js
index 5740d7d9ff..ac3cdc5b9e 100644
--- a/src/fireedge/src/client/features/OneApi/socket.js
+++ b/src/fireedge/src/client/features/OneApi/socket.js
@@ -80,7 +80,7 @@ const getResourceFromEventState = (data) => {
const UpdateFromSocket =
({ updateQueryData, resource }) =>
async (
- id,
+ { id },
{ cacheEntryRemoved, cacheDataLoaded, updateCachedData, getState, dispatch }
) => {
const { zone } = getState().general
diff --git a/src/fireedge/src/client/features/OneApi/vm.js b/src/fireedge/src/client/features/OneApi/vm.js
index ab226b0fec..b14881b36a 100644
--- a/src/fireedge/src/client/features/OneApi/vm.js
+++ b/src/fireedge/src/client/features/OneApi/vm.js
@@ -18,15 +18,25 @@ import {
Actions as ExtraActions,
Commands as ExtraCommands,
} from 'server/routes/api/vm/routes'
+
import {
oneApi,
ONE_RESOURCES,
ONE_RESOURCES_POOL,
} from 'client/features/OneApi'
+import {
+ updateResourceOnPool,
+ removeResourceOnPool,
+ updateNameOnResource,
+ updateLockLevelOnResource,
+ removeLockLevelOnResource,
+ updatePermissionOnResource,
+ updateOwnershipOnResource,
+ updateUserTemplateOnResource,
+} from 'client/features/OneApi/common'
import { actions as guacamoleActions } from 'client/features/Guacamole/slice'
import { UpdateFromSocket } from 'client/features/OneApi/socket'
import http from 'client/utils/rest'
-import { xmlToJson } from 'client/models/Helper'
import {
LockLevel,
FilterFlag,
@@ -44,7 +54,7 @@ const vmApi = oneApi.injectEndpoints({
* Retrieves information for all or part of
* the VMs in the pool.
*
- * @param {object} params - Request params
+ * @param {object} params - Request parameters
* @param {boolean} params.extended - Retrieves information for all or part
* @param {FilterFlag} [params.filter] - Filter flag
* @param {number} [params.start] - Range start ID
@@ -85,32 +95,37 @@ const vmApi = oneApi.injectEndpoints({
/**
* Retrieves information for the virtual machine.
*
- * @param {string} id - VM id
+ * @param {object} params - Request parameters
+ * @param {string} params.id - VM id
* @returns {VmType} Get VM identified by id
* @throws Fails when response isn't code 200
*/
- query: (id) => {
+ query: (params) => {
const name = Actions.VM_INFO
const command = { name, ...Commands[name] }
- return { params: { id }, command }
+ return { params, command }
},
transformResponse: (data) => data?.VM ?? {},
providesTags: (_, __, id) => [{ type: VM, id }],
async onQueryStarted(id, { dispatch, queryFulfilled }) {
try {
- const { data: queryVm } = await queryFulfilled
+ const { data: resourceFromQuery } = await queryFulfilled
dispatch(
- vmApi.util.updateQueryData('getVms', undefined, (draft) => {
- const index = draft.findIndex(({ ID }) => +ID === +id)
- index !== -1 && (draft[index] = queryVm)
- })
+ vmApi.util.updateQueryData(
+ 'getVms',
+ undefined,
+ updateResourceOnPool({ id, resourceFromQuery })
+ )
)
} catch {
+ // if the query fails, we want to remove the resource from the pool
dispatch(
- vmApi.util.updateQueryData('getVms', undefined, (draft) =>
- draft.filter(({ ID }) => +ID !== +id)
+ vmApi.util.updateQueryData(
+ 'getVms',
+ undefined,
+ removeResourceOnPool({ id })
)
)
}
@@ -590,7 +605,7 @@ const vmApi = oneApi.injectEndpoints({
* If set any permission to -1, it's not changed.
*
* @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
+ * @param {string} params.id - Virtual machine id
* @param {Permission|'-1'} params.ownerUse - User use
* @param {Permission|'-1'} params.ownerManage - User manage
* @param {Permission|'-1'} params.ownerAdmin - User administrator
@@ -610,33 +625,18 @@ const vmApi = oneApi.injectEndpoints({
return { params, command }
},
invalidatesTags: (_, __, { id }) => [{ type: VM, id }],
- async onQueryStarted(
- { id, ...permissions },
- { dispatch, queryFulfilled }
- ) {
- const patchResult = dispatch(
- vmApi.util.updateQueryData('getVm', id, (draft) => {
- Object.entries(permissions)
- .filter(([_, value]) => value !== '-1')
- .forEach(([name, value]) => {
- const ensuredName = {
- ownerUse: 'OWNER_U',
- ownerManage: 'OWNER_M',
- ownerAdmin: 'OWNER_A',
- groupUse: 'GROUP_U',
- groupManage: 'GROUP_M',
- groupAdmin: 'GROUP_A',
- otherUse: 'OTHER_U',
- otherManage: 'OTHER_M',
- otherAdmin: 'OTHER_A',
- }[name]
+ async onQueryStarted(params, { dispatch, queryFulfilled }) {
+ try {
+ const patchVm = dispatch(
+ vmApi.util.updateQueryData(
+ 'getVm',
+ { id: params.id },
+ updatePermissionOnResource(params)
+ )
+ )
- draft.PERMISSIONS[ensuredName] = value
- })
- })
- )
-
- queryFulfilled.catch(patchResult.undo)
+ queryFulfilled.catch(patchVm.undo)
+ } catch {}
},
}),
changeVmOwnership: builder.mutation({
@@ -644,7 +644,7 @@ const vmApi = oneApi.injectEndpoints({
* Changes the ownership bits of a virtual machine.
*
* @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
+ * @param {string} params.id - Virtual machine id
* @param {number} params.user - The user id
* @param {number} params.group - The group id
* @returns {number} Virtual machine id
@@ -657,13 +657,26 @@ const vmApi = oneApi.injectEndpoints({
return { params, command }
},
invalidatesTags: (_, __, { id }) => [{ type: VM, id }],
+ async onQueryStarted(params, { getState, dispatch, queryFulfilled }) {
+ try {
+ const patchVm = dispatch(
+ vmApi.util.updateQueryData(
+ 'getVm',
+ { id: params.id },
+ updateOwnershipOnResource(getState(), params)
+ )
+ )
+
+ queryFulfilled.catch(patchVm.undo())
+ } catch {}
+ },
}),
renameVm: builder.mutation({
/**
* Renames a virtual machine.
*
* @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
+ * @param {string} params.id - Virtual machine id
* @param {string} params.name - The new name
* @returns {number} Virtual machine id
* @throws Fails when response isn't code 200
@@ -675,16 +688,28 @@ const vmApi = oneApi.injectEndpoints({
return { params, command }
},
invalidatesTags: (_, __, { id }) => [{ type: VM, id }],
- async onQueryStarted({ id, name }, { dispatch, queryFulfilled }) {
+ async onQueryStarted(params, { dispatch, queryFulfilled }) {
try {
- await queryFulfilled
-
- dispatch(
- vmApi.util.updateQueryData('getVms', undefined, (draft) => {
- const vm = draft.find(({ ID }) => +ID === +id)
- vm && (vm.NAME = name)
- })
+ const patchVm = dispatch(
+ vmApi.util.updateQueryData(
+ 'getVm',
+ { id: params.id },
+ updateNameOnResource(params)
+ )
)
+
+ const patchVms = dispatch(
+ vmApi.util.updateQueryData(
+ 'getVms',
+ undefined,
+ updateNameOnResource(params)
+ )
+ )
+
+ queryFulfilled.catch(() => {
+ patchVm.undo()
+ patchVms.undo()
+ })
} catch {}
},
}),
@@ -693,7 +718,7 @@ const vmApi = oneApi.injectEndpoints({
* Creates a new virtual machine snapshot.
*
* @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
+ * @param {string} params.id - Virtual machine id
* @param {string} params.name - The new snapshot name
* @returns {number} Virtual machine id
* @throws Fails when response isn't code 200
@@ -711,8 +736,8 @@ const vmApi = oneApi.injectEndpoints({
* Reverts a virtual machine to a snapshot.
*
* @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
- * @param {string|number} params.snapshot - The snapshot id
+ * @param {string} params.id - Virtual machine id
+ * @param {string} params.snapshot - The snapshot id
* @returns {number} Virtual machine id
* @throws Fails when response isn't code 200
*/
@@ -729,8 +754,8 @@ const vmApi = oneApi.injectEndpoints({
* Deletes a virtual machine snapshot.
*
* @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
- * @param {string|number} params.snapshot - The snapshot id
+ * @param {string} params.id - Virtual machine id
+ * @param {string} params.snapshot - The snapshot id
* @returns {number} Virtual machine id
* @throws Fails when response isn't code 200
*/
@@ -747,7 +772,7 @@ const vmApi = oneApi.injectEndpoints({
* Changes the capacity of the virtual machine.
*
* @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
+ * @param {string} params.id - Virtual machine id
* @param {string} params.template - Template containing the new capacity
* @param {boolean} params.enforce - `true` to enforce the Host capacity isn't over committed
* @returns {number} Virtual machine id
@@ -766,7 +791,7 @@ const vmApi = oneApi.injectEndpoints({
* Replaces the user template contents.
*
* @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
+ * @param {string} params.id - Virtual machine id
* @param {string} params.template - The new user template contents on syntax XML
* @param {0|1} params.replace
* - Update type:
@@ -782,33 +807,22 @@ const vmApi = oneApi.injectEndpoints({
return { params, command }
},
invalidatesTags: (_, __, { id }) => [{ type: VM, id }],
- async onQueryStarted(
- { id, template: xml, replace = 0 },
- { dispatch, queryFulfilled }
- ) {
+ async onQueryStarted(params, { dispatch, queryFulfilled }) {
try {
- // update user template by id
const patchVm = dispatch(
- vmApi.util.updateQueryData('getVm', id, (draft) => {
- draft.USER_TEMPLATE =
- +replace === 0
- ? xmlToJson(xml)
- : { ...draft.USER_TEMPLATE, ...xmlToJson(xml) }
- })
+ vmApi.util.updateQueryData(
+ 'getVm',
+ { id: params.id },
+ updateUserTemplateOnResource(params)
+ )
)
- // update user template on pool by id (if exists)
const patchVms = dispatch(
- vmApi.util.updateQueryData('getVms', undefined, (draft) => {
- const vm = draft.find(({ ID }) => +ID === +id)
-
- if (!vm) return
-
- vm.USER_TEMPLATE =
- +replace === 0
- ? xmlToJson(xml)
- : { ...vm.USER_TEMPLATE, ...xmlToJson(xml) }
- })
+ vmApi.util.updateQueryData(
+ 'getVms',
+ undefined,
+ updateUserTemplateOnResource(params)
+ )
)
queryFulfilled.catch(() => {
@@ -823,7 +837,7 @@ const vmApi = oneApi.injectEndpoints({
* Updates (appends) a set of supported configuration attributes in the VM template.
*
* @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
+ * @param {string} params.id - Virtual machine id
* @param {string} params.template - The new configuration contents on syntax XML
* @returns {number} Virtual machine id
* @throws Fails when response isn't code 200
@@ -845,7 +859,7 @@ const vmApi = oneApi.injectEndpoints({
* if the operation was successful or not.
*
* @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
+ * @param {string} params.id - Virtual machine id
* @param {0|1|2|3|4} params.operation - Recover operation:
* failure (0), success (1), retry (2), delete (3), delete-recreate (4)
* @returns {number} Virtual machine id
@@ -864,7 +878,7 @@ const vmApi = oneApi.injectEndpoints({
* Locks a Virtual Machine. Lock certain actions depending on blocking level.
*
* @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
+ * @param {string} params.id - Virtual machine id
* @param {LockLevel} params.level - Lock level
* @param {boolean} params.test - Checks if the object is already locked to return an error
* @returns {number} Virtual machine id
@@ -877,16 +891,28 @@ const vmApi = oneApi.injectEndpoints({
return { params, command }
},
invalidatesTags: (_, __, { id }) => [{ type: VM, id }],
- async onQueryStarted({ id, level = '4' }, { dispatch, queryFulfilled }) {
+ async onQueryStarted(params, { dispatch, queryFulfilled }) {
try {
- await queryFulfilled
-
- dispatch(
- vmApi.util.updateQueryData('getVms', undefined, (draft) => {
- const vm = draft.find(({ ID }) => +ID === +id)
- vm && (vm.LOCK = { LOCKED: level })
- })
+ const patchVm = dispatch(
+ vmApi.util.updateQueryData(
+ 'getVm',
+ { id: params.id },
+ updateLockLevelOnResource(params)
+ )
)
+
+ const patchVms = dispatch(
+ vmApi.util.updateQueryData(
+ 'getVms',
+ undefined,
+ updateLockLevelOnResource(params)
+ )
+ )
+
+ queryFulfilled.catch(() => {
+ patchVm.undo()
+ patchVms.undo()
+ })
} catch {}
},
}),
@@ -894,27 +920,40 @@ const vmApi = oneApi.injectEndpoints({
/**
* Unlocks a Virtual Machine.
*
- * @param {string|number} id - Virtual machine id
+ * @param {object} params - Request parameters
+ * @param {string} params.id - Virtual machine id
* @returns {number} Virtual machine id
* @throws Fails when response isn't code 200
*/
- query: (id) => {
+ query: (params) => {
const name = Actions.VM_UNLOCK
const command = { name, ...Commands[name] }
- return { params: { id }, command }
+ return { params, command }
},
invalidatesTags: (_, __, id) => [{ type: VM, id }],
- async onQueryStarted(id, { dispatch, queryFulfilled }) {
+ async onQueryStarted(params, { dispatch, queryFulfilled }) {
try {
- await queryFulfilled
-
- dispatch(
- vmApi.util.updateQueryData('getVms', undefined, (draft) => {
- const vm = draft.find(({ ID }) => +ID === +id)
- vm && (vm.LOCK = undefined)
- })
+ const patchVm = dispatch(
+ vmApi.util.updateQueryData(
+ 'getVm',
+ { id: params.id },
+ removeLockLevelOnResource(params)
+ )
)
+
+ const patchVms = dispatch(
+ vmApi.util.updateQueryData(
+ 'getVms',
+ undefined,
+ removeLockLevelOnResource(params)
+ )
+ )
+
+ queryFulfilled.catch(() => {
+ patchVm.undo()
+ patchVms.undo()
+ })
} catch {}
},
}),
diff --git a/src/fireedge/src/client/features/OneApi/vmTemplate.js b/src/fireedge/src/client/features/OneApi/vmTemplate.js
index f6bfa32e89..db7bd975d1 100644
--- a/src/fireedge/src/client/features/OneApi/vmTemplate.js
+++ b/src/fireedge/src/client/features/OneApi/vmTemplate.js
@@ -14,13 +14,23 @@
* limitations under the License. *
* ------------------------------------------------------------------------- */
import { Actions, Commands } from 'server/utils/constants/commands/template'
+
import {
oneApi,
ONE_RESOURCES,
ONE_RESOURCES_POOL,
} from 'client/features/OneApi'
+import {
+ updateResourceOnPool,
+ removeResourceOnPool,
+ updateNameOnResource,
+ updateLockLevelOnResource,
+ removeLockLevelOnResource,
+ updatePermissionOnResource,
+ updateOwnershipOnResource,
+ updateUserTemplateOnResource,
+} from 'client/features/OneApi/common'
import { LockLevel, FilterFlag, Permission, VmTemplate } from 'client/constants'
-import { xmlToJson } from 'client/models/Helper'
const { TEMPLATE } = ONE_RESOURCES
const { TEMPLATE_POOL, VM_POOL } = ONE_RESOURCES_POOL
@@ -49,7 +59,10 @@ const vmTemplateApi = oneApi.injectEndpoints({
providesTags: (vmTemplates) =>
vmTemplates
? [
- ...vmTemplates.map(({ ID }) => ({ type: TEMPLATE_POOL, ID })),
+ ...vmTemplates.map(({ ID }) => ({
+ type: TEMPLATE_POOL,
+ id: `${ID}`,
+ })),
TEMPLATE_POOL,
]
: [TEMPLATE_POOL],
@@ -75,19 +88,25 @@ const vmTemplateApi = oneApi.injectEndpoints({
providesTags: (_, __, { id }) => [{ type: TEMPLATE, id }],
async onQueryStarted({ id }, { dispatch, queryFulfilled }) {
try {
- const { data: queryTemplate } = await queryFulfilled
+ const { data: resourceFromQuery } = await queryFulfilled
dispatch(
vmTemplateApi.util.updateQueryData(
'getTemplates',
undefined,
- (draft) => {
- const index = draft.findIndex(({ ID }) => +ID === +id)
- index !== -1 && (draft[index] = queryTemplate)
- }
+ updateResourceOnPool({ id, resourceFromQuery })
)
)
- } catch {}
+ } catch {
+ // if the query fails, we want to remove the resource from the pool
+ dispatch(
+ vmTemplateApi.util.updateQueryData(
+ 'getTemplates',
+ undefined,
+ removeResourceOnPool({ id })
+ )
+ )
+ }
},
}),
allocateTemplate: builder.mutation({
@@ -188,36 +207,21 @@ const vmTemplateApi = oneApi.injectEndpoints({
return { params, command }
},
invalidatesTags: (_, __, { id }) => [{ type: TEMPLATE, id }],
- async onQueryStarted(
- { id, template: xml, replace = 0 },
- { dispatch, queryFulfilled }
- ) {
+ async onQueryStarted(params, { dispatch, queryFulfilled }) {
try {
- // update template by id
const patchVmTemplate = dispatch(
- vmTemplateApi.util.updateQueryData('getTemplate', id, (draft) => {
- draft.TEMPLATE =
- +replace === 0
- ? xmlToJson(xml)
- : { ...draft.TEMPLATE, ...xmlToJson(xml) }
- })
+ vmTemplateApi.util.updateQueryData(
+ 'getTemplate',
+ { id: params.id },
+ updateUserTemplateOnResource(params, 'TEMPLATE')
+ )
)
- // update template on pool by id (if exists)
const patchVmTemplates = dispatch(
vmTemplateApi.util.updateQueryData(
'getTemplates',
undefined,
- (draft) => {
- const template = draft.find(({ ID }) => +ID === +id)
-
- if (!template) return
-
- template.TEMPLATE =
- +replace === 0
- ? xmlToJson(xml)
- : { ...template.TEMPLATE, ...xmlToJson(xml) }
- }
+ updateUserTemplateOnResource(params, 'TEMPLATE')
)
)
@@ -234,7 +238,7 @@ const vmTemplateApi = oneApi.injectEndpoints({
* If set any permission to -1, it's not changed.
*
* @param {object} params - Request parameters
- * @param {string|number} params.id - VM Template id
+ * @param {string} params.id - VM Template id
* @param {Permission|'-1'} params.ownerUse - User use
* @param {Permission|'-1'} params.ownerManage - User manage
* @param {Permission|'-1'} params.ownerAdmin - User administrator
@@ -255,33 +259,29 @@ const vmTemplateApi = oneApi.injectEndpoints({
return { params, command }
},
invalidatesTags: (_, __, { id }) => [{ type: TEMPLATE, id }],
- async onQueryStarted(
- { id, ...permissions },
- { dispatch, queryFulfilled }
- ) {
- const patchResult = dispatch(
- vmTemplateApi.util.updateQueryData('getTemplate', { id }, (draft) => {
- Object.entries(permissions)
- .filter(([_, value]) => value !== '-1')
- .forEach(([name, value]) => {
- const ensuredName = {
- ownerUse: 'OWNER_U',
- ownerManage: 'OWNER_M',
- ownerAdmin: 'OWNER_A',
- groupUse: 'GROUP_U',
- groupManage: 'GROUP_M',
- groupAdmin: 'GROUP_A',
- otherUse: 'OTHER_U',
- otherManage: 'OTHER_M',
- otherAdmin: 'OTHER_A',
- }[name]
+ async onQueryStarted(params, { dispatch, queryFulfilled }) {
+ try {
+ const patchVmTemplate = dispatch(
+ vmTemplateApi.util.updateQueryData(
+ 'getTemplate',
+ { id: params.id },
+ updatePermissionOnResource(params)
+ )
+ )
- draft.PERMISSIONS[ensuredName] = value
- })
+ const patchVmTemplates = dispatch(
+ vmTemplateApi.util.updateQueryData(
+ 'getTemplates',
+ undefined,
+ updatePermissionOnResource(params)
+ )
+ )
+
+ queryFulfilled.catch(() => {
+ patchVmTemplate.undo()
+ patchVmTemplates.undo()
})
- )
-
- queryFulfilled.catch(patchResult.undo)
+ } catch {}
},
}),
changeTemplateOwnership: builder.mutation({
@@ -303,18 +303,29 @@ const vmTemplateApi = oneApi.injectEndpoints({
return { params, command }
},
invalidatesTags: (_, __, { id }) => [{ type: TEMPLATE, id }],
- async onQueryStarted(
- { id, user, group },
- { dispatch, queryFulfilled, getState }
- ) {
- const patchResult = dispatch(
- vmTemplateApi.util.updateQueryData('getTemplate', id, (draft) => {
- user > 0 && (draft.UID = user)
- group > 0 && (draft.GID = group)
- })
- )
+ async onQueryStarted(params, { getState, dispatch, queryFulfilled }) {
+ try {
+ const patchVmTemplate = dispatch(
+ vmTemplateApi.util.updateQueryData(
+ 'getTemplate',
+ { id: params.id },
+ updateOwnershipOnResource(getState(), params)
+ )
+ )
- queryFulfilled.catch(patchResult.undo)
+ const patchVmTemplates = dispatch(
+ vmTemplateApi.util.updateQueryData(
+ 'getTemplates',
+ undefined,
+ updateOwnershipOnResource(getState(), params)
+ )
+ )
+
+ queryFulfilled.catch(() => {
+ patchVmTemplate.undo()
+ patchVmTemplates.undo()
+ })
+ } catch {}
},
}),
renameTemplate: builder.mutation({
@@ -334,20 +345,28 @@ const vmTemplateApi = oneApi.injectEndpoints({
return { params, command }
},
invalidatesTags: (_, __, { id }) => [{ type: TEMPLATE, id }],
- async onQueryStarted({ id, name }, { dispatch, queryFulfilled }) {
+ async onQueryStarted(params, { dispatch, queryFulfilled }) {
try {
- await queryFulfilled
+ const patchVmTemplate = dispatch(
+ vmTemplateApi.util.updateQueryData(
+ 'getTemplate',
+ { id: params.id },
+ updateNameOnResource(params)
+ )
+ )
- dispatch(
+ const patchVmTemplates = dispatch(
vmTemplateApi.util.updateQueryData(
'getTemplates',
undefined,
- (draft) => {
- const template = draft.find(({ ID }) => +ID === +id)
- template && (template.NAME = name)
- }
+ updateNameOnResource(params)
)
)
+
+ queryFulfilled.catch(() => {
+ patchVmTemplate.undo()
+ patchVmTemplates.undo()
+ })
} catch {}
},
}),
@@ -356,7 +375,7 @@ const vmTemplateApi = oneApi.injectEndpoints({
* Locks a VM Template.
*
* @param {object} params - Request parameters
- * @param {string|number} params.id - VM Template id
+ * @param {string} params.id - VM Template id
* @param {LockLevel} params.lock - Lock level
* @param {boolean} params.test - Checks if the object is already locked to return an error
* @returns {number} VM Template id
@@ -369,20 +388,28 @@ const vmTemplateApi = oneApi.injectEndpoints({
return { params, command }
},
invalidatesTags: (_, __, { id }) => [{ type: TEMPLATE, id }],
- async onQueryStarted({ id, level = '4' }, { dispatch, queryFulfilled }) {
+ async onQueryStarted(params, { dispatch, queryFulfilled }) {
try {
- await queryFulfilled
+ const patchVmTemplate = dispatch(
+ vmTemplateApi.util.updateQueryData(
+ 'getTemplate',
+ { id: params.id },
+ updateLockLevelOnResource(params)
+ )
+ )
- dispatch(
+ const patchVmTemplates = dispatch(
vmTemplateApi.util.updateQueryData(
'getTemplates',
undefined,
- (draft) => {
- const template = draft.find(({ ID }) => +ID === +id)
- template && (template.LOCK = { LOCKED: level })
- }
+ updateLockLevelOnResource(params)
)
)
+
+ queryFulfilled.catch(() => {
+ patchVmTemplate.undo()
+ patchVmTemplates.undo()
+ })
} catch {}
},
}),
@@ -390,31 +417,40 @@ const vmTemplateApi = oneApi.injectEndpoints({
/**
* Unlocks a VM Template.
*
- * @param {string|number} id - VM Template id
+ * @param {object} params - Request parameters
+ * @param {string} params.id - VM Template id
* @returns {number} VM Template id
* @throws Fails when response isn't code 200
*/
- query: (id) => {
+ query: (params) => {
const name = Actions.TEMPLATE_UNLOCK
const command = { name, ...Commands[name] }
- return { params: { id }, command }
+ return { params, command }
},
invalidatesTags: (_, __, id) => [{ type: TEMPLATE, id }],
- async onQueryStarted(id, { dispatch, queryFulfilled }) {
+ async onQueryStarted(params, { dispatch, queryFulfilled }) {
try {
- await queryFulfilled
+ const patchVmTemplate = dispatch(
+ vmTemplateApi.util.updateQueryData(
+ 'getTemplate',
+ { id: params.id },
+ removeLockLevelOnResource(params)
+ )
+ )
- dispatch(
+ const patchVmTemplates = dispatch(
vmTemplateApi.util.updateQueryData(
'getTemplates',
undefined,
- (draft) => {
- const template = draft.find(({ ID }) => +ID === +id)
- template && (template.LOCK = undefined)
- }
+ removeLockLevelOnResource(params)
)
)
+
+ queryFulfilled.catch(() => {
+ patchVmTemplate.undo()
+ patchVmTemplates.undo()
+ })
} catch {}
},
}),