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

Update public ip table with vuetify server side table #3946

Open
wants to merge 10 commits into
base: development
Choose a base branch
from
1 change: 1 addition & 0 deletions packages/gridproxy_client/src/builders/public_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export * from "./gateways";
export * from "./nodes";
export * from "./stats";
export * from "./twins";
export * from "./public_ips";
54 changes: 54 additions & 0 deletions packages/gridproxy_client/src/builders/public_ips.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { assertBoolean, assertId, assertNatural, assertString } from "../utils";
import { AbstractBuilder, BuilderMapper, BuilderMethods, BuilderValidator } from "./abstract_builder";
import { SortBy, SortOrder } from "./nodes";

export interface PublicIpQuery {
page: number;
size: number;
retCount: boolean;
randomize: boolean;
sortBy: SortBy;
sortOrder: SortOrder;
farmIds: number;
ip: string;
gateway: string;
free: boolean;
}

const PUBLICIPS_MAPPER: BuilderMapper<PublicIpQuery> = {
page: "page",
size: "size",
retCount: "ret_count",
randomize: "randomize",
sortBy: "sort_by",
sortOrder: "sort_order",
farmIds: "farm_ids",
ip: "ip",
gateway: "gateway",
free: "free",
};

const PUBLICIPS_VALIDATOR: BuilderValidator<PublicIpQuery> = {
page: assertNatural,
size: assertNatural,
retCount: assertBoolean,
randomize: assertBoolean,
sortBy: assertString,
sortOrder: assertString,
farmIds: assertId,
ip: assertString,
gateway: assertString,
free: assertBoolean,
};

export class PublicIpBuilder extends AbstractBuilder<PublicIpQuery> {
constructor(public uri: string, queries: Partial<PublicIpQuery> = {}) {
super({
mapper: PUBLICIPS_MAPPER,
validator: PUBLICIPS_VALIDATOR,
queries,
});
}
}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface PublicIpBuilder extends BuilderMethods<PublicIpQuery, PublicIpBuilder> {}
4 changes: 3 additions & 1 deletion packages/gridproxy_client/src/modules/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { ContractsClient } from "./contracts";
import { FarmsClient } from "./farms";
import { GatewaysClient } from "./gateways";
import { NodesClient } from "./nodes";
import { PublicIpsClient } from "./public_ips";
import { StatsClient } from "./stats";
import { TwinsClient } from "./twins";

