diff --git a/package-lock.json b/package-lock.json index 412b0ee..9b4eac1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,6 +7,7 @@ "": { "version": "0.0.0", "dependencies": { + "@vueuse/core": "^4.7.0", "idb-keyval": "^5.0.4", "vue": "^3.0.5", "vue-router": "^4.0.5" @@ -214,6 +215,73 @@ "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.0.11.tgz", "integrity": "sha512-b+zB8A2so8eCE0JsxjL24J7vdGl8rzPQ09hZNhystm+KqSbKcAej1A+Hbva1rCMmTTqA+hFnUSDc5kouEo0JzA==" }, + "node_modules/@vueuse/core": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-4.7.0.tgz", + "integrity": "sha512-0Kmo+Gqn47aCg6HHFUvXabD/T5haWyC5pk2PEzaGay9dGE7D+sc05Y1h2MylzcFzRX/2G4anOxSuDqmvQ/GunQ==", + "dependencies": { + "@vueuse/shared": "4.7.0", + "vue-demi": "latest" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/core/node_modules/vue-demi": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.7.4.tgz", + "integrity": "sha512-PT0qzI9Rp8R8eUAsTPXADC+KAZdrMufmbZqEMMqvaiesWyjCpgyuuvS5Su8cvBjK9RevLT/YfFiKWxc8YB9/8g==", + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-beta.1", + "vue": "^2.6.0 || >=3.0.0-rc.1" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/@vueuse/shared": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-4.7.0.tgz", + "integrity": "sha512-a9wmH6g+dh6ALeOejIL53s1HkASyOldbHunwEUEtRdgQyUCnU+RRiYTZlNLEyt1r79kPtnBjp5fHq0X36H96MA==", + "dependencies": { + "vue-demi": "latest" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/shared/node_modules/vue-demi": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.7.4.tgz", + "integrity": "sha512-PT0qzI9Rp8R8eUAsTPXADC+KAZdrMufmbZqEMMqvaiesWyjCpgyuuvS5Su8cvBjK9RevLT/YfFiKWxc8YB9/8g==", + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-beta.1", + "vue": "^2.6.0 || >=3.0.0-rc.1" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, "node_modules/acorn": { "version": "7.4.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", @@ -2337,6 +2405,39 @@ "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.0.11.tgz", "integrity": "sha512-b+zB8A2so8eCE0JsxjL24J7vdGl8rzPQ09hZNhystm+KqSbKcAej1A+Hbva1rCMmTTqA+hFnUSDc5kouEo0JzA==" }, + "@vueuse/core": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-4.7.0.tgz", + "integrity": "sha512-0Kmo+Gqn47aCg6HHFUvXabD/T5haWyC5pk2PEzaGay9dGE7D+sc05Y1h2MylzcFzRX/2G4anOxSuDqmvQ/GunQ==", + "requires": { + "@vueuse/shared": "4.7.0", + "vue-demi": "latest" + }, + "dependencies": { + "vue-demi": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.7.4.tgz", + "integrity": "sha512-PT0qzI9Rp8R8eUAsTPXADC+KAZdrMufmbZqEMMqvaiesWyjCpgyuuvS5Su8cvBjK9RevLT/YfFiKWxc8YB9/8g==", + "requires": {} + } + } + }, + "@vueuse/shared": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-4.7.0.tgz", + "integrity": "sha512-a9wmH6g+dh6ALeOejIL53s1HkASyOldbHunwEUEtRdgQyUCnU+RRiYTZlNLEyt1r79kPtnBjp5fHq0X36H96MA==", + "requires": { + "vue-demi": "latest" + }, + "dependencies": { + "vue-demi": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.7.4.tgz", + "integrity": "sha512-PT0qzI9Rp8R8eUAsTPXADC+KAZdrMufmbZqEMMqvaiesWyjCpgyuuvS5Su8cvBjK9RevLT/YfFiKWxc8YB9/8g==", + "requires": {} + } + } + }, "acorn": { "version": "7.4.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", diff --git a/package.json b/package.json index 6fd85fc..9e729b1 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "format": "npx prettier --write ." }, "dependencies": { + "@vueuse/core": "^4.7.0", "idb-keyval": "^5.0.4", "vue": "^3.0.5", "vue-router": "^4.0.5" diff --git a/src/api/index.ts b/src/api/index.ts index 2996b78..10ef6b6 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -3,7 +3,9 @@ import { AccessPointCreateResponse, cSite, LoginResponse, + RegisterAccessPointResponse, Site, + StateOfTask, token, } from "./types"; import { get as idbGet, set as idbSet, del as idbDel } from "idb-keyval"; @@ -105,6 +107,10 @@ export async function getSites(): Promise { return request("/sites", { auth: true, method: HTTPMethod.GET }); } +export async function getSite(id: number): Promise { + return request(`/sites/${id}`, { auth: true, method: HTTPMethod.GET }); +} + export async function createSite(site: Site) { return request( "/sites", @@ -134,8 +140,38 @@ export async function createAccessPoint( ap: AccessPoint ): Promise { return request( - "/aps", - { auth: true, method: HTTPMethod.POST }, - ap + `/aps${ap.id ? "/" + ap.id : ""}`, + { auth: true, method: ap.id ? HTTPMethod.PATCH : HTTPMethod.POST }, + Object.fromEntries( + Object.entries(ap).filter(([k, v]) => + [ + "ap_name", + "site_id", + "mac_address", + "serialnumber", + "location", + "model", + "group", + "appointment", + "comment", + ].includes(k) + ) + ) ); } + +export async function registerAccessPoint( + apName: string +): Promise { + return request( + `/${import.meta.env.DEV ? "test" : "register-ap"}/${apName}`, + { auth: true, method: HTTPMethod.POST } + ); +} + +export async function getStateOfTask(id: string): Promise { + return request(`/tasks/${id}`, { + auth: true, + method: HTTPMethod.GET, + }); +} diff --git a/src/api/types.ts b/src/api/types.ts index 465d4c9..99aacf1 100644 --- a/src/api/types.ts +++ b/src/api/types.ts @@ -21,8 +21,8 @@ export interface cSite { } export interface AccessPoint { - id: number; - site_id: number; + id?: number; + site_id?: number; ap_name: string; serialnumber: string; comment: string; @@ -30,7 +30,7 @@ export interface AccessPoint { location: string; mac_address: string; model: string; - appointment: Date; + appointment?: Date; new_switchport_id?: any; new_userport_id?: any; old_switchport_id?: any; @@ -42,3 +42,23 @@ export interface AccessPoint { export interface AccessPointCreateResponse { "ap-id": number; } + +export interface RegisterAccessPointResponse { + status: string; + "task-id": string; +} + +export interface StateOfTask { + state: string; + current: string; + total: number; + status: string; + result?: TaskResult; +} + +export interface TaskResult { + switchportid: number; + switchportid_new: number; + userportid: number; + userportid_new: number; +} diff --git a/src/components/VNav.vue b/src/components/VNav.vue index d557241..a8c962c 100644 --- a/src/components/VNav.vue +++ b/src/components/VNav.vue @@ -150,6 +150,14 @@ export default { name: "AccessPoints", to: "AccessPoints", }, + { + name: "Create AccessPoint", + to: "CreateAccessPoint", + }, + { + name: "Register AccessPoint", + to: "RegisterAccessPoint", + }, ]); const route = useRoute(); const activeRoute = computed(() => route.name); diff --git a/src/components/VTaskState.vue b/src/components/VTaskState.vue new file mode 100644 index 0000000..c1a222d --- /dev/null +++ b/src/components/VTaskState.vue @@ -0,0 +1,70 @@ + + + + + diff --git a/src/router/index.ts b/src/router/index.ts index 00de571..e65763f 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -4,6 +4,8 @@ const Settings = () => import("../views/Settings.vue"); const Login = () => import("../views/Login.vue"); const Sites = () => import("../views/Sites.vue"); const AccessPoints = () => import("../views/AccessPoints.vue"); +const CreateAccessPoint = () => import("../views/CreateAccessPoint.vue"); +const RegisterAccessPoint = () => import("../views/RegisterAccessPoint.vue"); import { isLoggedIn } from "../api"; const routes: RouteRecordRaw[] = [ @@ -32,7 +34,28 @@ const routes: RouteRecordRaw[] = [ path: "/aps", name: "AccessPoints", component: AccessPoints, - props: (route) => ({ site: Number(route.query["site-id"]).valueOf() }), + props: (route) => ({ siteID: Number(route.query["site-id"]).valueOf() }), + }, + { + path: "/createAccessPoint", + name: "CreateAccessPoint", + component: CreateAccessPoint, + props: (route) => ({ siteID: Number(route.query["site-id"]).valueOf() }), + }, + { + path: "/editAccessPoint", + name: "EditAccessPoint", + component: CreateAccessPoint, + props: (route) => ({ + apID: Number(route.query["ap-id"]).valueOf(), + edit: true, + }), + }, + { + path: "/registerAccessPoint", + name: "RegisterAccessPoint", + component: RegisterAccessPoint, + props: (route) => ({ apID: Number(route.query["ap-id"]).valueOf() }), }, ]; diff --git a/src/views/AccessPoints.vue b/src/views/AccessPoints.vue index dd7dde7..42caf4e 100644 --- a/src/views/AccessPoints.vue +++ b/src/views/AccessPoints.vue @@ -26,11 +26,18 @@ {{ ap.model }} {{ ap.comment }} - + Edit + Register + @@ -38,24 +45,28 @@ + + diff --git a/src/views/RegisterAccessPoint.vue b/src/views/RegisterAccessPoint.vue new file mode 100644 index 0000000..74b9af3 --- /dev/null +++ b/src/views/RegisterAccessPoint.vue @@ -0,0 +1,83 @@ + + + + + diff --git a/src/views/Sites.vue b/src/views/Sites.vue index 5aea3bf..24dcaf1 100644 --- a/src/views/Sites.vue +++ b/src/views/Sites.vue @@ -25,11 +25,11 @@ {{ site.id }} {{ site.default_prefix }} - + > ([]); + const sites = reactive([]); async function getSites() { - await apiGetSites().then((s) => void (sites.value = s)); + await apiGetSites().then((s) => void Object.assign(sites, s)); } await getSites();