mirror of
https://github.com/portainer/portainer.git
synced 2025-07-25 08:19:40 +02:00
feat(license): remove untrusted devices from node count [EE-5357] (#8817)
This commit is contained in:
parent
5f6ddc2fad
commit
cfed481d6e
7 changed files with 102 additions and 35 deletions
|
@ -6,12 +6,12 @@ import { useDeleteEnvironmentsMutation } from '@/react/portainer/environments/qu
|
|||
|
||||
import { Datatable as GenericDatatable } from '@@/datatables';
|
||||
import { Button } from '@@/buttons';
|
||||
import { TextTip } from '@@/Tip/TextTip';
|
||||
import { createPersistedStore } from '@@/datatables/types';
|
||||
import { useTableState } from '@@/datatables/useTableState';
|
||||
import { confirm } from '@@/modals/confirm';
|
||||
import { buildConfirmButton } from '@@/modals/utils';
|
||||
import { ModalType } from '@@/modals';
|
||||
import { TooltipWithChildren } from '@@/Tip/TooltipWithChildren';
|
||||
|
||||
import { useAssociateDeviceMutation, useLicenseOverused } from '../queries';
|
||||
|
||||
|
@ -26,7 +26,7 @@ const settingsStore = createPersistedStore(storageKey, 'Name');
|
|||
export function Datatable() {
|
||||
const associateMutation = useAssociateDeviceMutation();
|
||||
const removeMutation = useDeleteEnvironmentsMutation();
|
||||
const licenseOverused = useLicenseOverused();
|
||||
const { willExceed } = useLicenseOverused();
|
||||
const tableState = useTableState(settingsStore, storageKey);
|
||||
const { data: environments, totalCount, isLoading } = useEnvironments();
|
||||
|
||||
|
@ -41,28 +41,34 @@ export function Datatable() {
|
|||
<>
|
||||
<Button
|
||||
onClick={() => handleRemoveDevice(selectedRows)}
|
||||
disabled={selectedRows.length === 0 || licenseOverused}
|
||||
disabled={selectedRows.length === 0}
|
||||
color="dangerlight"
|
||||
icon={Trash2}
|
||||
>
|
||||
Remove Device
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
onClick={() => handleAssociateDevice(selectedRows)}
|
||||
disabled={selectedRows.length === 0 || licenseOverused}
|
||||
<TooltipWithChildren
|
||||
message={
|
||||
willExceed(selectedRows.length) && (
|
||||
<>
|
||||
Associating devices is disabled as your node count exceeds
|
||||
your license limit
|
||||
</>
|
||||
)
|
||||
}
|
||||
>
|
||||
Associate Device
|
||||
</Button>
|
||||
|
||||
{licenseOverused ? (
|
||||
<div className="ml-2 mt-2">
|
||||
<TextTip color="orange">
|
||||
Associating devices is disabled as your node count exceeds your
|
||||
license limit
|
||||
</TextTip>
|
||||
</div>
|
||||
) : null}
|
||||
<span>
|
||||
<Button
|
||||
onClick={() => handleAssociateDevice(selectedRows)}
|
||||
disabled={
|
||||
selectedRows.length === 0 || willExceed(selectedRows.length)
|
||||
}
|
||||
>
|
||||
Associate Device
|
||||
</Button>
|
||||
</span>
|
||||
</TooltipWithChildren>
|
||||
</>
|
||||
)}
|
||||
isLoading={isLoading}
|
||||
|
|
|
@ -3,12 +3,17 @@ import { withLimitToBE } from '@/react/hooks/useLimitToBE';
|
|||
import { InformationPanel } from '@@/InformationPanel';
|
||||
import { TextTip } from '@@/Tip/TextTip';
|
||||
import { PageHeader } from '@@/PageHeader';
|
||||
import { Link } from '@@/Link';
|
||||
import { Alert } from '@@/Alert';
|
||||
|
||||
import { Datatable } from './Datatable';
|
||||
import { useLicenseOverused, useUntrustedCount } from './queries';
|
||||
|
||||
export default withLimitToBE(WaitingRoomView);
|
||||
|
||||
function WaitingRoomView() {
|
||||
const untrustedCount = useUntrustedCount();
|
||||
const { willExceed } = useLicenseOverused();
|
||||
return (
|
||||
<>
|
||||
<PageHeader
|
||||
|
@ -27,6 +32,19 @@ function WaitingRoomView() {
|
|||
</TextTip>
|
||||
</InformationPanel>
|
||||
|
||||
{willExceed(untrustedCount) && (
|
||||
<div className="row">
|
||||
<div className="col-sm-12">
|
||||
<Alert color="warn">
|
||||
Associating all nodes in waiting room will exceed the node limit
|
||||
of your current license. Go to{' '}
|
||||
<Link to="portainer.licenses">Licenses</Link> page to view the
|
||||
current usage.
|
||||
</Alert>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<Datatable />
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import { useMutation, useQueryClient } from 'react-query';
|
||||
|
||||
import { EnvironmentId } from '@/react/portainer/environments/types';
|
||||
import { EdgeTypes, EnvironmentId } from '@/react/portainer/environments/types';
|
||||
import axios, { parseAxiosError } from '@/portainer/services/axios';
|
||||
import { promiseSequence } from '@/portainer/helpers/promise-utils';
|
||||
import { useIntegratedLicenseInfo } from '@/react/portainer/licenses/use-license.service';
|
||||
import { useEnvironmentList } from '@/react/portainer/environments/queries';
|
||||
|
||||
export function useAssociateDeviceMutation() {
|
||||
const queryClient = useQueryClient();
|
||||
|
@ -35,8 +36,23 @@ async function associateDevice(environmentId: EnvironmentId) {
|
|||
|
||||
export function useLicenseOverused() {
|
||||
const integratedInfo = useIntegratedLicenseInfo();
|
||||
if (integratedInfo && integratedInfo.licenseInfo.enforcedAt > 0) {
|
||||
return true;
|
||||
return {
|
||||
willExceed,
|
||||
isOverused: willExceed(0),
|
||||
};
|
||||
|
||||
function willExceed(moreNodes: number) {
|
||||
return (
|
||||
!!integratedInfo &&
|
||||
integratedInfo.usedNodes + moreNodes >= integratedInfo.licenseInfo.nodes
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function useUntrustedCount() {
|
||||
const query = useEnvironmentList({
|
||||
edgeDeviceUntrusted: true,
|
||||
types: EdgeTypes,
|
||||
});
|
||||
return query.totalCount;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue