mirror of
https://github.com/portainer/portainer.git
synced 2026-08-07 10:54:48 +00:00
fix(networks): fix auto-refresh interval and address review follow-ups [BE-6563] (#3165)
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -6,9 +6,14 @@ import { isAxiosError } from '@/portainer/services/axios/utils/isAxiosError';
|
||||
|
||||
import { buildDockerProxyUrl } from '../../proxy/queries/buildDockerProxyUrl';
|
||||
|
||||
export function useApiVersion(environmentId: EnvironmentId) {
|
||||
return useQuery(['environment', environmentId, 'agent', 'ping'], () =>
|
||||
getApiVersion(environmentId)
|
||||
export function useApiVersion(
|
||||
environmentId: EnvironmentId,
|
||||
{ enabled = true }: { enabled?: boolean } = {}
|
||||
) {
|
||||
return useQuery(
|
||||
['environment', environmentId, 'agent', 'api-version'],
|
||||
() => getApiVersion(environmentId),
|
||||
{ enabled }
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,9 @@ const settingsStore = createPersistedStore<TableSettings>(
|
||||
);
|
||||
|
||||
interface Props {
|
||||
onRemove(selectedItems: Array<{ nodeName?: string; id: string }>): void;
|
||||
onRemove(
|
||||
selectedItems: Array<{ nodeName?: string; id: string; name: string }>
|
||||
): void;
|
||||
}
|
||||
|
||||
export function NetworksDatatable({ onRemove }: Props) {
|
||||
@@ -45,7 +47,7 @@ export function NetworksDatatable({ onRemove }: Props) {
|
||||
const environmentId = useEnvironmentId();
|
||||
const isSwarm = useIsSwarm(environmentId);
|
||||
|
||||
const datasetQuery = useNetworksData(settings.autoRefreshRate);
|
||||
const datasetQuery = useNetworksData(settings.autoRefreshRate * 1000);
|
||||
const columns = useColumns(isSwarm);
|
||||
|
||||
const dataset = datasetQuery.data;
|
||||
@@ -84,7 +86,11 @@ export function NetworksDatatable({ onRemove }: Props) {
|
||||
confirmMessage="Do you want to remove the selected network(s)?"
|
||||
onConfirmed={() =>
|
||||
onRemove(
|
||||
selectedRows.map((n) => ({ id: n.Id, nodeName: n.NodeName }))
|
||||
selectedRows.map((n) => ({
|
||||
id: n.Id,
|
||||
name: n.Name,
|
||||
nodeName: n.NodeName,
|
||||
}))
|
||||
)
|
||||
}
|
||||
/>
|
||||
|
||||
@@ -61,6 +61,20 @@ describe('groupSwarmNetworksManagerNodesFirst', () => {
|
||||
|
||||
expect(result.map((n) => n.Id)).toEqual(['net1', 'net2']);
|
||||
});
|
||||
|
||||
it('should not mutate the input networks', () => {
|
||||
const manager = createNetwork({ Id: 'net1', NodeName: 'node-manager' });
|
||||
const worker = createNetwork({ Id: 'net1', NodeName: 'node-worker' });
|
||||
const agents = [
|
||||
createAgent({ NodeName: 'node-manager', NodeRole: 'manager' }),
|
||||
createAgent({ NodeName: 'node-worker', NodeRole: 'worker' }),
|
||||
];
|
||||
|
||||
groupSwarmNetworksManagerNodesFirst([worker, manager], agents);
|
||||
|
||||
expect(manager.Subs).toEqual([]);
|
||||
expect(worker.Subs).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
function createNetwork(
|
||||
|
||||
@@ -45,13 +45,15 @@ export function useNetworksData(autoRefreshRate?: number) {
|
||||
}
|
||||
);
|
||||
const isSwarmAgent = useIsSwarmAgent();
|
||||
const apiVersionQuery = useApiVersion(environmentId);
|
||||
const apiVersionQuery = useApiVersion(environmentId, {
|
||||
enabled: isSwarmAgent,
|
||||
});
|
||||
const agentsQuery = useAgentNodes(environmentId, apiVersionQuery.data || 1, {
|
||||
enabled: isSwarmAgent,
|
||||
});
|
||||
|
||||
if (!networksQuery.data) {
|
||||
return { isLoading: true };
|
||||
return { isLoading: networksQuery.isLoading };
|
||||
}
|
||||
|
||||
const networks = groupSwarmNetworksManagerNodesFirst(
|
||||
@@ -82,8 +84,7 @@ export function groupSwarmNetworksManagerNodesFirst(
|
||||
const groupedSwarmNetworks = Array.from(swarmNetworksById.values()).map(
|
||||
(group) => {
|
||||
const [item, ...rest] = _.sortBy(group, getRole);
|
||||
item.Subs = rest;
|
||||
return item;
|
||||
return { ...item, Subs: rest };
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@ import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
|
||||
import { processItemsInBatches } from '@/react/common/processItemsInBatches';
|
||||
import { useEnvironmentId } from '@/react/hooks/useEnvironmentId';
|
||||
import { notifySuccess } from '@/portainer/services/notifications';
|
||||
import { withError, withInvalidate } from '@/react-tools/react-query';
|
||||
import { notifyError, notifySuccess } from '@/portainer/services/notifications';
|
||||
import { withInvalidate } from '@/react-tools/react-query';
|
||||
|
||||
import { queryKeys } from './queryKeys';
|
||||
import { deleteNetwork } from './useDeleteNetworkMutation';
|
||||
@@ -16,14 +16,16 @@ export function useDeleteNetworkListMutation() {
|
||||
mutationFn: ({
|
||||
networks,
|
||||
}: {
|
||||
networks: Array<{ nodeName?: string; id: string }>;
|
||||
networks: Array<{ nodeName?: string; id: string; name: string }>;
|
||||
}) =>
|
||||
processItemsInBatches(networks, ({ id, nodeName }) =>
|
||||
deleteNetwork(environmentId, id, { nodeName }).then(() =>
|
||||
notifySuccess('Network successfully removed', id)
|
||||
)
|
||||
),
|
||||
processItemsInBatches(networks, async ({ id, name, nodeName }) => {
|
||||
try {
|
||||
await deleteNetwork(environmentId, id, { nodeName });
|
||||
notifySuccess('Network successfully removed', name);
|
||||
} catch (err) {
|
||||
notifyError(`Unable to remove network ${name}`, err);
|
||||
}
|
||||
}),
|
||||
...withInvalidate(queryClient, [queryKeys.base(environmentId)]),
|
||||
...withError('Failed to remove networks'),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { IPAMConfig, Network } from 'docker-types';
|
||||
|
||||
import axios, { parseAxiosError } from '@/portainer/services/axios/axios';
|
||||
import { EnvironmentId } from '@/react/portainer/environments/types';
|
||||
import { withError } from '@/react-tools/react-query';
|
||||
|
||||
import { withFiltersQueryParam } from '../../proxy/queries/utils';
|
||||
import { buildDockerProxyUrl } from '../../proxy/queries/buildDockerProxyUrl';
|
||||
@@ -43,6 +44,7 @@ export function useNetworks<T = Array<DockerNetwork>>(
|
||||
select,
|
||||
|
||||
refetchInterval: autoRefreshRate ?? false,
|
||||
...withError('Unable to retrieve networks'),
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -130,6 +132,7 @@ function toDockerNetwork(req: NetworkListResponseItem): DockerNetwork {
|
||||
|
||||
function toIpamConfig(req: IPAMConfig): IPConfig {
|
||||
return {
|
||||
...req,
|
||||
Subnet: req.Subnet ?? '',
|
||||
Gateway: req.Gateway ?? '',
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user