diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 2cfcbd94..75175686 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -8,7 +8,6 @@ "name": "filebrowser-frontend", "version": "2.0.0", "dependencies": { - "@vue/compat": "^3.3.4", "@vueuse/core": "^10.4.1", "ace-builds": "^1.24.1", "clipboard": "^2.0.11", @@ -21,7 +20,6 @@ "material-icons": "^1.13.10", "moment": "^2.29.4", "normalize.css": "^8.0.1", - "noty": "^3.2.0-beta", "pinia": "^2.1.6", "pretty-bytes": "^6.1.1", "qrcode.vue": "^3.4.1", @@ -31,11 +29,10 @@ "vue-i18n": "^9.2.2", "vue-lazyload": "^3.0.0", "vue-router": "^4.2.4", - "vue-simple-progress": "^1.1.1" + "vue-toastification": "^2.0.0-rc.5" }, "devDependencies": { "@intlify/unplugin-vue-i18n": "^0.12.3", - "@types/node": "^20.5.9", "@vitejs/plugin-legacy": "^4.1.1", "@vitejs/plugin-vue": "^4.3.3", "@vue/eslint-config-prettier": "^8.0.0", @@ -47,11 +44,9 @@ "postcss": "^8.4.28", "prettier": "^3.0.2", "terser": "^5.19.2", - "typescript": "^5.2.2", "vite": "^4.4.9", "vite-plugin-compression2": "^0.10.4", - "vite-plugin-rewrite-all": "^1.0.1", - "vue-tsc": "^1.8.10" + "vite-plugin-rewrite-all": "^1.0.1" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -2493,12 +2488,6 @@ "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", "dev": true }, - "node_modules/@types/node": { - "version": "20.5.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.9.tgz", - "integrity": "sha512-PcGNd//40kHAS3sTlzKB9C9XL4K0sTup8nbG5lC14kzEteTNuAFh9u5nA0o5TWnSG2r/JNPRXFVcHJIIeRlmqQ==", - "dev": true - }, "node_modules/@types/web-bluetooth": { "version": "0.0.17", "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.17.tgz", @@ -2542,46 +2531,6 @@ "vue": "^3.2.25" } }, - "node_modules/@volar/language-core": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-1.10.1.tgz", - "integrity": "sha512-JnsM1mIPdfGPxmoOcK1c7HYAsL6YOv0TCJ4aW3AXPZN/Jb4R77epDyMZIVudSGjWMbvv/JfUa+rQ+dGKTmgwBA==", - "dev": true, - "dependencies": { - "@volar/source-map": "1.10.1" - } - }, - "node_modules/@volar/source-map": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-1.10.1.tgz", - "integrity": "sha512-3/S6KQbqa7pGC8CxPrg69qHLpOvkiPHGJtWPkI/1AXCsktkJ6gIk/5z4hyuMp8Anvs6eS/Kvp/GZa3ut3votKA==", - "dev": true, - "dependencies": { - "muggle-string": "^0.3.1" - } - }, - "node_modules/@volar/typescript": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-1.10.1.tgz", - "integrity": "sha512-+iiO9yUSRHIYjlteT+QcdRq8b44qH19/eiUZtjNtuh6D9ailYM7DVR0zO2sEgJlvCaunw/CF9Ov2KooQBpR4VQ==", - "dev": true, - "dependencies": { - "@volar/language-core": "1.10.1" - } - }, - "node_modules/@vue/compat": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/compat/-/compat-3.3.4.tgz", - "integrity": "sha512-VwAsPqUqRJVxeLQPUC03Sa5d+T8UG2Qv4VItq74KmNvtQlRXICpa/sqq12BcyBB4Tz1U5paOEZxWCUoXkrZ9QQ==", - "dependencies": { - "@babel/parser": "^7.21.3", - "estree-walker": "^2.0.2", - "source-map-js": "^1.0.2" - }, - "peerDependencies": { - "vue": "3.3.4" - } - }, "node_modules/@vue/compiler-core": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.3.4.tgz", @@ -2647,54 +2596,6 @@ "prettier": ">= 3.0.0" } }, - "node_modules/@vue/language-core": { - "version": "1.8.10", - "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-1.8.10.tgz", - "integrity": "sha512-db8PtM4ZZr7SYNH30XpKxUYnUBYaTvcuJ4c2whKK04fuAjbtjAIZ2al5GzGEfUlesmvkpgdbiSviRXUxgD9Omw==", - "dev": true, - "dependencies": { - "@volar/language-core": "~1.10.0", - "@volar/source-map": "~1.10.0", - "@vue/compiler-dom": "^3.3.0", - "@vue/reactivity": "^3.3.0", - "@vue/shared": "^3.3.0", - "minimatch": "^9.0.0", - "muggle-string": "^0.3.1", - "vue-template-compiler": "^2.7.14" - }, - "peerDependencies": { - "typescript": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@vue/language-core/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@vue/language-core/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@vue/reactivity": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.3.4.tgz", @@ -2751,16 +2652,6 @@ "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.3.4.tgz", "integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==" }, - "node_modules/@vue/typescript": { - "version": "1.8.10", - "resolved": "https://registry.npmjs.org/@vue/typescript/-/typescript-1.8.10.tgz", - "integrity": "sha512-vPSpTXMk4chYwvyTGjM891cKgnx2r6vtbdANOp2mRU31f4HYGyLrZBlGgiua7SaO2cLjUg8y91OipJe0t8OFhA==", - "dev": true, - "dependencies": { - "@volar/typescript": "~1.10.0", - "@vue/language-core": "1.8.10" - } - }, "node_modules/@vueuse/core": { "version": "10.4.1", "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.4.1.tgz", @@ -3387,12 +3278,6 @@ "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.9.tgz", "integrity": "sha512-QvzAURSbQ0pKdIye2txOzNaHmxtUBXerpY0FJsFXUMKbIZeFm5ht1LS/jFsrncjnmtv8HsG0W2g6c0zUjZWmpA==" }, - "node_modules/de-indent": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", - "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", - "dev": true - }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -4286,15 +4171,6 @@ "node": ">=4" } }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "bin": { - "he": "bin/he" - } - }, "node_modules/html-encoding-sniffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", @@ -4959,12 +4835,6 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "node_modules/muggle-string": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.3.1.tgz", - "integrity": "sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==", - "dev": true - }, "node_modules/nanoid": { "version": "3.3.6", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", @@ -5017,12 +4887,6 @@ "resolved": "https://registry.npmjs.org/normalize.css/-/normalize.css-8.0.1.tgz", "integrity": "sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg==" }, - "node_modules/noty": { - "version": "3.2.0-beta-deprecated", - "resolved": "https://registry.npmjs.org/noty/-/noty-3.2.0-beta-deprecated.tgz", - "integrity": "sha512-ntRbHuQ9SnnnVFZm/oq5L1DBCaHQUvsU24AwZH3PGjAWx2YqR/IhOadMk11vmJovYiQo00oqTj6Hp+D6PGtmLA==", - "deprecated": "no longer supported" - }, "node_modules/npm-run-path": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", @@ -6066,19 +5930,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/typescript": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", - "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", - "devOptional": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, "node_modules/ufo": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.3.0.tgz", @@ -6423,71 +6274,14 @@ "vue": "^3.2.0" } }, - "node_modules/vue-simple-progress": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/vue-simple-progress/-/vue-simple-progress-1.1.1.tgz", - "integrity": "sha512-ltLWYBA5eVQHWyt1NwZeGeK0VQC69JVh1oqUdro0po7r8Hc8SEMEyEfuwyCO4s27h5I3jbD99BKKkyPSQZgoZA==" - }, - "node_modules/vue-template-compiler": { - "version": "2.7.14", - "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.14.tgz", - "integrity": "sha512-zyA5Y3ArvVG0NacJDkkzJuPQDF8RFeRlzV2vLeSnhSpieO6LK2OVbdLPi5MPPs09Ii+gMO8nY4S3iKQxBxDmWQ==", - "dev": true, - "dependencies": { - "de-indent": "^1.0.2", - "he": "^1.2.0" - } - }, - "node_modules/vue-tsc": { - "version": "1.8.10", - "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-1.8.10.tgz", - "integrity": "sha512-ptpTFFDoHQgkWJF7i5iERxooiQzOGtG1uKTfmAUuS3qPuSQGq+Ky/S8BFHhnFGwoOxq/PjmGN2QSZEfg1rtzQA==", - "dev": true, - "dependencies": { - "@vue/language-core": "1.8.10", - "@vue/typescript": "1.8.10", - "semver": "^7.3.8" - }, - "bin": { - "vue-tsc": "bin/vue-tsc.js" - }, + "node_modules/vue-toastification": { + "version": "2.0.0-rc.5", + "resolved": "https://registry.npmjs.org/vue-toastification/-/vue-toastification-2.0.0-rc.5.tgz", + "integrity": "sha512-q73e5jy6gucEO/U+P48hqX+/qyXDozAGmaGgLFm5tXX4wJBcVsnGp4e/iJqlm9xzHETYOilUuwOUje2Qg1JdwA==", "peerDependencies": { - "typescript": "*" + "vue": "^3.0.2" } }, - "node_modules/vue-tsc/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/vue-tsc/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/vue-tsc/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/w3c-xmlserializer": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index 262e3550..e0f78bcb 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -6,7 +6,7 @@ "scripts": { "dev": "vite dev", "serve": "vite serve", - "build": "vue-tsc -p ./tsconfig.json --noEmit && vite build --emptyOutDir", + "build": "vite build", "watch": "vite build --watch", "clean": "find ./dist -maxdepth 1 -mindepth 1 ! -name '.gitkeep' -exec rm -r {} +", "lint": "eslint --ext .vue,.js src/", @@ -14,7 +14,6 @@ "format": "prettier --write ." }, "dependencies": { - "@vue/compat": "^3.3.4", "@vueuse/core": "^10.4.1", "ace-builds": "^1.24.1", "clipboard": "^2.0.11", @@ -27,7 +26,6 @@ "material-icons": "^1.13.10", "moment": "^2.29.4", "normalize.css": "^8.0.1", - "noty": "^3.2.0-beta", "pinia": "^2.1.6", "pretty-bytes": "^6.1.1", "qrcode.vue": "^3.4.1", @@ -37,11 +35,10 @@ "vue-i18n": "^9.2.2", "vue-lazyload": "^3.0.0", "vue-router": "^4.2.4", - "vue-simple-progress": "^1.1.1" + "vue-toastification": "^2.0.0-rc.5" }, "devDependencies": { "@intlify/unplugin-vue-i18n": "^0.12.3", - "@types/node": "^20.5.9", "@vitejs/plugin-legacy": "^4.1.1", "@vitejs/plugin-vue": "^4.3.3", "@vue/eslint-config-prettier": "^8.0.0", @@ -53,15 +50,8 @@ "postcss": "^8.4.28", "prettier": "^3.0.2", "terser": "^5.19.2", - "typescript": "^5.2.2", "vite": "^4.4.9", "vite-plugin-compression2": "^0.10.4", - "vite-plugin-rewrite-all": "^1.0.1", - "vue-tsc": "^1.8.10" - }, - "browserslist": [ - "> 1%", - "last 2 versions", - "not ie < 11" - ] + "vite-plugin-rewrite-all": "^1.0.1" + } } diff --git a/frontend/src/components/CustomToast.vue b/frontend/src/components/CustomToast.vue new file mode 100644 index 00000000..9ba426e6 --- /dev/null +++ b/frontend/src/components/CustomToast.vue @@ -0,0 +1,41 @@ + + + + + diff --git a/frontend/src/components/ProgressBar.vue b/frontend/src/components/ProgressBar.vue new file mode 100644 index 00000000..dac55cfb --- /dev/null +++ b/frontend/src/components/ProgressBar.vue @@ -0,0 +1,223 @@ + + + + diff --git a/frontend/src/components/Sidebar.vue b/frontend/src/components/Sidebar.vue index b223cfc4..044ad8bd 100644 --- a/frontend/src/components/Sidebar.vue +++ b/frontend/src/components/Sidebar.vue @@ -82,9 +82,7 @@
@@ -112,8 +110,10 @@ diff --git a/frontend/src/components/files/ListingItem.vue b/frontend/src/components/files/ListingItem.vue index 0e46a5d3..2816dcf0 100644 --- a/frontend/src/components/files/ListingItem.vue +++ b/frontend/src/components/files/ListingItem.vue @@ -48,9 +48,6 @@ import * as upload from "@/utils/upload"; export default { name: "item", - compatConfig: { - ATTR_FALSE_VALUE: "suppress-warning", - }, data: function () { return { touches: 0, diff --git a/frontend/src/css/styles.css b/frontend/src/css/styles.css index 00442507..9308889c 100644 --- a/frontend/src/css/styles.css +++ b/frontend/src/css/styles.css @@ -1,6 +1,5 @@ @import "normalize.css/normalize.css"; -@import "noty/lib/noty.css"; -@import "noty/lib/themes/mint.css"; +@import "vue-toastification/dist/index.css"; @import "./_variables.css"; @import "./_buttons.css"; @import "./_inputs.css"; diff --git a/frontend/src/main.ts b/frontend/src/main.ts index 995b47e7..02e9bf07 100644 --- a/frontend/src/main.ts +++ b/frontend/src/main.ts @@ -1,14 +1,12 @@ import { disableExternal } from "@/utils/constants"; import { createApp } from "vue"; -import Noty from "noty"; import VueLazyload from "vue-lazyload"; +import Toast, { useToast } from "vue-toastification"; import createPinia from "@/stores"; import router from "@/router"; -import i18n from "@/i18n"; +import i18n, { rtlLanguages } from "@/i18n"; import App from "@/App.vue"; -import '@/css/styles.css' - -// configureCompat({ RENDER_FUNCTION: false }); +import CustomToast from "@/components/CustomToast.vue"; import dayjs from "dayjs"; import localizedFormat from "dayjs/plugin/localizedFormat"; @@ -24,6 +22,11 @@ const pinia = createPinia(router); const app = createApp(App); app.use(VueLazyload); +app.use(Toast, { + transition: "Vue-Toastification__bounce", + maxToasts: 10, + newestOnTop: true, +}); app.use(i18n); app.use(pinia); @@ -44,54 +47,51 @@ app.directive("focus", { }, }); -const notyDefault: Noty.Options = { - type: "info", - layout: "bottomCenter", - timeout: 1000, - progressBar: true, +const toastConfig = { + position: "bottom-center", + timeout: 4000, + closeOnClick: true, + pauseOnFocusLoss: true, + pauseOnHover: true, + draggable: true, + draggablePercent: 0.6, + showCloseButtonOnHover: false, + hideProgressBar: false, + closeButton: "button", + icon: true, }; -// app.provide("$noty", (opts) => { -// new Noty(Object.assign({}, notyDefault, opts)).show(); -// }); - -app.provide("$showSuccess", (message: any) => { - new Noty( - Object.assign({}, notyDefault, { - text: message, - type: "success", - }) - ).show(); +app.provide("$showSuccess", (message) => { + const $toast = useToast(); + $toast.success( + { + component: CustomToast, + props: { + message: message, + }, + }, + { ...toastConfig, rtl: rtlLanguages.includes(i18n.global.locale) } + ); }); -app.provide("$showError", (error: any, displayReport = true) => { - let btns = [ - // @ts-ignore - Noty.button(i18n.global.t("buttons.close"), "", function () { - n.close(); - }), - ]; - - if (!disableExternal && displayReport) { - btns.unshift( - Noty.button(i18n.global.t("buttons.reportIssue"), "", function () { - window.open( - "https://github.com/filebrowser/filebrowser/issues/new/choose" - ); - }) - ); - } - - let n = new Noty( - Object.assign({}, notyDefault, { - text: error.message || error, - type: "error", - timeout: null, - buttons: btns, - }) +app.provide("$showError", (error, displayReport = true) => { + const $toast = useToast(); + $toast.error( + { + component: CustomToast, + props: { + message: error.message || error, + isReport: !disableExternal && displayReport, + // TODO: i couldnt use $t inside the component + reportText: i18n.global.t("buttons.reportIssue"), + }, + }, + { + ...toastConfig, + timeout: 0, + rtl: rtlLanguages.includes(i18n.global.locale), + } ); - - n.show(); }); router.isReady().then(() => app.mount("#app")); diff --git a/frontend/src/stores/upload.ts b/frontend/src/stores/upload.ts index 88f23d7a..10bba803 100644 --- a/frontend/src/stores/upload.ts +++ b/frontend/src/stores/upload.ts @@ -27,6 +27,7 @@ export const useUploadStore = defineStore("upload", { progress: [], queue: [], uploads: {}, + error: null, }), getters: { // user and jwt getter removed, no longer needed @@ -78,6 +79,9 @@ export const useUploadStore = defineStore("upload", { const { id, loaded } = obj this.progress[id] = loaded; }, + setError(error) { + this.error = error; + }, reset() { this.id = 0; this.sizes = []; @@ -140,8 +144,7 @@ export const useUploadStore = defineStore("upload", { this.moveJob(); if (item.file.isDir) { - // TODO: find a way to display notification - await api.post(item.path).catch(console.error); + await api.post(item.path).catch(this.setError); } else { let onUpload = throttle( (event) => @@ -153,10 +156,9 @@ export const useUploadStore = defineStore("upload", { { leading: true, trailing: false } ); - // TODO: find a way to display notification await api .post(item.path, item.file, item.overwrite, onUpload) - .catch(console.error); + .catch(this.setError); } this.finishUpload(item); diff --git a/frontend/src/views/Files.vue b/frontend/src/views/Files.vue index e519bbeb..51744265 100644 --- a/frontend/src/views/Files.vue +++ b/frontend/src/views/Files.vue @@ -25,12 +25,13 @@ import { files as api } from "@/api"; import { mapState, mapActions, mapWritableState } from "pinia"; import { useFileStore } from "@/stores/file"; import { useLayoutStore } from "@/stores/layout"; +import { useUploadStore } from "@/stores/upload"; import HeaderBar from "@/components/header/HeaderBar.vue"; import Breadcrumbs from "@/components/Breadcrumbs.vue"; import Errors from "@/views/Errors.vue"; import Preview from "@/views/files/Preview.vue"; -import Listing from "@/views/files/Listing.vue"; +import FileListing from "@/views/files/FileListing.vue"; function clean(path) { return path.endsWith("/") ? path.slice(0, -1) : path; @@ -43,7 +44,7 @@ export default { Breadcrumbs, Errors, Preview, - Listing, + FileListing, Editor: defineAsyncComponent(() => import("@/views/files/Editor.vue")), }, data: function () { @@ -52,6 +53,7 @@ export default { width: window.innerWidth, }; }, + inject: ["$showError"], computed: { ...mapWritableState(useFileStore, [ "req", @@ -62,13 +64,16 @@ export default { ]), ...mapState(useLayoutStore, ["show", "showShell"]), ...mapWritableState(useLayoutStore, ["loading"]), + ...mapState(useUploadStore, { + uploadError: "error", + }), currentView() { if (this.req.type == undefined) { return null; } if (this.req.isDir) { - return "listing"; + return "file-listing"; } else if ( this.req.type === "text" || this.req.type === "textImmutable" @@ -89,6 +94,9 @@ export default { this.fetchData(); } }, + uploadError(newValue, oldValue) { + newValue && newValue !== oldValue && this.$showError(this.uploadError); + }, }, mounted() { this.isFiles = true; diff --git a/frontend/src/views/files/Listing.vue b/frontend/src/views/files/FileListing.vue similarity index 99% rename from frontend/src/views/files/Listing.vue rename to frontend/src/views/files/FileListing.vue index 422453b6..8dd8c334 100644 --- a/frontend/src/views/files/Listing.vue +++ b/frontend/src/views/files/FileListing.vue @@ -267,7 +267,6 @@