diff --git a/src/fireedge/src/client/components/Tables/MarketplaceApps/actions.js b/src/fireedge/src/client/components/Tables/MarketplaceApps/actions.js index 726cbd2b87..61d2573d2d 100644 --- a/src/fireedge/src/client/components/Tables/MarketplaceApps/actions.js +++ b/src/fireedge/src/client/components/Tables/MarketplaceApps/actions.js @@ -19,7 +19,12 @@ import { AddCircledOutline, CloudDownload, DownloadCircledOutline, + Lock, + MoreVert, + Group, + Trash, } from 'iconoir-react' +import PropTypes from 'prop-types' import { useViews } from 'client/features/Auth' import { useGeneralApi } from 'client/features/General' @@ -27,6 +32,12 @@ import { Translate } from 'client/components/HOC' import { useExportAppMutation, useDownloadAppMutation, + useLockAppMutation, + useUnlockAppMutation, + useEnableAppMutation, + useDisableAppMutation, + useChangeAppOwnershipMutation, + useDeleteAppMutation, } from 'client/features/OneApi/marketplaceApp' import { ExportForm } from 'client/components/Forms/MarketplaceApp' @@ -37,22 +48,37 @@ import { import { PATH } from 'client/apps/sunstone/routesOne' import { T, RESOURCE_NAMES, MARKETPLACE_APP_ACTIONS } from 'client/constants' +import { ChangeGroupForm, ChangeUserForm } from 'client/components/Forms/Vm' +import { Typography } from '@mui/material' -const MessageToConfirmAction = (rows) => { +const ListAppNames = ({ rows = [] }) => { const names = rows?.map?.(({ original }) => original?.NAME) return ( - <> -

- - {`: ${names.join(', ')}`} -

-

- -

- + + + {`: ${names.join(', ')}`} + ) } +ListAppNames.propTypes = { + rows: PropTypes.arrayOf( + PropTypes.shape({ + original: PropTypes.shape({ + NAME: PropTypes.string, + }), + }) + ), +} + +const SubHeader = (rows) => + +const MessageToConfirmAction = (rows) => ( + <> + + + +) MessageToConfirmAction.displayName = 'MessageToConfirmAction' @@ -67,6 +93,12 @@ const Actions = () => { const { enqueueSuccess } = useGeneralApi() const [exportApp] = useExportAppMutation() const [downloadApp] = useDownloadAppMutation() + const [lock] = useLockAppMutation() + const [unlock] = useUnlockAppMutation() + const [enable] = useEnableAppMutation() + const [disable] = useDisableAppMutation() + const [changeOwnership] = useChangeAppOwnershipMutation() + const [deleteApp] = useDeleteAppMutation() const marketplaceAppActions = useMemo( () => @@ -117,6 +149,142 @@ const Actions = () => { urls.forEach((url) => window.open(url, '_blank')) }, }, + { + tooltip: T.Lock, + icon: Lock, + selected: true, + color: 'secondary', + dataCy: 'marketapp-lock', + options: [ + { + accessor: MARKETPLACE_APP_ACTIONS.LOCK, + name: T.Lock, + isConfirmDialog: true, + dialogProps: { + title: T.Lock, + children: MessageToConfirmAction, + dataCy: `modal-${MARKETPLACE_APP_ACTIONS.LOCK}`, + }, + onSubmit: (rows) => async () => { + const ids = rows?.map?.(({ original }) => original?.ID) + await Promise.all(ids.map((id) => lock({ id }))) + }, + }, + { + accessor: MARKETPLACE_APP_ACTIONS.UNLOCK, + name: T.Unlock, + isConfirmDialog: true, + dialogProps: { + title: T.Unlock, + children: MessageToConfirmAction, + dataCy: `modal-${MARKETPLACE_APP_ACTIONS.UNLOCK}`, + }, + onSubmit: (rows) => async () => { + const ids = rows?.map?.(({ original }) => original?.ID) + await Promise.all(ids.map((id) => unlock({ id }))) + }, + }, + ], + }, + { + tooltip: T.Enable, + icon: MoreVert, + selected: true, + color: 'secondary', + dataCy: 'marketapp-enable', + options: [ + { + accessor: MARKETPLACE_APP_ACTIONS.ENABLE, + name: T.Enable, + isConfirmDialog: true, + dialogProps: { + title: T.Enable, + children: MessageToConfirmAction, + dataCy: `modal-${MARKETPLACE_APP_ACTIONS.ENABLE}`, + }, + onSubmit: (rows) => async () => { + const ids = rows?.map?.(({ original }) => original?.ID) + await Promise.all(ids.map((id) => enable(id))) + }, + }, + { + accessor: MARKETPLACE_APP_ACTIONS.DISABLE, + name: T.Disable, + isConfirmDialog: true, + dialogProps: { + title: T.Disable, + children: MessageToConfirmAction, + dataCy: `modal-${MARKETPLACE_APP_ACTIONS.DISABLE}`, + }, + onSubmit: (rows) => async () => { + const ids = rows?.map?.(({ original }) => original?.ID) + await Promise.all(ids.map((id) => disable(id))) + }, + }, + ], + }, + { + tooltip: T.Ownership, + icon: Group, + selected: true, + color: 'secondary', + dataCy: 'vm-ownership', + options: [ + { + accessor: MARKETPLACE_APP_ACTIONS.CHANGE_OWNER, + name: T.ChangeOwner, + dialogProps: { + title: T.ChangeOwner, + subheader: SubHeader, + dataCy: `modal-${MARKETPLACE_APP_ACTIONS.CHANGE_OWNER}`, + }, + form: ChangeUserForm, + onSubmit: (rows) => async (newOwnership) => { + const ids = rows?.map?.(({ original }) => original?.ID) + await Promise.all( + ids.map((id) => changeOwnership({ id, ...newOwnership })) + ) + }, + }, + { + accessor: MARKETPLACE_APP_ACTIONS.CHANGE_GROUP, + name: T.ChangeGroup, + dialogProps: { + title: T.ChangeGroup, + subheader: SubHeader, + dataCy: `modal-${MARKETPLACE_APP_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: MARKETPLACE_APP_ACTIONS.DELETE, + tooltip: T.Delete, + icon: Trash, + color: 'error', + selected: { min: 1 }, + options: [ + { + isConfirmDialog: true, + dialogProps: { + title: T.Delete, + dataCy: `modal-${MARKETPLACE_APP_ACTIONS.DELETE}`, + children: MessageToConfirmAction, + }, + onSubmit: (rows) => async () => { + const ids = rows?.map?.(({ original }) => original?.ID) + await Promise.all(ids.map((id) => deleteApp({ id }))) + }, + }, + ], + }, ], }), [view] diff --git a/src/fireedge/src/client/constants/marketplaceApp.js b/src/fireedge/src/client/constants/marketplaceApp.js index aa8d8e7ee7..d78e312d93 100644 --- a/src/fireedge/src/client/constants/marketplaceApp.js +++ b/src/fireedge/src/client/constants/marketplaceApp.js @@ -56,6 +56,8 @@ export const MARKETPLACE_APP_ACTIONS = { DISABLE: 'disable', DELETE: 'delete', EDIT_LABELS: 'edit_labels', + LOCK: 'lock', + UNLOCK: 'unlock', // INFORMATION RENAME: ACTIONS.RENAME, diff --git a/src/fireedge/src/client/features/OneApi/marketplaceApp.js b/src/fireedge/src/client/features/OneApi/marketplaceApp.js index e6dc6341ad..6b076ff046 100644 --- a/src/fireedge/src/client/features/OneApi/marketplaceApp.js +++ b/src/fireedge/src/client/features/OneApi/marketplaceApp.js @@ -484,6 +484,23 @@ const marketAppApi = oneApi.injectEndpoints({ }, invalidatesTags: [APP_POOL], }), + deleteApp: builder.mutation({ + /** + * Delete Marketplaceapp. + * + * @param {object} params - Request parameters + * @param {string} params.id - Marketplaceapp ID + * @returns {number} Marketplace app id + * @throws Fails when response isn't code 200 + */ + query: (params) => { + const name = Actions.MARKETAPP_DELETE + const command = { name, ...Commands[name] } + + return { params, command } + }, + invalidatesTags: (_, __, { id }) => [{ type: APP, id }], + }), downloadApp: builder.mutation({ /** * Download a MarketPlaceApp. @@ -559,6 +576,7 @@ export const { useImportAppMutation, useExportAppMutation, useDownloadAppMutation, + useDeleteAppMutation, } = marketAppApi export default marketAppApi diff --git a/src/fireedge/src/server/utils/constants/commands/marketapp.js b/src/fireedge/src/server/utils/constants/commands/marketapp.js index 38c2bb385d..8378008663 100644 --- a/src/fireedge/src/server/utils/constants/commands/marketapp.js +++ b/src/fireedge/src/server/utils/constants/commands/marketapp.js @@ -158,11 +158,11 @@ module.exports = { from: resource, default: 0, }, - userId: { + user: { from: postBody, default: -1, }, - groupId: { + group: { from: postBody, default: -1, },