Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(NET-1599): use network stats endpoit to get host count per net #774

Merged
merged 1 commit into from
Sep 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/constants/ApiRoutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export class ApiRoutes {
static EXTERNAL_CLIENTS = '/extclients';
static HOSTS = '/hosts';
static NETWORKS = '/networks';
static NETWORKS_STATS = '/v1/networks/stats';
static DNS = '/dns';
static DNS_ADMIN = '/dns/adm';
static LOGIN = '/users/adm/authenticate';
Expand Down
4 changes: 4 additions & 0 deletions src/models/Network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,7 @@ export type NetworkPayload = Modify<
defaultudpholepunch: 'no' | 'yes';
}
>;

export type NetworkStat = Network & { hosts: number };

export type NetworkStatPayload = NetworkPayload & { hosts: number };
17 changes: 9 additions & 8 deletions src/pages/DashboardPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -150,14 +150,15 @@ export default function DashboardPage(props: PageProps) {
},
{
title: 'Hosts Count',
render(_, network) {
const nodeCount = store.nodes?.filter((node) => node.network === network.netid).length ?? 0;
return (
<div onClick={(ev) => ev.stopPropagation()}>
<Typography.Text>{nodeCount}</Typography.Text>
</div>
);
},
dataIndex: 'hosts',
// render(_, network) {
// const nodeCount = store.nodes?.filter((node) => node.network === network.netid).length ?? 0;
// return (
// <div onClick={(ev) => ev.stopPropagation()}>
// <Typography.Text>{nodeCount}</Typography.Text>
// </div>
// );
// },
},
{
title: 'Network Last Modified',
Expand Down
52 changes: 26 additions & 26 deletions src/pages/networks/NetworkDetailsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3684,32 +3684,32 @@ export default function NetworkDetailsPage(props: PageProps) {
loadMetrics,
]);

const onNetworkFormEdit = useCallback(async () => {
try {
const formData = await form.validateFields();
const network = store.networks.find((network) => network.netid === networkId);
if (!networkId || !network) {
throw new Error('Network not found');
}
const newNetwork = (
await NetworksService.updateNetwork(networkId, convertUiNetworkToNetworkPayload({ ...network, ...formData }))
).data;
store.updateNetwork(networkId, convertNetworkPayloadToUiNetwork(newNetwork));
notify.success({ message: `Network ${networkId} updated` });
setIsEditingNetwork(false);
} catch (err) {
if (err instanceof AxiosError) {
notify.error({
message: 'Failed to save changes',
description: extractErrorMsg(err),
});
} else {
notify.error({
message: err instanceof Error ? err.message : 'Failed to save changes',
});
}
}
}, [form, networkId, notify, store]);
// const onNetworkFormEdit = useCallback(async () => {
// try {
// const formData = await form.validateFields();
// const network = store.networks.find((network) => network.netid === networkId);
// if (!networkId || !network) {
// throw new Error('Network not found');
// }
// const newNetwork = (
// await NetworksService.updateNetwork(networkId, convertUiNetworkToNetworkPayload({ ...network, ...formData }))
// ).data;
// store.updateNetwork(networkId, convertNetworkPayloadToUiNetwork(newNetwork));
// notify.success({ message: `Network ${networkId} updated` });
// setIsEditingNetwork(false);
// } catch (err) {
// if (err instanceof AxiosError) {
// notify.error({
// message: 'Failed to save changes',
// description: extractErrorMsg(err),
// });
// } else {
// notify.error({
// message: err instanceof Error ? err.message : 'Failed to save changes',
// });
// }
// }
// }, [form, networkId, notify, store]);

