diff --git a/api/treehole/tag.ts b/api/treehole/tag.ts index 0a59ba9..375bc61 100644 --- a/api/treehole/tag.ts +++ b/api/treehole/tag.ts @@ -56,12 +56,12 @@ export const tagCreateSchema = { name: 'tag-create', base: 'TREEHOLE', path: '/tags', - method: 'CREATE', + method: 'POST', token: true, requestSchema: tagCreateRequestSchema, responseSchema: { success: { - status: [200], + status: [200, 201], schema: tagCreateSuccessfulResponseSchema } } @@ -84,7 +84,7 @@ export const tagDeleteResponseSchema = { export const tagDeleteSchema = { name: 'tag-delete', base: 'TREEHOLE', - path: '/api/tags/:id:', + path: '/tags/:id:', method: 'DELETE', token: true, requestSchema: tagDeleteRequestSchema, diff --git a/nuxt.config.ts b/nuxt.config.ts index 2455e66..168f1c6 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -1,5 +1,8 @@ // https://nuxt.com/docs/api/configuration/nuxt-config +const dotenv = require('dotenv') +dotenv.config() + export default defineNuxtConfig({ modules: [ '@element-plus/nuxt', @@ -19,5 +22,19 @@ export default defineNuxtConfig({ authBase: '', treeHoleBase: '', } + }, + nitro: { + devProxy: { + "/AUTH": { + target: process.env.NUXT_PUBLIC_AUTH_BASE, + changeOrigin: true, + prependPath: true, + }, + "/TREEHOLE": { + target: process.env.NUXT_PUBLIC_TREE_HOLE_BASE, + changeOrigin: true, + prependPath: true, + } + } } }) diff --git a/pages/treehole/tag.vue b/pages/treehole/tag.vue index e2ffff1..d278ea6 100644 --- a/pages/treehole/tag.vue +++ b/pages/treehole/tag.vue @@ -80,31 +80,29 @@ layoutStore.path = [ { name: "Tag" } ] +// the following code is mess +// but it works + const current_page = ref(1) const search = reactive({ - all_tag: [], + all_tag: [], // all the tags fetched from the server filtered_tag: [], // all_tag filtered by tag - current_tag: [], - tag: "", - total_page: 0, - current_path: 1 + current_tag: [], // tags to be displayed + tag: "", // the regex user inputed + total_page: 0 }) -async function load() { - if (search.all_tag.length > 0) { - return; - } +async function load() { // load the tags from the server - const { type, data } = await callApi(tagListSchema, { tag: search.tag }) - // console.log(data) + const { type, data } = await callApi(tagListSchema, {}) + search.tag = "" if (type == 'success') { search.all_tag = data - dataChange(data) + dataChange(data) // dataChange called when filtered_tag should be changed. ElNotification({ title: 'Successfully loaded data', - // message: data.message, position: 'bottom-right', type: 'success' }) @@ -121,6 +119,8 @@ function dataChange(data) { } function handleTagInput() { + // when the input changes + // flush the filtered_tag try { let reg = new RegExp(search.tag) dataChange(search.all_tag.filter(item => reg.test(item.name))) @@ -130,7 +130,7 @@ function handleTagInput() { } } -function changePage(to) { +function changePage(to) { // the page changed, update the view current_page.value = to search.current_tag = search.filtered_tag.slice((current_page.value - 1) * 20, current_page.value * 20) } @@ -144,11 +144,12 @@ const transfer = reactive({ function handleTransfer(scope) { transfer.from_id = search.current_tag[scope].id - dialog_visibility.value = true + dialog_visibility.value = true // open the dialog } function closeDialog() { dialog_visibility.value = false + // do nothing transfer.to = "" } @@ -158,7 +159,7 @@ async function transfer_tag() { if (transfer.to.length == 0) { ElNotification({ title: 'Error', - message: 'Tag cannot be empty', + message: 'Tag cannot be empty.', position: 'bottom-right', type: 'error' }) @@ -173,32 +174,32 @@ async function transfer_tag() { const { type, data } = await callApi(tagCreateSchema, { name: transfer.to }) - console.log('create', type, data) + if (type !== 'success') { ElNotification({ title: 'Error', - // message: data.message, + message: 'Failed to create tag.', position: 'bottom-right', type: 'error' }) - return } - } - - // find if the target tag is the same as the current tag - if (target_tag.id == transfer.from_id) { + } else if (target_tag.id == transfer.from_id) { + // find if the target tag is the same as the current tag ElNotification({ title: 'Error', - message: 'Tag cannot be the same as the current tag', + message: 'Tag cannot be the same as the current tag.', position: 'bottom-right', type: 'error' }) - return } - const { type, data } = await callApi(tagDeleteSchema) + const { type, data } = await callApi(tagDeleteSchema, { + to: transfer.to // payloads + }, { + id: transfer.from_id // params + }) if (type !== 'success') { ElNotification({ @@ -218,6 +219,8 @@ async function transfer_tag() { type: 'success' }) + await load(); // the tags have changed, reload it to sync + transfer.to = "" } diff --git a/util/callApi.ts b/util/callApi.ts index 54b46e0..7fcd219 100644 --- a/util/callApi.ts +++ b/util/callApi.ts @@ -2,11 +2,7 @@ import { useUserStore } from "@/store/user" import Ajv, { type Schema } from 'ajv' const ajv = new Ajv() -export async function callApi(schema: any, payload: any, config: any = {}, param: any = {}) { - const runtimeConfig = useRuntimeConfig() - const AUTH = runtimeConfig.public.authBase - const TREEHOLE = runtimeConfig.public.treeHoleBase - const URL_MAPPER = { AUTH, TREEHOLE } +export async function callApi(schema: any, payload: any, param: any = {}, config: any = {}) { const NoResponse = { type: undefined, @@ -31,14 +27,15 @@ export async function callApi(schema: any, payload: any, config: any = {}, param config.headers["Authorization"] = `Bearer ${userStore.access_token}` } - let path = URL_MAPPER[schema.base] + schema.path + let path = `/${schema.base}${schema.path}` for (let cur_param in param) { + console.log(cur_param, param[cur_param]) path = path.replace(`:${cur_param}:`, param[cur_param]) } config.method = schema.method - + config.server = false config.lazy = false if (schema.method !== 'GET') { @@ -58,7 +55,6 @@ export async function callApi(schema: any, payload: any, config: any = {}, param await useFetch(path, config) for (let cur_schema in schema.responseSchema) { - // console.log(schema.responseSchema[cur_schema]) if (schema.responseSchema[cur_schema].status.includes(status_code) && ajv.validate(schema.responseSchema[cur_schema].schema, ret)) { return { diff --git a/util/webio.ts b/util/webio.ts deleted file mode 100644 index bef4e9d..0000000 --- a/util/webio.ts +++ /dev/null @@ -1,31 +0,0 @@ -interface WebIOConfig { - method: 'GET' | 'POST' | 'CREATE' | 'PUT' | 'DELETE', - data: any, - header: { - [key: string]: any - } -} - -interface WebIOResponse { - status_code: number - body: any -} - -export function webio(url: string, config: WebIOConfig): WebIOResponse { - let xhr = new XMLHttpRequest() - xhr.open(config.method, url) - xhr.setRequestHeader('Content-Type', 'application/json') - xhr.setRequestHeader('Accept', 'application/json') - for (let key in config.header) { - xhr.setRequestHeader(key, config.header[key]) - } - xhr.send(JSON.stringify(config.data)) - xhr.onload = function () { - return { status_code: xhr.status, body: JSON.parse(xhr.responseText) } - } - while (1); // waiting for the response - return { - status_code: 0, - body: null - } -} \ No newline at end of file