mirror of https://github.com/portainer/portainer
feat(edge): hide envs from waiting room [EE-5185] (#8688)
parent
4b9c857d85
commit
bbea0bc8a5
|
@ -1,13 +1,18 @@
|
||||||
import { useStore } from 'zustand';
|
import { useStore } from 'zustand';
|
||||||
|
import { Trash2 } from 'lucide-react';
|
||||||
|
|
||||||
import { Environment } from '@/react/portainer/environments/types';
|
import { Environment } from '@/react/portainer/environments/types';
|
||||||
import { notifySuccess } from '@/portainer/services/notifications';
|
import { notifySuccess } from '@/portainer/services/notifications';
|
||||||
|
import { useDeleteEnvironmentsMutation } from '@/react/portainer/environments/queries/useDeleteEnvironmentsMutation';
|
||||||
|
|
||||||
import { Datatable as GenericDatatable } from '@@/datatables';
|
import { Datatable as GenericDatatable } from '@@/datatables';
|
||||||
import { Button } from '@@/buttons';
|
import { Button } from '@@/buttons';
|
||||||
import { TextTip } from '@@/Tip/TextTip';
|
import { TextTip } from '@@/Tip/TextTip';
|
||||||
import { createPersistedStore } from '@@/datatables/types';
|
import { createPersistedStore } from '@@/datatables/types';
|
||||||
import { useSearchBarState } from '@@/datatables/SearchBar';
|
import { useSearchBarState } from '@@/datatables/SearchBar';
|
||||||
|
import { confirm } from '@@/modals/confirm';
|
||||||
|
import { buildConfirmButton } from '@@/modals/utils';
|
||||||
|
import { ModalType } from '@@/modals';
|
||||||
|
|
||||||
import { useAssociateDeviceMutation, useLicenseOverused } from '../queries';
|
import { useAssociateDeviceMutation, useLicenseOverused } from '../queries';
|
||||||
|
|
||||||
|
@ -21,6 +26,7 @@ const settingsStore = createPersistedStore(storageKey, 'Name');
|
||||||
|
|
||||||
export function Datatable() {
|
export function Datatable() {
|
||||||
const associateMutation = useAssociateDeviceMutation();
|
const associateMutation = useAssociateDeviceMutation();
|
||||||
|
const removeMutation = useDeleteEnvironmentsMutation();
|
||||||
const licenseOverused = useLicenseOverused();
|
const licenseOverused = useLicenseOverused();
|
||||||
const settings = useStore(settingsStore);
|
const settings = useStore(settingsStore);
|
||||||
const [search, setSearch] = useSearchBarState(storageKey);
|
const [search, setSearch] = useSearchBarState(storageKey);
|
||||||
|
@ -40,6 +46,15 @@ export function Datatable() {
|
||||||
emptyContentLabel="No Edge Devices found"
|
emptyContentLabel="No Edge Devices found"
|
||||||
renderTableActions={(selectedRows) => (
|
renderTableActions={(selectedRows) => (
|
||||||
<>
|
<>
|
||||||
|
<Button
|
||||||
|
onClick={() => handleRemoveDevice(selectedRows)}
|
||||||
|
disabled={selectedRows.length === 0 || licenseOverused}
|
||||||
|
color="dangerlight"
|
||||||
|
icon={Trash2}
|
||||||
|
>
|
||||||
|
Remove Device
|
||||||
|
</Button>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
onClick={() => handleAssociateDevice(selectedRows)}
|
onClick={() => handleAssociateDevice(selectedRows)}
|
||||||
disabled={selectedRows.length === 0}
|
disabled={selectedRows.length === 0}
|
||||||
|
@ -73,4 +88,27 @@ export function Datatable() {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function handleRemoveDevice(devices: Environment[]) {
|
||||||
|
const confirmed = await confirm({
|
||||||
|
title: 'Are you sure?',
|
||||||
|
message:
|
||||||
|
"You're about to remove edge device(s) from waiting room, which will not be shown until next agent startup.",
|
||||||
|
confirmButton: buildConfirmButton('Remove', 'danger'),
|
||||||
|
modalType: ModalType.Destructive,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!confirmed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
removeMutation.mutate(
|
||||||
|
devices.map((d) => d.Id),
|
||||||
|
{
|
||||||
|
onSuccess() {
|
||||||
|
notifySuccess('Success', 'Edge devices were hidden successfully');
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
import { useQueryClient, useMutation } from 'react-query';
|
||||||
|
|
||||||
|
import { promiseSequence } from '@/portainer/helpers/promise-utils';
|
||||||
|
import {
|
||||||
|
mutationOptions,
|
||||||
|
withError,
|
||||||
|
withInvalidate,
|
||||||
|
} from '@/react-tools/react-query';
|
||||||
|
import { EnvironmentId } from '@/react/portainer/environments/types';
|
||||||
|
|
||||||
|
import { deleteEndpoint } from '../environment.service';
|
||||||
|
|
||||||
|
export function useDeleteEnvironmentsMutation() {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
return useMutation(
|
||||||
|
(ids: Array<EnvironmentId>) =>
|
||||||
|
promiseSequence(ids.map((id) => () => deleteEndpoint(id))),
|
||||||
|
mutationOptions(
|
||||||
|
withError('Failed to remove environments'),
|
||||||
|
withInvalidate(queryClient, [['environments']])
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
Loading…
Reference in New Issue