export default class GridProxyClient {
private readonly __uri: string;

Expand All @@ -20,6 +20,7 @@ export default class GridProxyClient {
this.twins = new TwinsClient(this.__uri);
this.nodes = new NodesClient(this.__uri, this.farms, this.twins);
this.stats = new StatsClient(this.__uri);
this.publicIps = new PublicIpsClient(this.__uri);
}

public contracts: ContractsClient;
Expand All @@ -28,4 +29,5 @@ export default class GridProxyClient {
public nodes: NodesClient;
public stats: StatsClient;
public twins: TwinsClient;
public publicIps: PublicIpsClient;
}
1 change: 1 addition & 0 deletions packages/gridproxy_client/src/modules/public_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ export * from "./gateways";
export * from "./nodes";
export * from "./stats";
export * from "./twins";
export * from "./public_ips";
35 changes: 35 additions & 0 deletions packages/gridproxy_client/src/modules/public_ips.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import type { Pagination } from "../builders/abstract_builder";
import { PublicIpBuilder, PublicIpQuery } from "../builders/public_api";
import { resolvePaginator } from "../utils";
import { AbstractClient } from "./abstract_client";
import { PublicIp } from "./farms";

export class PublicIpsClient extends AbstractClient<PublicIpBuilder, PublicIpQuery> {
constructor(uri: string) {
super({
uri,
Builder: PublicIpBuilder,
});
}

public async list(queries: Partial<PublicIpQuery> = {}) {
const res = await this.builder(queries).build("/public_ips");
return resolvePaginator<PublicIp[]>(res);
}

public async listAll(queries: Partial<PublicIpQuery> = {}) {
const { count } = await this.list({
...queries,
size: 50,
page: 1,
retCount: true,
});
const promises: Promise<Pagination<PublicIp[]>>[] = [];
const pages = Math.ceil(count! / 50);
for (let i = 0; i < pages; i++) {
promises.push(this.list({ ...queries, size: 50, page: i + 1 }));
}
const publicIps = await Promise.all(promises);
return publicIps.map(node => node.data).flat(1);
}
}
2 changes: 1 addition & 1 deletion packages/playground/src/dashboard/components/add_ip.vue
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ export default {
});
}
context.emit("ip-added-successfully");
createCustomToast("IP is added successfully.", ToastType.success);
createCustomToast("IP is added successfully. It may takes a few seconds to reflect", ToastType.success);
showDialogue.value = false;
} catch (error) {
if (error instanceof TFChainError && error.keyError === "IpExists") {
Expand Down
81 changes: 54 additions & 27 deletions packages/playground/src/dashboard/components/public_ips_table.vue
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image
after changing the counts to 5 it is not changed and stay at 10

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also the. farm contains 17 ip and I can list only 10
image

Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
<template>
<div>
<ListTable
<v-data-table-server
v-model="selectedItems"
:headers="headers"
:items="publicIps"
:loading="loading"
:items-length="publicIpsCount"
:loading="loadingIps"
v-model:items-per-page="pageSize"
@update:options="
(options: any ) => {
page = options.page;
pageSize = options.itemsPerPage;
getFarmPublicIp(true, { page, size: pageSize });
}
"
:items-per-page-options="[
{ value: 5, title: '5' },
{ value: 10, title: '10' },
Expand All @@ -12,7 +22,8 @@
]"
no-data-text="No IPs added on this farm"
:deleting="isRemoving"
v-model="selectedItems"
show-select
return-object
>
<template v-slot:top>
<v-alert>
Expand All @@ -27,23 +38,24 @@
</template>

<template #[`item.contractId`]="{ item }">
{{ item.contractId ?? "-" }}
{{ item.contract_id ?? "-" }}
</template>
</ListTable>
</v-data-table-server>

<div v-if="publicIps.length > 0" class="d-flex align-end justify-end">
<v-btn
class="ma-3"
class="my-3"
color="error"
:disabled="selectedItems.length == 0 || isRemoving"
prepend-icon="mdi-delete"
:disabled="selectedItems.length === 0 || isRemoving"
@click="showDialogue = true"
>
Delete
</v-btn>
</div>
<v-dialog v-model="showDialogue" max-width="600" attach="#modals">
<v-card>
<v-card-title class="text-subtitle-1">
<v-card-title class="bg-primary text-subtitle-1">
<strong>Delete the following IPs?</strong>
</v-card-title>
<v-card-text>
Expand All @@ -58,7 +70,7 @@
text="Delete"
:loading="isRemoving"
color="error"
:disabled="isRemoving"
:disabled="selectedItems.length == 0 || isRemoving"
@click="removeFarmIps"
></v-btn>
</v-card-actions>
Expand All @@ -69,17 +81,16 @@

<script lang="ts">
import type { RemoveFarmIPModel } from "@threefold/grid_client";
import type { PublicIp } from "@threefold/tfchain_client";
import type { PublicIp } from "@threefold/gridproxy_client";
import { onMounted, ref, watch } from "vue";

import ListTable from "@/components/list_table.vue";
import { gridProxyClient } from "@/clients";
import { useGrid } from "@/stores";
import { IPType } from "@/utils/types";

import { createCustomToast, ToastType } from "../../utils/custom_toast";
export default {
name: "PublicIPsTable",
components: { ListTable },
props: {
farmId: {
type: Number,
Expand Down Expand Up @@ -109,7 +120,7 @@ export default {
},
] as any;
const publicIps = ref<PublicIp[]>([]);
const loading = ref(false);
const publicIpsCount = ref();
const loadingIps = ref(false);
const showDialogue = ref(false);
const type = ref(IPType.single);
Expand All @@ -119,31 +130,42 @@ export default {
const isRemoving = ref(false);
const selectedItems = ref<any[]>([]);
const items = ref<RemoveFarmIPModel[]>([]);
const page = ref<number>(1);
const pageSize = ref(5);

onMounted(async () => {
await getFarmByID(props.farmId);
});

async function getFarmByID(id: number) {
loadingIps.value = true;
async function getFarmPublicIp(retCount = false, options = { page: 1, size: 10 }) {
try {
const farm = await gridStore.grid.farms.getFarmByID({ id });
publicIps.value = farm.publicIps as unknown as PublicIp[];
loadingIps.value = true;
const { data, count } = await gridProxyClient.publicIps.list({
retCount,
page: options.page,
size: options.size,
free: true,
farmIds: props.farmId,
});
publicIps.value = data as PublicIp[];
if (retCount) publicIpsCount.value = count || 0;
} catch (error) {
createCustomToast(`Failed to get public IPs! ${error}`, ToastType.danger);
} finally {
loadingIps.value = false;
}
loadingIps.value = false;
}

async function removeFarmIps() {
try {
isRemoving.value = true;
loadingIps.value = true;
items.value = selectedItems.value.map(item => ({
ip: item.ip,
farmId: props.farmId,
}));
await gridStore.grid.farms.removeFarmIps(items.value);
createCustomToast("IP is deleted successfully!", ToastType.success);
await getFarmByID(props.farmId);
setTimeout(async () => {
await getFarmPublicIp(false, { page: page.value, size: pageSize.value });
createCustomToast("IP is deleted successfully!", ToastType.success);
loadingIps.value = false;
}, 20000);
} catch (error) {
console.log(error);
createCustomToast("Failed to delete IP!", ToastType.danger);
Expand All @@ -156,11 +178,13 @@ export default {
watch(
() => props.refreshPublicIPs,
() => {
getFarmByID(props.farmId);
loadingIps.value = true;
setTimeout(async () => {
await getFarmPublicIp(false, { page: page.value, size: pageSize.value });
}, 20000);
},
{ deep: true },
);

return {
gridStore,
headers,
Expand All @@ -169,12 +193,15 @@ export default {
publicIP,
toPublicIP,
gateway,
loading,
showDialogue,
isRemoving,
removeFarmIps,
selectedItems,
loadingIps,
getFarmPublicIp,
pageSize,
page,
publicIpsCount,
};
},
};
Expand Down
Loading