From 3ba0d7521a91182c2b1110796e64d22e154685f3 Mon Sep 17 00:00:00 2001 From: Alicia Sykes Date: Mon, 9 Mar 2026 13:01:03 +0000 Subject: [PATCH 01/70] =?UTF-8?q?=F0=9F=91=BD=20Begin=20the=20Vue=202=20--?= =?UTF-8?q?>=20Vue=203=20migration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 22 +- .github/workflows/pr-quality-check.yml | 2 - Dockerfile | 6 +- docs/authentication.md | 8 +- docs/configuring.md | 2 +- docs/developing.md | 4 +- docs/development-guides.md | 2 +- docs/troubleshooting.md | 2 + docs/widgets.md | 22 +- index.html | 58 + package.json | 109 +- server.js | 13 +- src/components/Configuration/AppInfo.vue | 97 + src/components/Configuration/AppInfoModal.vue | 124 +- src/components/Configuration/AppVersion.vue | 2 +- .../Configuration/ConfigContainer.vue | 69 +- src/components/Configuration/JsonEditor.vue | 84 +- src/components/Configuration/RebuildApp.vue | 11 +- src/components/FormElements/Input.vue | 6 +- src/components/FormElements/Radio.vue | 2 +- src/components/FormElements/Select.vue | 6 +- src/components/FormElements/TabItem.vue | 14 + src/components/FormElements/Tabs.vue | 128 + .../InteractiveEditor/EditAppConfig.vue | 83 +- .../InteractiveEditor/EditModeSaveMenu.vue | 7 + .../InteractiveEditor/EditMultiPages.vue | 201 +- .../InteractiveEditor/EditPageInfo.vue | 40 +- .../InteractiveEditor/EditSection.vue | 112 +- .../InteractiveEditor/ExportConfigMenu.vue | 4 +- src/components/LinkItems/IframeModal.vue | 2 +- src/components/LinkItems/Item.vue | 18 +- src/components/LinkItems/ItemIcon.vue | 2 +- src/components/LinkItems/Section.vue | 2 +- src/components/MinimalView/MinimalSearch.vue | 2 +- src/components/PageStrcture/Nav.vue | 4 +- src/components/Settings/CustomThemeMaker.vue | 32 +- src/components/Settings/SearchBar.vue | 2 +- src/components/Settings/ThemeSelector.vue | 5 +- src/components/Settings/ViewSwitcher.vue | 1 + src/components/Widgets/AdGuardDnsInfo.vue | 6 +- .../Widgets/AdGuardFilterStatus.vue | 6 +- src/components/Widgets/AnonAddy.vue | 16 +- src/components/Widgets/Clock.vue | 2 +- src/components/Widgets/CodeStats.vue | 8 +- src/components/Widgets/CovidStats.vue | 18 +- src/components/Widgets/CryptoWatchList.vue | 10 +- src/components/Widgets/CveVulnerabilities.vue | 34 +- src/components/Widgets/DomainMonitor.vue | 14 +- src/components/Widgets/DroneCi.vue | 36 +- src/components/Widgets/EmbedWidget.vue | 2 +- src/components/Widgets/ExchangeRates.vue | 10 +- src/components/Widgets/Flights.vue | 16 +- src/components/Widgets/GitHubTrending.vue | 18 +- src/components/Widgets/GlAlerts.vue | 1 - src/components/Widgets/GlCpuTemp.vue | 8 +- src/components/Widgets/GlDiskIo.vue | 12 +- src/components/Widgets/GlDiskSpace.vue | 6 +- src/components/Widgets/GlIpAddress.vue | 1 - .../Widgets/GlNetworkInterfaces.vue | 14 +- src/components/Widgets/HealthChecks.vue | 32 +- src/components/Widgets/Mvg.vue | 18 +- src/components/Widgets/MvgConnection.vue | 54 +- src/components/Widgets/NewsHeadlines.vue | 6 +- src/components/Widgets/PiHoleStats.vue | 6 +- src/components/Widgets/PiHoleStatsV6.vue | 6 +- src/components/Widgets/RssFeed.vue | 6 +- src/components/Widgets/SportsScores.vue | 8 +- src/components/Widgets/StatPing.vue | 2 +- src/components/Widgets/SynologyDownload.vue | 16 +- src/components/Widgets/SystemInfo.vue | 10 +- src/components/Widgets/TacticalRMM.vue | 2 +- src/components/Widgets/TflStatus.vue | 6 +- .../Workspace/MultiTaskingWebComtent.vue | 18 +- src/directives/ClickOutside.js | 4 +- src/directives/LongPress.js | 6 +- src/main.js | 82 +- src/mixins/ConfigSaving.js | 2 +- src/mixins/ItemMixin.js | 2 +- src/mixins/NextcloudMixin.js | 2 +- src/mixins/WidgetMixin.js | 11 +- src/router.js | 28 +- src/store.js | 9 +- src/styles/global-styles.scss | 7 + src/styles/typography.scss | 6 +- src/utils/Auth.js | 18 +- src/utils/ConfigHelpers.js | 1 + src/utils/CoolConsole.js | 2 +- src/utils/EmojiUnicodeRegex.js | 2 +- src/utils/ErrorReporting.js | 12 +- src/utils/HeaderAuth.js | 2 +- src/utils/InitServiceWorker.js | 4 +- src/utils/defaults.js | 64 +- src/views/Home.vue | 3 +- tests/components/item.test.js | 86 +- tests/setup.js | 5 - vite.config.mjs | 102 + vitest.config.js => vitest.config.mjs | 24 +- vue.config.js | 113 - yarn.lock | 6204 +++-------------- 99 files changed, 2344 insertions(+), 6195 deletions(-) create mode 100644 index.html create mode 100644 src/components/Configuration/AppInfo.vue create mode 100644 src/components/FormElements/TabItem.vue create mode 100644 src/components/FormElements/Tabs.vue create mode 100644 vite.config.mjs rename vitest.config.js => vitest.config.mjs (55%) delete mode 100644 vue.config.js diff --git a/.env b/.env index 7200bc095c..a16ca2446f 100644 --- a/.env +++ b/.env @@ -35,23 +35,23 @@ # BASIC_AUTH_PASSWORD # If you'd like frontend to automatically authenticate when basic auth enabled, set credentials here too -# VUE_APP_BASIC_AUTH_USERNAME -# VUE_APP_BASIC_AUTH_PASSWORD +# VITE_APP_BASIC_AUTH_USERNAME +# VITE_APP_BASIC_AUTH_PASSWORD # Override where the path to the configuration file is, can be a remote URL -# VUE_APP_CONFIG_PATH=/conf.yml +# VITE_APP_CONFIG_PATH=/conf.yml # Usually the same as BASE_URL, but accessible in frontend -# VUE_APP_DOMAIN=https://dashy.to +# VITE_APP_DOMAIN=https://dashy.to # Override the page title for the frontend app -# VUE_APP_TITLE='' +# VITE_APP_TITLE='' # Set the default view to load on startup (can be `minimal`, `workspace` or `home`) -# VUE_APP_STARTING_VIEW=home +# VITE_APP_STARTING_VIEW=home # Set the Vue app routing mode (can be 'hash', 'history' or 'abstract') -# VUE_APP_ROUTING_MODE=history +# VITE_APP_ROUTING_MODE=history # Should enable SRI for build script and link resources # INTEGRITY=true @@ -60,11 +60,11 @@ # IS_DOCKER=true # Again, set automatically using package.json during build time -# VUE_APP_VERSION=2.0.0 +# VITE_APP_VERSION=2.0.0 # Directory for conf.yml backups # BACKUP_DIR=./user-data/config-backups -# Setup any other user defined vars by prepending VUE_APP_ to the var name -# VUE_APP_pihole_ip=http://your.pihole.ip -# VUE_APP_pihole_key=your_pihole_secret_key +# Setup any other user defined vars by prepending VITE_APP_ to the var name +# VITE_APP_pihole_ip=http://your.pihole.ip +# VITE_APP_pihole_key=your_pihole_secret_key diff --git a/.github/workflows/pr-quality-check.yml b/.github/workflows/pr-quality-check.yml index 61c5239253..68daff232a 100644 --- a/.github/workflows/pr-quality-check.yml +++ b/.github/workflows/pr-quality-check.yml @@ -67,8 +67,6 @@ jobs: - name: 🏗️ Build Project run: yarn build - env: - NODE_OPTIONS: --openssl-legacy-provider - name: ✅ Verify Build Output run: | diff --git a/Dockerfile b/Dockerfile index c3c542b877..5b34460354 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:18.19.1-alpine AS BUILD_IMAGE +FROM node:20-alpine AS BUILD_IMAGE # Set the platform to build image for ARG TARGETPLATFORM @@ -22,10 +22,10 @@ RUN yarn install --ignore-engines --immutable --no-cache --network-timeout 30000 COPY . ./ # Build initial app for production -RUN yarn build --mode production --no-clean +RUN yarn build # Production stage -FROM node:20.11.1-alpine3.19 +FROM node:20-alpine # Define some ENV Vars ENV PORT=8080 \ diff --git a/docs/authentication.md b/docs/authentication.md index 35846b1ac7..feb064c85a 100644 --- a/docs/authentication.md +++ b/docs/authentication.md @@ -125,7 +125,7 @@ To disable all UI config features, including View Config, set `disableConfigurat If you don't want to hash your password, you can instead leave out the `hash` attribute, and replace it with `password` which should have the value of an environmental variable name you wish to use. -Note that env var must begin with `VUE_APP_`, and you must set this variable before building the app. +Note that env var must begin with `VITE_APP_`, and you must set this variable before building the app. For example: @@ -133,10 +133,10 @@ For example: auth: users: - user: bob - password: VUE_APP_BOB + password: VITE_APP_BOB ``` -Just be sure to set `VUE_APP_BOB='my super secret password'` before build-time. +Just be sure to set `VITE_APP_BOB='my super secret password'` before build-time. ### Adding HTTP Auth to Configuration @@ -154,7 +154,7 @@ With basic auth, all logic is happening on the client-side, which could mean a s If you'd like to protect all your config files from direct access, you can set the `BASIC_AUTH_USERNAME` and `BASIC_AUTH_PASSWORD` environmental variables. You'll then be prompted to enter these credentials when visiting Dashy. -Then, if you'd like your frontend to automatically log you in, without prompting you for credentials (insecure, so only use on a trusted environment), then also specify `VUE_APP_BASIC_AUTH_USERNAME` and `VUE_APP_BASIC_AUTH_PASSWORD`. This is useful for when you're hosting Dashy on a private server, and just want to use auth for user management and to prevent direct access to your config files, while still allowing the frontend to access them. Note that a rebuild is required for these changes to take effect. +Then, if you'd like your frontend to automatically log you in, without prompting you for credentials (insecure, so only use on a trusted environment), then also specify `VITE_APP_BASIC_AUTH_USERNAME` and `VITE_APP_BASIC_AUTH_PASSWORD`. This is useful for when you're hosting Dashy on a private server, and just want to use auth for user management and to prevent direct access to your config files, while still allowing the frontend to access them. Note that a rebuild is required for these changes to take effect. **[⬆️ Back to Top](#authentication)** diff --git a/docs/configuring.md b/docs/configuring.md index 62b876f7ab..300b37142c 100644 --- a/docs/configuring.md +++ b/docs/configuring.md @@ -104,7 +104,7 @@ For more info, see the[Multi-Page docs](/docs/pages-and-sections.md#multi-page-s **Field** | **Type** | **Required**| **Description** --- | --- | --- | --- **`language`** | `string` | _Optional_ | The 2 (or 4-digit) [ISO 639-1 code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) for your language, e.g. `en` or `en-GB`. This must be a language that the app has already been [translated](https://github.com/Lissy93/dashy/tree/master/src/assets/locales) into. If your language is unavailable, Dashy will fallback to English. By default Dashy will attempt to auto-detect your language, although this may not work on some privacy browsers. -~~**`startingView`**~~ | `enum` | _Optional_ | Which page to load by default, and on the base page or domain root. You can still switch to different views from within the UI. Can be either `default`, `minimal` or `workspace`. Defaults to `default`. NOTE: This has been replaced by an environmental variable: `VUE_APP_STARTING_VIEW` in V3 onwards +~~**`startingView`**~~ | `enum` | _Optional_ | Which page to load by default, and on the base page or domain root. You can still switch to different views from within the UI. Can be either `default`, `minimal` or `workspace`. Defaults to `default`. NOTE: This has been replaced by an environmental variable: `VITE_APP_STARTING_VIEW` in V3 onwards **`defaultOpeningMethod`** | `enum` | _Optional_ | The default opening method for items, if no `target` is specified for a given item. Can be either `newtab`, `sametab`, `modal`, `workspace`, `clipboard`, `top` or `parent`. Defaults to `newtab` **`statusCheck`** | `boolean` | _Optional_ | When set to `true`, Dashy will ping each of your services and display their status as a dot next to each item. This can be overridden by setting `statusCheck` under each item. Defaults to `false` **`statusCheckInterval`** | `number` | _Optional_ | The number of seconds between checks. If set to `0` then service will only be checked on initial page load, which is usually the desired functionality. If value is less than `10` you may experience a hit in performance. Defaults to `0` diff --git a/docs/developing.md b/docs/developing.md index 0168fc78a2..789f864339 100644 --- a/docs/developing.md +++ b/docs/developing.md @@ -76,10 +76,10 @@ You can set variables either in your environment, or using the [`.env`](https:// - `PORT` - The port to expose the running application on - `HOST` - The host that Dashy is running on, domain or IP - `BASE_URL` - The default base path for serving up static assets -- `VUE_APP_DOMAIN` - Usually the same as BASE_URL, but accessible in frontend +- `VITE_APP_DOMAIN` - Usually the same as BASE_URL, but accessible in frontend - `INTEGRITY` - Should enable SRI for build script and link resources - `IS_DOCKER` - Computed automatically on build. Indicates if running in container -- `VUE_APP_VERSION` - Again, set automatically using package.json during build time +- `VITE_APP_VERSION` - Again, set automatically using package.json during build time - `BACKUP_DIR` - Directory for conf.yml backups ### Environment Modes diff --git a/docs/development-guides.md b/docs/development-guides.md index ffc6bd75e3..0ee783d9b4 100644 --- a/docs/development-guides.md +++ b/docs/development-guides.md @@ -250,7 +250,7 @@ All environmental variables are optional. Currently there are not many environme You can set variables either in your environment, or using the [`.env`](https://github.com/Lissy93/dashy/blob/master/.env) file. -Any environmental variables used by the frontend are preceded with `VUE_APP_`. Vue will merge the contents of your `.env` file into the app in a similar way to the ['dotenv'](https://github.com/motdotla/dotenv) package, where any variables that you set on your system will always take preference over the contents of any `.env` file. +Any environmental variables used by the frontend are preceded with `VITE_APP_`. Vite will merge the contents of your `.env` file into the app in a similar way to the ['dotenv'](https://github.com/motdotla/dotenv) package, where any variables that you set on your system will always take preference over the contents of any `.env` file. If add any new variables, ensure that there is always a fallback (define it in [`defaults.js`](https://github.com/Lissy93/dashy/blob/master/src/utils/defaults.js)), so as to not cause breaking changes. Don't commit the contents of your `.env` file to git, but instead take a few moments to document what you've added under the appropriate section. Try and follow the concepts outlined in the [12 factor app](https://12factor.net/config). diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index a0f7f0e770..0ac5239a60 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -571,6 +571,8 @@ export NODE_OPTIONS=--openssl-legacy-provider This will be fixed once [webpack/webpack#17659](https://github.com/webpack/webpack/pull/17659) is merged. +**Update:** This should be fully resolved. Raise a ticket if you're still needing to use those NODE_OPTIONS after upgrade. + --- ## How to Reset Local Settings diff --git a/docs/widgets.md b/docs/widgets.md index 0ff7419995..1415256c7b 100644 --- a/docs/widgets.md +++ b/docs/widgets.md @@ -1783,13 +1783,13 @@ Displays the number of queries blocked by [Pi-Hole](https://pi-hole.net/). ``` > [!TIP] -> In order to avoid leaking secret data, both `hostname` and `apiKey` can leverage environment variables. Simply pass the name of the variable, which MUST start with `VUE_APP_`. +> In order to avoid leaking secret data, both `hostname` and `apiKey` can leverage environment variables. Simply pass the name of the variable, which MUST start with `VITE_APP_`. ```yaml - type: pi-hole-stats options: - hostname: VUE_APP_pihole_ip - apiKey: VUE_APP_pihole_key + hostname: VITE_APP_pihole_ip + apiKey: VITE_APP_pihole_key ``` > [!IMPORTANT] @@ -1829,13 +1829,13 @@ Displays the number of queries blocked by [Pi-Hole](https://pi-hole.net/). Use t ``` > [!TIP] -> In order to avoid leaking secret data, both `hostname` and `apiKey` can leverage environment variables. Simply pass the name of the variable, which MUST start with `VUE_APP_`. +> In order to avoid leaking secret data, both `hostname` and `apiKey` can leverage environment variables. Simply pass the name of the variable, which MUST start with `VITE_APP_`. ```yaml - type: pi-hole-stats-v6 options: - hostname: VUE_APP_pihole_ip - apiKey: VUE_APP_pihole_key + hostname: VITE_APP_pihole_ip + apiKey: VITE_APP_pihole_key ``` > [!IMPORTANT] @@ -2636,7 +2636,7 @@ Displays storage statistics and file listings from a [Filebrowser Quantum](https useProxy: true options: hostname: http://filebrowser.local:8080 - apiKey: VUE_APP_FILEBROWSER_KEY + apiKey: VITE_APP_FILEBROWSER_KEY source: Documents path: / showRecent: 5 @@ -2652,7 +2652,7 @@ Displays storage statistics and file listings from a [Filebrowser Quantum](https useProxy: true options: hostname: http://filebrowser.local:8080 - apiKey: VUE_APP_FILEBROWSER_KEY + apiKey: VITE_APP_FILEBROWSER_KEY source: Downloads showDetailedStats: true showRecent: 10 @@ -3342,7 +3342,7 @@ Instead, for secrets you should use environmental vairables. You can do this, by setting the environmental variable name as the value, instead of the actual key, and then setting that env var in your container or local environment. -The key can be named whatever you like, but it must start with `VUE_APP_` (to be picked up by Vue). If you need to update any of these values, a rebuild is required (this can be done under the Config menu in the UI, or by running `yarn build` then restarting the container). +The key can be named whatever you like, but it must start with `VITE_APP_` (to be picked up by Vite). If you need to update any of these values, a rebuild is required (this can be done under the Config menu in the UI, or by running `yarn build` then restarting the container). For more infomation about setting and managing your environmental variables, see [Management Docs --> Environmental Variables](/docs/management.md#passing-in-environmental-variables). @@ -3351,13 +3351,13 @@ For example: ```yaml - type: weather options: - apiKey: VUE_APP_WEATHER_TOKEN + apiKey: VITE_APP_WEATHER_TOKEN city: London units: metric hideDetails: true ``` -Then, set `VUE_APP_WEATHER_TOKEN='xxx'` +Then, set `VITE_APP_WEATHER_TOKEN='xxx'` --- diff --git a/index.html b/index.html new file mode 100644 index 0000000000..5d7371534e --- /dev/null +++ b/index.html @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + Dashy + + + + +
+ +
+

