From 26609eb46c18d34eb3a1f77f54549f45918b82b4 Mon Sep 17 00:00:00 2001 From: Casey Wittrock Date: Mon, 20 Oct 2025 09:26:47 -0500 Subject: [PATCH] develop --- .../custom_ui/page/custom_ui/custom_ui.js | 13 +- frontend/index.html | 20 +-- frontend/package-lock.json | 141 +++++++++++++++++- frontend/package.json | 4 +- frontend/src/components/HelloWorld.vue | 51 +++---- frontend/src/components/SideBar.vue | 15 ++ frontend/src/components/pages/Home.vue | 0 frontend/src/router/index.js | 11 ++ frontend/src/stores/user.js | 16 ++ frontend/src/style.css | 12 +- frontend/vite.config.js | 38 +++-- 11 files changed, 251 insertions(+), 70 deletions(-) create mode 100644 frontend/src/components/SideBar.vue create mode 100644 frontend/src/components/pages/Home.vue create mode 100644 frontend/src/router/index.js create mode 100644 frontend/src/stores/user.js diff --git a/custom_ui/custom_ui/page/custom_ui/custom_ui.js b/custom_ui/custom_ui/page/custom_ui/custom_ui.js index 3d0de57..847afd7 100644 --- a/custom_ui/custom_ui/page/custom_ui/custom_ui.js +++ b/custom_ui/custom_ui/page/custom_ui/custom_ui.js @@ -1,13 +1,20 @@ frappe.pages["custom_ui"].on_page_load = async (wrapper) => { $(wrapper).html('
'); console.log("App root div created"); - - const script = document.createElement("script"); - manifest = await fetch("/assets/custom_ui/dist/.vite/manifest.json").then((res) => res.json()); console.log("Fetched manifest:", manifest); + + const script = document.createElement("script"); script.src = "/assets/custom_ui/dist/" + manifest["src/main.js"]["file"]; script.type = "module"; document.body.appendChild(script); + console.log("Appended script:", script.src); + + const link = document.createElement("link"); + link.rel = "stylesheet"; + link.href = "/assets/custom_ui/dist/" + manifest["src/main.js"]["css"][0]; + document.head.appendChild(link); + + console.log("Custom UI stylesheet loaded:", link.href); console.log("Custom UI script loaded:", script.src); }; diff --git a/frontend/index.html b/frontend/index.html index 7d082ee..c1e19dc 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -1,13 +1,13 @@ - - - - - frontend - - -
- - + + + + + frontend + + +
+ + diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 0c62a8e..ead3c0f 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -10,7 +10,9 @@ "dependencies": { "axios": "^1.12.2", "frappe-ui": "^0.1.205", - "vue": "^3.5.22" + "pinia": "^3.0.3", + "vue": "^3.5.22", + "vue-router": "^4.6.3" }, "devDependencies": { "@vitejs/plugin-vue": "^6.0.1", @@ -1880,8 +1882,31 @@ "version": "6.6.4", "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz", "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==", + "license": "MIT" + }, + "node_modules/@vue/devtools-kit": { + "version": "7.7.7", + "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.7.tgz", + "integrity": "sha512-wgoZtxcTta65cnZ1Q6MbAfePVFxfM+gq0saaeytoph7nEa7yMXoi6sCPy4ufO111B9msnw0VOWjPEFCXuAKRHA==", "license": "MIT", - "peer": true + "dependencies": { + "@vue/devtools-shared": "^7.7.7", + "birpc": "^2.3.0", + "hookable": "^5.5.3", + "mitt": "^3.0.1", + "perfect-debounce": "^1.0.0", + "speakingurl": "^14.0.1", + "superjson": "^2.2.2" + } + }, + "node_modules/@vue/devtools-shared": { + "version": "7.7.7", + "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.7.tgz", + "integrity": "sha512-+udSj47aRl5aKb0memBvcUG9koarqnxNM5yjuREvqwK6T3ap4mn3Zqqc17QrBFTqSMjr3HK1cvStEZpMDpfdyw==", + "license": "MIT", + "dependencies": { + "rfdc": "^1.4.1" + } }, "node_modules/@vue/reactivity": { "version": "3.5.22", @@ -2149,6 +2174,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/birpc": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/birpc/-/birpc-2.6.1.tgz", + "integrity": "sha512-LPnFhlDpdSH6FJhJyn4M0kFO7vtQ5iPw24FnG0y21q09xC7e8+1LeR31S1MAIrDAHp4m7aas4bEkTDTvMAtebQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -2324,6 +2358,21 @@ "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==", "license": "MIT" }, + "node_modules/copy-anything": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz", + "integrity": "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==", + "license": "MIT", + "dependencies": { + "is-what": "^4.1.8" + }, + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, "node_modules/core-js": { "version": "3.46.0", "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.46.0.tgz", @@ -2919,6 +2968,12 @@ "node": ">=12.0.0" } }, + "node_modules/hookable": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz", + "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==", + "license": "MIT" + }, "node_modules/idb-keyval": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-6.2.2.tgz", @@ -3023,6 +3078,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-what": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz", + "integrity": "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==", + "license": "MIT", + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, "node_modules/js-tokens": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", @@ -3196,6 +3263,12 @@ "mini-svg-data-uri": "cli.js" } }, + "node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", + "license": "MIT" + }, "node_modules/mlly": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.0.tgz", @@ -3320,6 +3393,12 @@ "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", "license": "MIT" }, + "node_modules/perfect-debounce": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", + "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", + "license": "MIT" + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -3338,6 +3417,36 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pinia": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pinia/-/pinia-3.0.3.tgz", + "integrity": "sha512-ttXO/InUULUXkMHpTdp9Fj4hLpD/2AoJdmAbAeW2yu1iy1k+pkFekQXw5VpC0/5p51IOR/jDaDRfRWRnMMsGOA==", + "license": "MIT", + "dependencies": { + "@vue/devtools-api": "^7.7.2" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "typescript": ">=4.4.4", + "vue": "^2.7.0 || ^3.5.11" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/pinia/node_modules/@vue/devtools-api": { + "version": "7.7.7", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.7.7.tgz", + "integrity": "sha512-lwOnNBH2e7x1fIIbVT7yF5D+YWhqELm55/4ZKf45R9T8r9dE2AIOy8HKjfqzGsoTHFbWbr337O4E0A0QADnjBg==", + "license": "MIT", + "dependencies": { + "@vue/devtools-kit": "^7.7.7" + } + }, "node_modules/pkg-types": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.0.tgz", @@ -3785,6 +3894,12 @@ "node": ">=8" } }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "license": "MIT" + }, "node_modules/rollup": { "version": "4.52.5", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.5.tgz", @@ -3902,6 +4017,15 @@ "node": ">=0.10.0" } }, + "node_modules/speakingurl": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz", + "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -3935,6 +4059,18 @@ "url": "https://github.com/sponsors/antfu" } }, + "node_modules/superjson": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.2.tgz", + "integrity": "sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==", + "license": "MIT", + "dependencies": { + "copy-anything": "^3.0.2" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -4357,7 +4493,6 @@ "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.6.3.tgz", "integrity": "sha512-ARBedLm9YlbvQomnmq91Os7ck6efydTSpRP3nuOKCvgJOHNrhRoJDSKtee8kcL1Vf7nz6U+PMBL+hTvR3bTVQg==", "license": "MIT", - "peer": true, "dependencies": { "@vue/devtools-api": "^6.6.4" }, diff --git a/frontend/package.json b/frontend/package.json index 076eeeb..160c27f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -11,7 +11,9 @@ "dependencies": { "axios": "^1.12.2", "frappe-ui": "^0.1.205", - "vue": "^3.5.22" + "pinia": "^3.0.3", + "vue": "^3.5.22", + "vue-router": "^4.6.3" }, "devDependencies": { "@vitejs/plugin-vue": "^6.0.1", diff --git a/frontend/src/components/HelloWorld.vue b/frontend/src/components/HelloWorld.vue index 546ebbc..2a37c76 100644 --- a/frontend/src/components/HelloWorld.vue +++ b/frontend/src/components/HelloWorld.vue @@ -1,43 +1,38 @@ diff --git a/frontend/src/components/SideBar.vue b/frontend/src/components/SideBar.vue new file mode 100644 index 0000000..2040b80 --- /dev/null +++ b/frontend/src/components/SideBar.vue @@ -0,0 +1,15 @@ + + + diff --git a/frontend/src/components/pages/Home.vue b/frontend/src/components/pages/Home.vue new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/router/index.js b/frontend/src/router/index.js new file mode 100644 index 0000000..3c8f203 --- /dev/null +++ b/frontend/src/router/index.js @@ -0,0 +1,11 @@ +import { createRouter, createWebHashHistory } from "vue-router"; +import Home from "../components/pages/Home.vue"; + +const routes = [{ path: "/", component: Home }]; + +const router = createRouter({ + history: createWebHashHistory(), + routes, +}); + +export default router; diff --git a/frontend/src/stores/user.js b/frontend/src/stores/user.js new file mode 100644 index 0000000..5552579 --- /dev/null +++ b/frontend/src/stores/user.js @@ -0,0 +1,16 @@ +import { defineStore } from "pinia"; + +export const useUserStore = defineStore("user", { + state: () => ({ + username: "", + roles: [], + }), + actions: { + check_permission(role) { + if (this.roles.includes(role)) { + return true; + } + return false; + }, + }, +}); diff --git a/frontend/src/style.css b/frontend/src/style.css index cc4e557..9491fd5 100644 --- a/frontend/src/style.css +++ b/frontend/src/style.css @@ -13,15 +13,6 @@ -moz-osx-font-smoothing: grayscale; } -a { - font-weight: 500; - color: #646cff; - text-decoration: inherit; -} -a:hover { - color: #535bf2; -} - h1 { font-size: 3.2em; line-height: 1.1; @@ -50,10 +41,11 @@ button:focus-visible { padding: 2em; } -#app { +#custom-ui-app { max-width: 1280px; margin: 0 auto; padding: 2rem; + /* border: 1px solid #444; */ text-align: center; } diff --git a/frontend/vite.config.js b/frontend/vite.config.js index d3139c5..c2a1e72 100644 --- a/frontend/vite.config.js +++ b/frontend/vite.config.js @@ -2,20 +2,28 @@ import { defineConfig } from "vite"; import vue from "@vitejs/plugin-vue"; import { resolve } from "path"; -// https://vite.dev/config/ -export default defineConfig({ - plugins: [vue()], - build: { - outDir: resolve(__dirname, "../custom_ui/public/dist"), - emptyOutDir: true, - manifest: true, - rollupOptions: { - input: resolve(__dirname, "src/main.js"), +export default defineConfig(({ command }) => { + const isDev = command === "serve"; // 'serve' = npm run dev + + return { + plugins: [vue()], + + base: isDev ? "/" : "/assets/custom_ui/dist/", + + build: { + outDir: isDev + ? resolve(__dirname, "dist-dev") // optional, Vite dev server serves in memory + : resolve(__dirname, "../custom_ui/public/dist"), + emptyOutDir: true, + manifest: true, + rollupOptions: { + input: resolve(__dirname, "src/main.js"), + }, }, - }, - server: { - port: 5173, - strictPort: true, - }, - base: "/assets/custom_ui/dist/", + + server: { + port: 5173, + strictPort: true, + }, + }; });