diff --git a/backend/models/configItemsModel.js b/backend/models/configItemsModel.js index b3f2410..aecf8bd 100644 --- a/backend/models/configItemsModel.js +++ b/backend/models/configItemsModel.js @@ -76,6 +76,7 @@ export const updateConfigItemById = async (data, result) => { export const insertConfigItem = async (data, result) => { try { const results = await ownConn.query(`INSERT INTO changedb(assetName, customerID, customer, location, remoteLocation, type, description, notes, state, lastView, user, hardwareBool, model, serialnumber, CPU, RAM, storageConfiguration, miscellaneous, softwareBool, software, version, license, networkBool, IPv4, IPv6, MAC, subnetmask) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [data.assetName, data.customerID, data.customer, data.location, data.remoteLocation, data.type, data.description, data.notes, data.state, data.lastView, data.user, data.hardwareBool, data.model, data.serialnumber, data.CPU, data.RAM, data.storageConfiguration, data.miscellaneous, data.softwareBool, data.software, data.version, data.license, data.networkBool, data.IPv4, data.IPv6, data.MAC, data.subnetmask]) + results.insertId = results.insertId.toString(); result(null, results); } catch (err) { diff --git a/components/ClientSearch.vue b/components/ClientSearch.vue index 4734068..9feaffd 100644 --- a/components/ClientSearch.vue +++ b/components/ClientSearch.vue @@ -1,14 +1,35 @@ Client - ... + {{ clientFilter }} + @@ -241,7 +353,6 @@ export default { flex-direction: column; align-items: flex-start; justify-content: center; - width: 100%; padding: 1.25rem 1.875rem; border-radius: 0.625rem; box-shadow: 0.25rem 0.25rem 0.25rem 0rem rgba(0, 0, 0, 0.25); diff --git a/components/server/AssetTable.vue b/components/server/AssetTable.vue index 877096b..bead5ef 100644 --- a/components/server/AssetTable.vue +++ b/components/server/AssetTable.vue @@ -1,4 +1,9 @@ + + Config item + + Last viewed: @@ -49,10 +54,11 @@ @@ -222,7 +375,6 @@ export default { flex-direction: column; align-items: flex-start; justify-content: center; - width: 100%; padding: 1.25rem 1.875rem; border-radius: 0.625rem; box-shadow: 0.25rem 0.25rem 0.25rem 0rem rgba(0, 0, 0, 0.25); @@ -306,6 +458,42 @@ export default { border-radius: 0.3125rem; } +.saveNewItem-darkmode { + background: #2c2c2c; + color: #fff; + font: 400 0.875rem/1.875rem Overpass, sans-serif; + border: none; + padding: 1rem 1.875rem; + width: 8%; + border-radius: 0.625rem; + box-shadow: 0.25rem 0.25rem 0.25rem 0rem rgba(0, 0, 0, 0.25); +} + +.saveNewItem-lightmode { + background: #EBEBEB; + color: #212121; + font: 400 0.875rem/1.875rem Overpass, sans-serif; + border: none; + padding: 1rem 1.875rem; + width: 8%; + border-radius: 0.625rem; + box-shadow: 0.25rem 0.25rem 0.25rem 0rem rgba(0, 0, 0, 0.25); +} + +.saveNewItem-darkmode:hover { + background-color: #444444; + cursor: pointer; +} + +.saveNewItem-lightmode:hover { + background-color: #ACACAC; + cursor: pointer; +} + +#saveNewItem { + text-align: center; +} + .input { border: none; } diff --git a/components/server/SoftwareSpecifications.vue b/components/server/SoftwareSpecifications.vue index 932b2bb..9f6a619 100644 --- a/components/server/SoftwareSpecifications.vue +++ b/components/server/SoftwareSpecifications.vue @@ -1,5 +1,6 @@ - + Software specifications: @@ -43,6 +44,41 @@ + + Software specifications: + + + + + + Software + + Version + License + + + + + + + + + + + + + + + + + diff --git a/middleware/auth.js b/middleware/auth.js new file mode 100644 index 0000000..22abc8d --- /dev/null +++ b/middleware/auth.js @@ -0,0 +1,12 @@ +// export default function ({ route, redirect }) { +// // Check if user is not authenticated and trying to access a page other than /login +// if (!isAuthenticated() && route.path !== '/login') { +// return redirect('/login'); +// } +// } + +// function isAuthenticated() { +// // Implement authentication logic +// return false +// // Return true if authenticated, false otherwise +// } \ No newline at end of file diff --git a/nuxt.config.ts b/nuxt.config.ts index aaecfc9..db98ff1 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -1,4 +1,7 @@ // https://nuxt.com/docs/api/configuration/nuxt-config +import type { + NuxtPage +} from 'nuxt/schema' export default defineNuxtConfig({ devtools: { enabled: true }, @@ -10,10 +13,27 @@ export default defineNuxtConfig({ }, vite: { server: { - cors: { + cors: { origin: true, optionsSuccessStatus: 204, }, } - } + }, + // hooks: { + // 'pages:extend'(pages) { + // function setMiddleware(pages: NuxtPage[]) { + // for (const page of pages) { + // if (/* some condition */ true) { + // page.meta ||= {} + // // Note that this will override any middleware set in `definePageMeta` in the page + // page.meta.middleware = ['auth'] + // } + // if (page.children) { + // setMiddleware(page.children) + // } + // } + // } + // setMiddleware(pages) + // } + // } }) diff --git a/plugins/vuex.js b/plugins/vuex.js index 17033f3..7eb420a 100644 --- a/plugins/vuex.js +++ b/plugins/vuex.js @@ -4,18 +4,52 @@ const store = createStore({ state() { return { assetEditable: false, + assetFiltered: false, + assetSearchable: false, deleteAsset: false, onAssetlist: true, onCustomerAssetlist: false, onAsset: false, onSolutionlistAsset: false, - chosenAssetId: -1 + chosenAssetId: -1, + filteredAssetbyClient: '', + newAsset: false, + newAssetName: '', + newCustomerID: '', + newCustomer: '', + newLocation: '', + newRemoteLocation: '', + newType: '', + newDescription: '', + newNotes: '', + newState: '', + newLastView: '', + newUser: '', + hardwareBool: false, + newModel: '', + newSerialnumber: '', + newCPU: '', + newRAM: '', + newStorageConfiguration: '', + newMiscellaneous: '', + softwareBool: false, + newSoftware: '', + newVersion: '', + newLicense: '', }; }, mutations: { toggleEditableAsset(state) { state.assetEditable = !state.assetEditable }, + toggleFilteredAsset(state) { + if (state.assetFiltered == false) { + state.assetFiltered = true + state.assetSearchable = false + } else { + state.assetFiltered = false + } + }, changeToAssetlist(state) { state.onAssetlist = true state.onCustomerAssetlist = false @@ -44,14 +78,89 @@ const store = createStore({ state.chosenAssetId = id }, resetAssetStore(state) { - state.chosenAssetId = -1 state.assetEditable = false + state.assetFiltered = false + state.assetSearchable = false + state.deleteAsset = false + state.chosenAssetId = -1 + state.filteredAssetbyClient = '' + state.newAsset = false + state.newAssetName = '' + state.newCustomerID = '' + state.newCustomer = '' + state.newLocation = '' + state.newRemoteLocation = '' + state.newType = '' + state.newDescription = '' + state.newNotes = '' + state.newState = '' + state.newLastView = '' + state.newUser = '' + state.hardwareBool = false + state.newModel = '' + state.newSerialnumber = '' + state.newCPU = '' + state.newRAM = '' + state.newStorageConfiguration = '' + state.newMiscellaneous = '' + state.softwareBool = false + state.newSoftware = '' + state.newVersion = '' + state.newLicense = '' }, doDeleteAsset(state) { state.deleteAsset = true }, undoDeleteAsset(state) { state.deleteAsset = false + }, + updateAssetFilterbyClient(state, client) { + state.filteredAssetbyClient = client + }, + toggleAssetSearchable(state) { + if (state.assetSearchable == false) { + state.assetSearchable = true + state.assetFiltered = false + } else { + state.assetSearchable = false + } + state.filteredAssetbyClient = '' + }, + addNewAsset(state) { + state.newAsset = true + state.assetEditable = false + state.assetFiltered = false + state.assetSearchable = false + state.onAssetlist = false + state.onCustomerAssetlist = false + state.onAsset = true + state.onSolutionlistAsset = false + }, + updateAssetComponent(state, asset) { + state.newAssetName = asset.assetName + state.newCustomerID = asset.customerId + state.newCustomer = asset.customer + state.newLocation = asset.location + state.newRemoteLocation = asset.remoteLocation + state.newType = asset.type + state.newDescription = asset.description + state.newNotes = asset.notes + state.newState = asset.state + }, + updateHardwareComponent(state, asset) { + state.hardwareBool = asset.hardwareBool + state.newModel = asset.model + state.newSerialnumber = asset.serialnumber + state.newCPU = asset.CPU + state.newRAM = asset.RAM + state.newStorageConfiguration = asset.storageConfig + state.newMiscellaneous = asset.miscellaneous + }, + updateSoftwareComponent(state, asset) { + state.softwareBool = asset.softwareBool + state.newSoftware = asset.software + state.newVersion = asset.version + state.newLicense = asset.license } }, }); diff --git a/server/api/addConfigItem.ts b/server/api/addConfigItem.ts new file mode 100644 index 0000000..4ece70d --- /dev/null +++ b/server/api/addConfigItem.ts @@ -0,0 +1,21 @@ +import { errorMsg } from "../middleware/configItems"; +import { OutgoingMessage } from 'http'; + +export default defineEventHandler(async (event) => { + + const headers: Record[1]> = { + 'Access-Control-Allow-Origin': 'https://tueitapp.tueit.de', + 'Access-Control-Allow-Headers': 'authorization, content-type', + 'Access-Control-Allow-Methods': 'OPTIONS,GET,HEAD,PUT,PATCH,POST,DELETE', + }; + setResponseHeaders(event, headers) + + if (!(errorMsg === '')) { + throw createError({ + statusCode: 400, + statusMessage: errorMsg, + }) + } + + setResponseStatus(event, 200) +}) diff --git a/server/api/getSelectedConfigItemsByAsset/[id].ts b/server/api/getSelectedConfigItemsByAsset/[id].ts new file mode 100644 index 0000000..e77de56 --- /dev/null +++ b/server/api/getSelectedConfigItemsByAsset/[id].ts @@ -0,0 +1,22 @@ +import { selectedConfigItemsByAsset, errorMsg } from "../../middleware/configItems"; +import { OutgoingMessage } from 'http'; + +export default defineEventHandler(async (event) => { + + const headers: Record[1]> = { + 'Access-Control-Allow-Origin': 'https://tueitapp.tueit.de', + 'Access-Control-Allow-Headers': 'authorization, content-type', + 'Access-Control-Allow-Methods': 'OPTIONS,GET,HEAD,PUT,PATCH,POST,DELETE', + }; + setResponseHeaders(event, headers) + + if (!(errorMsg === '')) { + throw createError({ + statusCode: 400, + statusMessage: errorMsg, + }) + } + + setResponseStatus(event, 200) + return selectedConfigItemsByAsset +}) diff --git a/server/api/getSelectedConfigItemsByClient/[id].ts b/server/api/getSelectedConfigItemsByClient/[id].ts new file mode 100644 index 0000000..899ba8c --- /dev/null +++ b/server/api/getSelectedConfigItemsByClient/[id].ts @@ -0,0 +1,22 @@ +import { selectedConfigItemsByClient, errorMsg } from "../../middleware/configItems"; +import { OutgoingMessage } from 'http'; + +export default defineEventHandler(async (event) => { + + const headers: Record[1]> = { + 'Access-Control-Allow-Origin': 'https://tueitapp.tueit.de', + 'Access-Control-Allow-Headers': 'authorization, content-type', + 'Access-Control-Allow-Methods': 'OPTIONS,GET,HEAD,PUT,PATCH,POST,DELETE', + }; + setResponseHeaders(event, headers) + + if (!(errorMsg === '')) { + throw createError({ + statusCode: 400, + statusMessage: errorMsg, + }) + } + + setResponseStatus(event, 200) + return selectedConfigItemsByClient +}) diff --git a/server/middleware/configItems.ts b/server/middleware/configItems.ts index 728c0d5..efbd1ad 100644 --- a/server/middleware/configItems.ts +++ b/server/middleware/configItems.ts @@ -5,6 +5,8 @@ import https from 'https'; let configItems = []; let configItem = {}; let errorMsg = ''; +let selectedConfigItemsByClient = []; +let selectedConfigItemsByAsset = []; export default defineEventHandler(async (event) => { @@ -108,6 +110,34 @@ export default defineEventHandler(async (event) => { } } + if (event.path.startsWith("/api/addConfigItem")) { + const body = await readBody(event) + // add the config item in the backend + try { + let res = await axiosInstance.post(`https://${serversideConfig.url}:${serversideConfig.port}/configItems`, body); + } catch (err) { + if (axios.isAxiosError(err)) { + const axiosError = err as AxiosError; + + if (axiosError.response) { + // Axios error + console.error(axiosError.response.data.message); + errorMsg = axiosError.response.data.message; + } else if (axiosError.request) { + console.log(err) + // If error was caused by the request + console.error(axiosError.request); + } else { + // Other errors + console.error('Error', axiosError.message); + } + } else { + // No AxiosError + console.error('Error', err); + } + } + } + if (event.path.startsWith("/api/deleteConfigItem")) { let itemId = null; const path = event._path; @@ -139,6 +169,70 @@ export default defineEventHandler(async (event) => { } } } + + if (event.path.startsWith("/api/getSelectedConfigItemsByClient")) { + // get selected config items object by client from backend + let filteredClient = null; + const path = event._path; + const pathSegments = path.split('/'); + filteredClient = pathSegments[pathSegments.length - 1]; + + try { + let res = await axiosInstance.get(`https://${serversideConfig.url}:${serversideConfig.port}/selectedConfigItemsByCustomer/${filteredClient}`); + selectedConfigItemsByClient = res.data; + } catch (err) { + if (axios.isAxiosError(err)) { + const axiosError = err as AxiosError; + + if (axiosError.response) { + // Axios error + console.error(axiosError.response.data.message); + errorMsg = axiosError.response.data.message; + } else if (axiosError.request) { + // If error was caused by the request + console.error(axiosError.request); + } else { + // Other errors + console.error('Error', axiosError.message); + } + } else { + // No AxiosError + console.error('Error', err); + } + } + } + + if (event.path.startsWith("/api/getSelectedConfigItemsByAsset")) { + // get selected config items object by asset from backend + let filteredAsset = null; + const path = event._path; + const pathSegments = path.split('/'); + filteredAsset = pathSegments[pathSegments.length - 1]; + + try { + let res = await axiosInstance.get(`https://${serversideConfig.url}:${serversideConfig.port}/selectedConfigItemsByAssetName/${filteredAsset}`); + selectedConfigItemsByAsset = res.data; + } catch (err) { + if (axios.isAxiosError(err)) { + const axiosError = err as AxiosError; + + if (axiosError.response) { + // Axios error + console.error(axiosError.response.data.message); + errorMsg = axiosError.response.data.message; + } else if (axiosError.request) { + // If error was caused by the request + console.error(axiosError.request); + } else { + // Other errors + console.error('Error', axiosError.message); + } + } else { + // No AxiosError + console.error('Error', err); + } + } + } }) -export { configItems, configItem, errorMsg }; \ No newline at end of file +export { configItems, configItem, selectedConfigItemsByClient, selectedConfigItemsByAsset, errorMsg }; \ No newline at end of file
...
{{ clientFilter }}