Dashy

+

Loading...

+ + +
+
+ + + + + + + + + + diff --git a/package.json b/package.json index ba76ebedff..21f6b98fa6 100644 --- a/package.json +++ b/package.json @@ -6,23 +6,22 @@ "author": "Alicia Sykes (https://aliciasykes.com)", "scripts": { "start": "node server", - "dev": "NODE_OPTIONS=--openssl-legacy-provider vue-cli-service serve", - "build": "NODE_OPTIONS=--openssl-legacy-provider vue-cli-service build", - "lint": "vue-cli-service lint", + "dev": "vite", + "build": "vite build", + "preview": "vite preview", + "lint": "eslint src/", "test": "vitest run", "test:watch": "vitest", "test:ui": "vitest --ui", "test:coverage": "vitest run --coverage", "pm2-start": "npx pm2 start server.js", - "build-watch": "vue-cli-service build --watch --mode production", - "build-and-start": "NODE_OPTIONS=--openssl-legacy-provider npm-run-all --parallel build start", + "build-and-start": "npm-run-all --sequential build start", "validate-config": "node services/config-validator", "health-check": "node services/healthcheck", "dependency-audit": "npx improved-yarn-audit --ignore-dev-deps" }, "dependencies": { - "@babel/core": "^7.26.0", - "@formschema/native": "^2.0.0-beta.6", + "@febe95/vue-js-modal": "^3.2.0", "@sentry/tracing": "^7.102.1", "@sentry/vue": "^7.102.1", "ajv": "^8.10.0", @@ -30,8 +29,10 @@ "connect-history-api-fallback": "^1.6.0", "crypto-js": "^4.2.0", "dompurify": "^3.0.8", + "entities": "^7.0.1", "express": "^4.21.0", "express-basic-auth": "^1.2.1", + "floating-vue": "^5.2.2", "frappe-charts": "^1.6.2", "js-yaml": "^4.1.0", "keycloak-js": "^20.0.3", @@ -41,88 +42,76 @@ "rss-parser": "3.13.0", "rsup-progress": "^3.2.0", "simple-icons": "^14.4.0", - "v-jsoneditor": "^1.4.5", - "v-tooltip": "^2.1.3", - "vue": "^2.7.0", - "vue-i18n": "^8.27.2", - "vue-js-modal": "^2.0.1", - "vue-json-tree-view": "^2.1.6", - "vue-material-tabs": "0.1.5", - "vue-router": "^3.5.3", - "vue-select": "^3.20.2", - "vue-swatches": "^2.1.1", - "vue-toasted": "^1.1.28", - "vuex": "^3.6.2" + "vue": "^3.5.0", + "vue-i18n": "^9.14.0", + "vue-router": "^4.4.0", + "vue-select": "4.0.0-beta.6", + "vue3-json-viewer": "^2.4.1", + "vuex": "^4.1.0" }, "devDependencies": { - "@babel/preset-env": "^7.26.0", - "@vitest/ui": "^1.6.0", - "@vue/cli-plugin-babel": "^5.0.8", - "@vue/cli-plugin-eslint": "^5.0.8", - "@vue/cli-plugin-pwa": "^5.0.8", - "@vue/cli-plugin-typescript": "^5.0.8", - "@vue/cli-service": "^5.0.8", - "@babel/eslint-parser": "^7.25.0", - "@vue/eslint-config-standard": "^4.0.0", - "@vue/test-utils": "^1.3.6", - "copy-webpack-plugin": "6.4.0", - "eslint": "^7.32.0", - "eslint-config-airbnb": "^18.0.1", - "eslint-plugin-vue": "^7.9.0", + "@vitejs/plugin-vue": "^5.0.0", + "@vitest/ui": "^4.0.18", + "@vue/compiler-sfc": "^3.5.0", + "@vue/test-utils": "^2.4.0", + "autoprefixer": "^10.4.27", + "eslint": "^8.57.0", + "eslint-plugin-vue": "^9.28.0", "happy-dom": "^17.4.0", "npm-run-all": "^4.1.5", "sass": "^1.77.0", - "sass-loader": "^12.0.0", - "typescript": "^5.4.4", - "vite-plugin-vue2": "^2.0.3", - "vitest": "^1.6.0", - "vue-cli-plugin-yaml": "^1.0.2", - "vue-svg-loader": "^0.16.0", - "vue-template-compiler": "^2.7.0" + "vite": "^5.4.0", + "vite-plugin-pwa": "^0.20.0", + "vite-svg-loader": "^5.1.0", + "vitest": "^4.0.18" }, "engines": { - "node": ">=16.0.0 <21.6.2" + "node": ">=18.0.0" }, "eslintConfig": { "root": true, "env": { - "node": true + "node": true, + "es2022": true }, "extends": [ - "plugin:vue/essential", - "@vue/standard", - "airbnb-base" + "plugin:vue/vue3-essential", + "eslint:recommended" ], "rules": { "import/no-unresolved": "off", "import/extensions": "off", "arrow-parens": 0, - "no-else-return": 0 + "no-else-return": 0, + "no-console": "off", + "no-unused-vars": [ + "warn", + { + "argsIgnorePattern": "^_" + } + ], + "vue/multi-word-component-names": "off", + "vue/no-reserved-component-names": "off" }, "parserOptions": { - "parser": "@babel/eslint-parser" + "ecmaVersion": 2022, + "sourceType": "module" }, "overrides": [ { "files": [ "tests/**", - "vitest.config.js" + "vitest.config.mjs", + "vite.config.mjs" ], "rules": { "import/no-extraneous-dependencies": "off", "no-undef": "off", - "global-require": "off", "no-unused-vars": "off" } } ] }, - "babel": { - "presets": [ - "@vue/cli-plugin-babel/preset", - "@babel/preset-env" - ] - }, "postcss": { "plugins": { "autoprefixer": {} @@ -133,17 +122,9 @@ "last 2 versions" ], "resolutions": { - "ejs": "^3.1.10", - "loader-utils": "^2.0.4", - "minimatch": "^3.1.2", "braces": "^3.0.3", "micromatch": "^4.0.8", - "serialize-javascript": "^6.0.2", - "node-forge": "^1.3.1", - "nth-check": "^2.1.1", - "ip": "^2.0.1", - "postcss": "^8.4.31", - "tar": "^6.2.1" + "postcss": "^8.4.31" }, "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" } diff --git a/server.js b/server.js index 5737245c1f..39023acfb1 100644 --- a/server.js +++ b/server.js @@ -39,7 +39,18 @@ const getUser = require('./services/get-user'); // Enables server side user look /* Helper functions, and default config */ const printMessage = require('./services/print-message'); // Function to print welcome msg on start -const ENDPOINTS = require('./src/utils/defaults').serviceEndpoints; // API endpoint URL paths +// Service endpoints +// TODO: We already got these defined in './src/utils/defaults' under `serviceEndpoints` +// Need a way to import from there, without getting stupid ESM import issues from defaults.js +const ENDPOINTS = { + statusPing: '/status-ping', + statusCheck: '/status-check', + save: '/config-manager/save', + rebuild: '/config-manager/rebuild', + systemInfo: '/system-info', + corsProxy: '/cors-proxy', + getUser: '/get-user', +}; /* Checks if app is running within a container, from env var */ const isDocker = !!process.env.IS_DOCKER; diff --git a/src/components/Configuration/AppInfo.vue b/src/components/Configuration/AppInfo.vue new file mode 100644 index 0000000000..8f6da88767 --- /dev/null +++ b/src/components/Configuration/AppInfo.vue @@ -0,0 +1,97 @@ + + + + + + + diff --git a/src/components/Configuration/AppInfoModal.vue b/src/components/Configuration/AppInfoModal.vue index 19c0caa768..98374ccb66 100644 --- a/src/components/Configuration/AppInfoModal.vue +++ b/src/components/Configuration/AppInfoModal.vue @@ -1,130 +1,16 @@ - - - - diff --git a/src/components/Configuration/AppVersion.vue b/src/components/Configuration/AppVersion.vue index 1000257060..886ab107eb 100644 --- a/src/components/Configuration/AppVersion.vue +++ b/src/components/Configuration/AppVersion.vue @@ -43,7 +43,7 @@ export default { }, data() { return { - appVersion: process.env.VUE_APP_VERSION, // Current version, from package.json + appVersion: import.meta.env.VITE_APP_VERSION, // Current version, from package.json progress: new Progress({ color: 'var(--progress-bar)' }), latestVersion: '', // Will store latest version, when request returns checksEnabled: true, // Should we check for updates diff --git a/src/components/Configuration/ConfigContainer.vue b/src/components/Configuration/ConfigContainer.vue index 67e70c2320..6ed1ab3411 100644 --- a/src/components/Configuration/ConfigContainer.vue +++ b/src/components/Configuration/ConfigContainer.vue @@ -31,7 +31,7 @@ - @@ -41,7 +41,7 @@ - @@ -61,8 +61,6 @@ {{ $t('config.backup-note') }} - - @@ -73,6 +71,12 @@ + + + + + + @@ -86,8 +90,11 @@ import JsonEditor from '@/components/Configuration/JsonEditor'; import CustomCssEditor from '@/components/Configuration/CustomCss'; import CloudBackupRestore from '@/components/Configuration/CloudBackupRestore'; import RebuildApp from '@/components/Configuration/RebuildApp'; +import AppInfo from '@/components/Configuration/AppInfo'; import AppVersion from '@/components/Configuration/AppVersion'; import Button from '@/components/FormElements/Button'; +import Tabs from '@/components/FormElements/Tabs'; +import TabItem from '@/components/FormElements/TabItem'; import DownloadIcon from '@/assets/interface-icons/config-download-file.svg'; import DeleteIcon from '@/assets/interface-icons/config-delete-local.svg'; @@ -103,7 +110,7 @@ export default { data() { return { backupId: localStorage[localStorageKeys.BACKUP_ID] || '', - appVersion: process.env.VUE_APP_VERSION, + appVersion: import.meta.env.VITE_APP_VERSION, latestVersion: '', }; }, @@ -119,16 +126,19 @@ export default { }, configPath() { return this.$store.state.currentConfigInfo?.confPath - || process.env.VUE_APP_CONFIG_PATH + || import.meta.env.VITE_APP_CONFIG_PATH || '/conf.yml'; }, }, components: { + Tabs, + TabItem, Button, JsonEditor, CustomCssEditor, CloudBackupRestore, RebuildApp, + AppInfo, AppVersion, DownloadIcon, DeleteIcon, @@ -145,15 +155,16 @@ export default { const itemToSelect = this.$refs.tabView.navItems[tabInxex]; this.$refs.tabView.activeTabItem(itemToSelect); }, - openRebuildAppModal() { + openRebuildAppTab() { if (this.enableConfig) { - this.$modal.show(modalNames.REBUILD_APP); + this.navigateToTab(4); } else { this.unauthorized(); } }, - openAboutModal() { - this.$modal.show(modalNames.ABOUT_APP); + openAboutTab() { + const lastIndex = this.$refs.tabView.navItems.length - 1; + this.navigateToTab(lastIndex); }, openLanguageSwitchModal() { this.$modal.show(modalNames.LANG_SWITCHER); @@ -379,46 +390,8 @@ p.small-screen-note { display: none !important; } -.tabs__content { - height: -webkit-fill-available; - height: -moz-available; - height: stretch; - height: 100%; // Firefox -} - .tab-item { background: var(--config-settings-background) !important; } -.tab__pagination { - background: var(--config-settings-background) !important; - color: var(--config-settings-color) !important; - .tab__nav__items .tab__nav__item { - span { - color: var(--config-settings-color) !important; - } - &:hover { - background: var(--config-settings-color) !important; - span { - color: var(--config-settings-background) !important; - } - } - &.active { - span { - font-weight: bold !important; - color: var(--config-settings-color) !important; - } - &:hover span { - color: var(--config-settings-background) !important; - } - } - } - .tab__nav__items .tab__nav__item.active { - border-bottom: 2px solid var(--config-settings-color) !important; - } - hr.tab__slider { - background: var(--config-settings-color) !important; - } -} - diff --git a/src/components/Configuration/JsonEditor.vue b/src/components/Configuration/JsonEditor.vue index b2bdbe72b2..066d1c182a 100644 --- a/src/components/Configuration/JsonEditor.vue +++ b/src/components/Configuration/JsonEditor.vue @@ -1,7 +1,13 @@