const onNetworkDelete = useCallback(async () => {
try {
Expand Down
21 changes: 11 additions & 10 deletions src/pages/networks/NetworksPage.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Network } from '@/models/Network';
import { Network, NetworkStat } from '@/models/Network';
import { AppRoutes } from '@/routes';
import { InfoCircleOutlined, PlusOutlined, ReloadOutlined, SearchOutlined } from '@ant-design/icons';
import {
Expand Down Expand Up @@ -76,7 +76,7 @@ export default function NetworksPage(props: PageProps) {
[store.nodes],
);

const tableColumns: TableColumnsType<Network> = [
const tableColumns: TableColumnsType<NetworkStat> = [
{
title: 'Name',
dataIndex: 'netid',
Expand Down Expand Up @@ -111,14 +111,15 @@ export default function NetworksPage(props: PageProps) {
},
{
title: 'Hosts Count',
render(_, network) {
const nodeCount = store.nodes?.filter((node) => node.network === network.netid).length ?? 0;
return (
<div onClick={(ev) => ev.stopPropagation()}>
<Typography.Text>{nodeCount}</Typography.Text>
</div>
);
},
dataIndex: 'hosts',
// render(_, network) {
// const nodeCount = store.nodes?.filter((node) => node.network === network.netid).length ?? 0;
// return (
// <div onClick={(ev) => ev.stopPropagation()}>
// <Typography.Text>{nodeCount}</Typography.Text>
// </div>
// );
// },
},
{
title: 'Network Last Modified',
Expand Down
8 changes: 7 additions & 1 deletion src/services/NetworksService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,22 @@ import { NodeAclContainer } from '@/models/Acl';
import { ApiRoutes } from '../constants/ApiRoutes';
import { AccessKey } from '../models/AccessKey';
import { DNS } from '../models/Dns';
import { Network, NetworkPayload } from '../models/Network';
import { Network, NetworkPayload, NetworkStatPayload } from '../models/Network';
import { axiosService } from './BaseService';
import { CreateAccessKeyDto } from './dtos/CreateAccessKeyDto';
import { CreateNetworkDto } from './dtos/CreateNetworkDto';
import { NetworkMetrics, NodeOrClientMetric } from '@/models/Metrics';
import { ExternalClient } from '@/models/ExternalClient';
import { GenericResponseDto } from './dtos/GenericDto';

function getNetworks() {
return axiosService.get<NetworkPayload[]>(`${ApiRoutes.NETWORKS}`);
}

function getNetworksWithStats() {
return axiosService.get<GenericResponseDto<NetworkStatPayload[]>>(`${ApiRoutes.NETWORKS_STATS}`);
}

function createNetwork(payload: CreateNetworkDto) {
return axiosService.post<NetworkPayload>(`${ApiRoutes.NETWORKS}`, payload);
}
Expand Down Expand Up @@ -79,6 +84,7 @@ function getClientMetrics(networkId: Network['netid']) {

export const NetworksService = {
getNetworks,
getNetworksWithStats,
createNetwork,
updateNetwork,
deleteNetwork,
Expand Down
36 changes: 18 additions & 18 deletions src/store/networks.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import { NetworksService } from '@/services/NetworksService';
import { convertNetworkPayloadToUiNetwork } from '@/utils/NetworkUtils';
import { StateCreator } from 'zustand';
import { Network } from '../models/Network';
import { Network, NetworkStat } from '../models/Network';

export interface INetworkSlice {
// state
networks: Network[];
networks: NetworkStat[];
isFetchingNetworks: boolean;

// actions
fetchNetworks: () => Promise<void>;
setNetworks: (networks: Network[]) => void;
// setNetworks: (networks: Network[]) => void;
addNetwork: (network: Network) => void;
removeNetwork: (networkId: Network['netid']) => void;
updateNetwork: (networkId: Network['netid'], newNetwork: Network) => void;
// updateNetwork: (networkId: Network['netid'], newNetwork: Network) => void;
deleteNetwork: (networkId: Network['netid']) => void;
}

Expand All @@ -24,33 +24,33 @@ const createNetworkSlice: StateCreator<INetworkSlice, [], [], INetworkSlice> = (
async fetchNetworks() {
try {
set(() => ({ isFetchingNetworks: true }));
const networks = (await NetworksService.getNetworks()).data ?? [];
const nets = (await NetworksService.getNetworksWithStats()).data.Response ?? [];
set(() => ({
networks: networks.map((network) => convertNetworkPayloadToUiNetwork(network)),
networks: nets.map((ns) => ({ ...convertNetworkPayloadToUiNetwork(ns), hosts: ns.hosts })),
isFetchingNetworks: false,
}));
} catch (err) {
console.error(err);
set(() => ({ isFetchingNetworks: false }));
}
},
setNetworks: (networks: Network[]) => set(() => ({ networks: networks })),
// setNetworks: (networks: Network[]) => set(() => ({ networks: networks })),
addNetwork(network) {
set((state) => ({ networks: [...state.networks, network] }));
set((state) => ({ networks: [...state.networks, { ...network, hosts: 0 }] }));
},
removeNetwork(networkId) {
set((state) => ({ networks: state.networks.filter((network) => network.netid !== networkId) }));
},
updateNetwork(networkId, newNetwork) {
set((state) => ({
networks: state.networks.map((network) => {
if (network.netid === networkId) {
return newNetwork;
}
return network;
}),
}));
},
// updateNetwork(networkId, newNetwork) {
// set((state) => ({
// networks: state.networks.map((network) => {
// if (network.netid === networkId) {
// return newNetwork;
// }
// return network;
// }),
// }));
// },
deleteNetwork(networkId) {
set((state) => ({ networks: state.networks.filter((network) => network.netid !== networkId) }));
},
Expand Down
Loading