Compare commits

...

53 Commits

Author SHA1 Message Date
WofWca 1eb4331a02 WIP: proper types for `objectToCamelCase` 2023-03-14 11:07:56 +04:00
renovate cdf0690da6 fix(deps): update dependency @intlify/unplugin-vue-i18n to v0.9.2 2023-03-13 10:17:16 +00:00
renovate 80335e7b95 chore(deps): update dependency netlify-cli to v13.1.2 2023-03-13 09:05:32 +00:00
renovate dbc2de14c9 chore(deps): update dependency @types/node to v18.15.1 2023-03-13 08:14:47 +00:00
renovate c0f711d27f chore(deps): update dependency caniuse-lite to v1.0.30001465 2023-03-13 07:04:54 +00:00
kolaente df24522490
chore: 0.20.5 release preperations 2023-03-12 10:23:07 +01:00
kolaente 6cf2e574bf
fix(docker): revert unprivileged user
nginx runs the init process as root so that it can bind to port 80. All worker processes run as an unprivileged user and thus the attack surface is minimal.
The previous solution didn't change the user id of the user running Vikunja and thus didn't have an effect anyway.

Related to #3228
2023-03-11 21:56:47 +01:00
kolaente e7b89ae44f
fix(docker): add cap_net_bind to the nginx binary in the docker container 2023-03-11 21:16:31 +01:00
renovate 72a1aaa654 chore(deps): update dependency eslint to v8.36.0 2023-03-11 06:04:52 +00:00
renovate c70c3b6080 chore(deps): update dependency sass to v1.59.2 2023-03-11 02:05:52 +00:00
kolaente 401f2cdd7e
chore: 0.20.4 release preperations 2023-03-10 14:51:04 +01:00
konrad 013472e899 fix(i18n): load language files before doing anything else (#3218)
Resolves #3214

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: vikunja/frontend#3218
2023-03-10 13:46:23 +00:00
renovate e9d48c442d chore(deps): update dependency rollup to v3.19.1 2023-03-10 13:05:34 +00:00
renovate 6837038922 chore(deps): update dependency autoprefixer to v10.4.14 2023-03-10 07:05:55 +00:00
renovate 6cf7c75954 chore(deps): update dependency @types/node to v18.15.0 2023-03-10 01:06:32 +00:00
Frederick [Bot] 52d6677d93 [skip ci] Updated translations via Crowdin 2023-03-10 00:06:22 +00:00
renovate f8f8c8ac6e chore(deps): update dependency vite-plugin-inject-preload to v1.3.1 2023-03-09 20:53:21 +00:00
renovate 97bd5d77b6 chore(deps): update dependency rollup to v3.19.0 2023-03-09 20:05:23 +00:00
renovate 5278bcbac2 fix(deps): update sentry-javascript monorepo to v7.42.0 2023-03-09 14:05:28 +00:00
renovate 194fef0dab fix(deps): update dependency @intlify/unplugin-vue-i18n to v0.9.1 2023-03-09 11:42:49 +00:00
renovate 97b6ba06dd chore(deps): update dependency @vue/test-utils to v2.3.1 2023-03-09 05:04:25 +00:00
Frederick [Bot] 559cfde8da [skip ci] Updated translations via Crowdin 2023-03-09 00:06:07 +00:00
WofWca 9db3aedde9 chore: remove an unused duplicate key
Introduced in 172d353df, feels like it was by error
2023-03-08 16:06:56 +00:00
WofWca 0eb78e32f9 chore: improve `@/message` `action` type (#3209)
Reviewed-on: vikunja/frontend#3209
Reviewed-by: konrad <k@knt.li>
Co-authored-by: WofWca <wofwca@protonmail.com>
Co-committed-by: WofWca <wofwca@protonmail.com>
2023-03-08 09:51:55 +00:00
WofWca b4dd23b85d fix: i18ze a string (#3210)
Reviewed-on: vikunja/frontend#3210
Reviewed-by: konrad <k@knt.li>
Co-authored-by: WofWca <wofwca@protonmail.com>
Co-committed-by: WofWca <wofwca@protonmail.com>
2023-03-08 09:43:46 +00:00
renovate 2262b49aaf chore(deps): update pnpm to v7.29.1 2023-03-08 06:56:34 +00:00
renovate c887990bad fix(deps): update dependency @intlify/unplugin-vue-i18n to v0.9.0 2023-03-08 06:05:02 +00:00
renovate 37c5a88744 chore(deps): update node.js to v18.15.0 2023-03-07 20:03:33 +00:00
Dominik Pschenitschni 9b7770ade4 fix(keyboard-shortcuts): use card prop 2023-03-07 17:19:21 +00:00
Dominik Pschenitschni af4a039502
chore: histoire add logo link 2023-03-07 18:07:12 +01:00
Dan Stewart 1b06112db4 fix: collapse menu on mobile when path changes 2023-03-07 15:56:09 +00:00
renovate 0952f059c0 fix(deps): update dependency pinia to v2.0.33 2023-03-07 15:08:55 +00:00
WofWca 0f97ba6ec9 fix: sync sidebar transition with `<main>` (#3200)
Reviewed-on: vikunja/frontend#3200
Co-authored-by: WofWca <wofwca@protonmail.com>
Co-committed-by: WofWca <wofwca@protonmail.com>
2023-03-06 18:56:13 +00:00
renovate d4c9edb55d chore(deps): update typescript-eslint monorepo to v5.54.1 2023-03-06 18:04:27 +00:00
renovate 394f056cf4 fix(deps): update sentry-javascript monorepo to v7.41.0 2023-03-06 13:04:12 +00:00
renovate 7672676b6e chore(deps): update pnpm to v7.29.0 2023-03-06 07:30:39 +00:00
renovate 51b33fd67e chore(deps): update dependency caniuse-lite to v1.0.30001460 2023-03-06 07:30:06 +00:00
renovate 0ed3ebda94 chore(deps): update dependency netlify-cli to v13.0.1 2023-03-06 00:06:16 +00:00
danstewart 7b6f76d1b4 fix: stop revealing elements on hover if hover is not supported (#3191)
Resolves #3162

Co-authored-by: Dan Stewart <git@mail.danstewart.dev>
Reviewed-on: vikunja/frontend#3191
Reviewed-by: konrad <k@knt.li>
Co-authored-by: danstewart <danstewart@noreply.kolaente.de>
Co-committed-by: danstewart <danstewart@noreply.kolaente.de>
2023-03-04 16:13:31 +00:00
renovate ad0029789d chore(deps): update dependency esbuild to v0.17.11 2023-03-03 23:04:25 +00:00
renovate e13f57c30a chore(deps): update dependency @types/node to v18.14.6 2023-03-03 22:04:16 +00:00
WofWca 6a3518dace chore(refactor): improve `stores/config` types (#3190)
Reviewed-on: vikunja/frontend#3190
Reviewed-by: konrad <k@knt.li>
Co-authored-by: WofWca <wofwca@protonmail.com>
Co-committed-by: WofWca <wofwca@protonmail.com>
2023-03-03 14:36:59 +00:00
renovate f1ec554d09 chore(deps): update dependency @types/node to v18.14.5 2023-03-03 06:04:12 +00:00
WofWca 6aa02e29b1
chore(services): let `getAll`: always return `Model[]` 2023-03-02 16:44:01 +01:00
WofWca 5f9485414b
chore(services): add examples for some functions 2023-03-02 16:43:46 +01:00
WofWca 149ceaf2e5 fix(quick-actions): nothing happening on team click (#3186)
Reviewed-on: vikunja/frontend#3186
Reviewed-by: konrad <k@knt.li>
Co-authored-by: WofWca <wofwca@protonmail.com>
Co-committed-by: WofWca <wofwca@protonmail.com>
2023-03-02 15:28:43 +00:00
renovate 9b3e185dd4 chore(deps): update dependency @types/node to v18.14.4 2023-03-02 09:04:10 +00:00
renovate 779fe3e323 fix(deps): update sentry-javascript monorepo to v7.40.0 2023-03-02 08:02:54 +00:00
renovate a27b77f24e fix(deps): update dependency dompurify to v3.0.1 2023-03-02 08:02:13 +00:00
renovate 41f22a1035 chore(deps): update dependency rollup to v3.18.0 2023-03-01 23:04:23 +00:00
renovate 28d01c5ba0 chore(deps): update dependency vitest to v0.29.2 2023-03-01 19:04:08 +00:00
Frederick [Bot] e272dd8e64 [skip ci] Updated translations via Crowdin 2023-03-01 00:06:13 +00:00
kolaente c002275e7f
fix(table view): correctly load sort order from local storage
Resolves https://community.vikunja.io/t/table-view-sort-by-due-date-doesnt-persist-after-page-refresh/1198
2023-02-28 11:56:05 +01:00
46 changed files with 1296 additions and 780 deletions

2
.nvmrc
View File

@ -1 +1 @@
18.14.2
18.15.0

View File

@ -9,6 +9,279 @@ All releases can be found on https://code.vikunja.io/frontend/releases.
The releases aim at the api versions which is why there are missing versions.
## [0.20.5] - 2023-03-12
### Bug Fixes
* *(docker)* Add cap_net_bind to the nginx binary in the docker container
* *(docker)* Revert unprivileged user
### Dependencies
* *(deps)* Update dependency sass to v1.59.2
* *(deps)* Update dependency eslint to v8.36.0
## [0.20.4] - 2023-03-10
### Bug Fixes
* *(base)* Use Build Time Base Path
* *(docker)* Cross compilation with buildx
* *(docker)* Default api url
* *(docker)* Make sure the service worker and webmanifest are never cached
* *(filter)* Validate title before creating or editing a filter
* *(filter)* Don't allow marking a filter as favorite
* *(i18n)* Load language files before doing anything else (#3218)
* *(keyboard-shortcuts)* Use card prop
* *(list)* Make sure favorite lists are not duplicated in the menu when renaming them
* *(menu)* Don't show drag handle for not draggable menu items
* *(postcss-preset-env)* Client side polyfills (#3051)
* *(quick actions)* Don't throw an error message when selecting the last items with the arrow keys
* *(quick actions)* Hide edges of last entry on hover
* *(quick add magic)* Correctly parse "next {weekday}" on the beginning of the text
* *(quick-actions)* Nothing happening on team click (#3186)
* *(table view)* Correctly load sort order from local storage
* *(task)* Allow clicking on the whole task to open the task detail view
* *(tests)* Only look in src for tests
* Make sure global error handler handles unrejected promises correctly ([4576da0](4576da0dd394ee68801b1dc424c9550896d63737))
* Use Build Time Base Path (#2964) ([6572f75](6572f75e5d111f7f2dd06e8c2ad0e0d16091fca6))
* Always show update popup on top ([7cbf0ac](7cbf0acac503c508a44e0491ae51e6d5749dfa04))
* Button styles ([d40729c](d40729cbe70b760bcc64d56130a410b05ef9d3dc))
* Stop revealing elements on hover if hover is not supported (#3191) ([7b6f76d](7b6f76d1b4698d0d6c6889aaab3f1cdad80469f8))
* Sync sidebar transition with `<main>` (#3200) ([0f97ba6](0f97ba6ec904226ed91cd3ade8223e2959e9207a))
* Collapse menu on mobile when path changes ([1b06112](1b06112db4ba5ad4144b5868dd04e954be1d77f7))
* I18ze a string (#3210) ([b4dd23b](b4dd23b85d909f7e629e953f1d8543ccbf963a1c))
### Dependencies
* *(deps)* Update sentry-javascript monorepo to v7.33.0 (#3004)
* *(deps)* Update dependency axios to v1.2.4 (#3005)
* *(deps)* Update pnpm to v7.26.0 (#3002)
* *(deps)* Update dependency cypress to v12.4.0 (#3006)
* *(deps)* Update dependency @infectoone/vue-ganttastic to v2.1.4 (#3009)
* *(deps)* Update dependency vitest to v0.28.2 (#3008)
* *(deps)* Update dependency rollup to v3.11.0 (#3013)
* *(deps)* Update dependency @vitejs/plugin-legacy to v3.0.2 (#3012)
* *(deps)* Update dependency axios to v1.2.5
* *(deps)* Update sentry-javascript monorepo to v7.34.0
* *(deps)* Update pnpm to v7.26.1
* *(deps)* Update dependency @vue/test-utils to v2.2.8
* *(deps)* Update dependency vitest to v0.28.3 (#3019)
* *(deps)* Update dependency cypress to v12.4.1
* *(deps)* Update dependency rollup to v3.12.0
* *(deps)* Update dependency esbuild to v0.17.5
* *(deps)* Update dependency axios to v1.2.6
* *(deps)* Update dependency @vueuse/core to v9.12.0
* *(deps)* Update pnpm to v7.26.2
* *(deps)* Update dependency eslint to v8.33.0
* *(deps)* Update dependency netlify-cli to v12.10.0
* *(deps)* Update dependency happy-dom to v8.2.0
* *(deps)* Update dependency caniuse-lite to v1.0.30001449
* *(deps)* Update dependency typescript to v4.9.5
* *(deps)* Update typescript-eslint monorepo to v5.50.0
* *(deps)* Update dependency axios to v1.3.0 (#3036)
* *(deps)* Update dependency sass to v1.58.0
* *(deps)* Update dependency cypress to v12.5.0
* *(deps)* Update pnpm to v7.26.3
* *(deps)* Update dependency rollup to v3.12.1
* *(deps)* Update sentry-javascript monorepo to v7.35.0 (#3041)
* *(deps)* Update dependency pinia to v2.0.30 (#3042)
* *(deps)* Update dependency @vue/test-utils to v2.2.9
* *(deps)* Update dependency axios to v1.3.1
* *(deps)* Update dependency vue to v3.2.47
* *(deps)* Update dependency vite to v4.1.0
* *(deps)* Update dependency postcss-preset-env to v8 (#3000)
* *(deps)* Update dependency @vitejs/plugin-legacy to v4
* *(deps)* Update dependency @vitejs/plugin-legacy to v4.0.1
* *(deps)* Update sentry-javascript monorepo to v7.36.0
* *(deps)* Update dependency vite to v4.1.1
* *(deps)* Update dependency cypress to v12.5.1
* *(deps)* Update dependency @vue/test-utils to v2.2.10
* *(deps)* Update dependency vitest to v0.28.4
* *(deps)* Update dependency rollup to v3.13.0
* *(deps)* Update dependency axios to v1.3.2
* *(deps)* Update dependency rollup to v3.14.0
* *(deps)* Update dependency @types/node to v18.11.19
* *(deps)* Update dependency @histoire/plugin-screenshot to v0.13.0
* *(deps)* Update dependency histoire to v0.13.0
* *(deps)* Update caniuse-and-related
* *(deps)* Update dependency @histoire/plugin-vue to v0.13.0
* *(deps)* Update dependency happy-dom to v8.2.6
* *(deps)* Update typescript-eslint monorepo to v5.51.0
* *(deps)* Update dependency esbuild to v0.17.6
* *(deps)* Update dependency @cypress/vue to v5.0.4
* *(deps)* Update dependency @types/node to v18.13.0
* *(deps)* Update dependency vite-plugin-pwa to v0.14.2
* *(deps)* Update font awesome to v6.3.0
* *(deps)* Update pnpm to v7.27.0
* *(deps)* Update dependency @histoire/plugin-screenshot to v0.13.1
* *(deps)* Update dependency @histoire/plugin-vue to v0.13.1
* *(deps)* Update dependency vite-plugin-pwa to v0.14.3
* *(deps)* Update dependency histoire to v0.13.1
* *(deps)* Update dependency @histoire/plugin-screenshot to v0.13.2
* *(deps)* Update dependency @histoire/plugin-vue to v0.13.2
* *(deps)* Update dependency histoire to v0.13.2
* *(deps)* Update dependency @intlify/unplugin-vue-i18n to v0.8.2
* *(deps)* Update sentry-javascript monorepo to v7.37.0
* *(deps)* Update dependency esbuild to v0.17.7
* *(deps)* Update dependency rollup to v3.15.0
* *(deps)* Create a group for all histoire dependencies
* *(deps)* Update dependency @histoire/plugin-vue to v0.14.0
* *(deps)* Update dependency @histoire/plugin-screenshot to v0.14.0
* *(deps)* Update dependency @histoire/plugin-vue to v0.14.0
* *(deps)* Update dependency histoire to v0.14.0
* *(deps)* Update sentry-javascript monorepo to v7.37.1
* *(deps)* Update dependency histoire to v0.14.2
* *(deps)* Include histoire main package in histoire renovate group
* *(deps)* Histoire renovate group
* *(deps)* Update dependency eslint to v8.34.0
* *(deps)* Update histoire to v0.14.2
* *(deps)* Update dependency vite-plugin-pwa to v0.14.4
* *(deps)* Update dependency esbuild to v0.17.8
* *(deps)* Update dependency netlify-cli to v12.12.0
* *(deps)* Update dependency caniuse-lite to v1.0.30001451
* *(deps)* Update dependency vite-plugin-inject-preload to v1.3.0
* *(deps)* Update dependency vitest to v0.28.5
* *(deps)* Update sentry-javascript monorepo to v7.37.2
* *(deps)* Update dependency dompurify to v3 (#3107)
* *(deps)* Update typescript-eslint monorepo to v5.52.0
* *(deps)* Update dependency axios to v1.3.3
* *(deps)* Update dependency start-server-and-test to v1.15.4 (#3109)
* *(deps)* Update dependency sass to v1.58.1
* *(deps)* Update dependency vue-flatpickr-component to v11.0.2 (#3112)
* *(deps)* Update dependency @kyvg/vue3-notification to v2.9.0 (#3113)
* *(deps)* Update histoire to v0.15.1
* *(deps)* Update histoire to v0.15.3
* *(deps)* Update dependency vue-tsc to v1.1.0
* *(deps)* Pin node.js to 18.14.0
* *(deps)* Update dependency cypress to v12.6.0 (#3115)
* *(deps)* Update histoire to v0.15.4
* *(deps)* Update dependency vue-tsc to v1.1.2
* *(deps)* Update dependency sass to v1.58.2
* *(deps)* Update dependency ufo to v1.1.0
* *(deps)* Update node.js to v18.14.1
* *(deps)* Update dependency vite to v4.1.2
* *(deps)* Update sentry-javascript monorepo to v7.38.0
* *(deps)* Update dependency rollup to v3.16.0
* *(deps)* Update histoire to v0.15.7
* *(deps)* Update dependency blurhash to v2.0.5
* *(deps)* Update dependency @cypress/vite-dev-server to v5.0.3
* *(deps)* Update dependency @types/node to v18.14.0
* *(deps)* Update histoire to v0.15.8
* *(deps)* Update dependency @vueuse/core to v9.13.0
* *(deps)* Update dependency rollup to v3.17.0
* *(deps)* Update pnpm to v7.27.1
* *(deps)* Update dependency vue-tsc to v1.1.3
* *(deps)* Update dependency sass to v1.58.3
* *(deps)* Update dependency rollup to v3.17.1
* *(deps)* Update dependency esbuild to v0.17.9
* *(deps)* Update dependency vite to v4.1.3
* *(deps)* Update dependency @vue/test-utils to v2.3.0
* *(deps)* Update dependency caniuse-lite to v1.0.30001457
* *(deps)* Update dependency codemirror to v5.65.12
* *(deps)* Update dependency pinia to v2.0.31
* *(deps)* Update dependency vue-tsc to v1.1.4
* *(deps)* Update dependency rollup to v3.17.2
* *(deps)* Update dependency happy-dom to v8.6.0
* *(deps)* Update dependency netlify-cli to v12.13.2
* *(deps)* Update dependency esbuild to v0.17.10
* *(deps)* Update typescript-eslint monorepo to v5.53.0
* *(deps)* Update dependency vue-tsc to v1.1.5
* *(deps)* Update dependency pinia to v2.0.32
* *(deps)* Update node.js to v18.14.2
* *(deps)* Update dependency vite to v4.1.4
* *(deps)* Update dependency vue-tsc to v1.1.7
* *(deps)* Update dependency axios to v1.3.4
* *(deps)* Update dependency @types/node to v18.14.1
* *(deps)* Update dependency @cypress/vite-dev-server to v5.0.4
* *(deps)* Update dependency cypress to v12.7.0
* *(deps)* Update dependency vue-tsc to v1.2.0
* *(deps)* Update dependency vitest to v0.29.1
* *(deps)* Update pnpm to v7.28.0
* *(deps)* Update dependency eslint to v8.35.0
* *(deps)* Update dependency rollup to v3.17.3
* *(deps)* Update dependency netlify-cli to v13
* *(deps)* Update dependency happy-dom to v8.9.0
* *(deps)* Update dependency caniuse-lite to v1.0.30001458
* *(deps)* Update dependency start-server-and-test to v1.15.5
* *(deps)* Update dependency start-server-and-test to v2
* *(deps)* Update dependency @types/node to v18.14.2
* *(deps)* Update sentry-javascript monorepo to v7.39.0
* *(deps)* Update typescript-eslint monorepo to v5.54.0
* *(deps)* Update dependency ufo to v1.1.1
* *(deps)* Update dependency vitest to v0.29.2
* *(deps)* Update dependency rollup to v3.18.0
* *(deps)* Update dependency dompurify to v3.0.1
* *(deps)* Update sentry-javascript monorepo to v7.40.0
* *(deps)* Update dependency @types/node to v18.14.4
* *(deps)* Update dependency @types/node to v18.14.5
* *(deps)* Update dependency @types/node to v18.14.6
* *(deps)* Update dependency esbuild to v0.17.11
* *(deps)* Update dependency netlify-cli to v13.0.1
* *(deps)* Update dependency caniuse-lite to v1.0.30001460
* *(deps)* Update pnpm to v7.29.0
* *(deps)* Update sentry-javascript monorepo to v7.41.0
* *(deps)* Update typescript-eslint monorepo to v5.54.1
* *(deps)* Update dependency pinia to v2.0.33
* *(deps)* Update node.js to v18.15.0
* *(deps)* Update dependency @intlify/unplugin-vue-i18n to v0.9.0
* *(deps)* Update pnpm to v7.29.1
* *(deps)* Update dependency @vue/test-utils to v2.3.1
* *(deps)* Update dependency @intlify/unplugin-vue-i18n to v0.9.1
* *(deps)* Update sentry-javascript monorepo to v7.42.0
* *(deps)* Update dependency rollup to v3.19.0
* *(deps)* Update dependency vite-plugin-inject-preload to v1.3.1
* *(deps)* Update dependency @types/node to v18.15.0
* *(deps)* Update dependency autoprefixer to v10.4.14
* *(deps)* Update dependency rollup to v3.19.1
### Features
* *(config)* Support Setting Base Path in .env
* Use v-show for navigation buttons ([7ed1a37](7ed1a37de53cb8c15994e9524a52080170db5950))
* Unindent settings page (#2996) ([13a39be](13a39be3de4d0f7e0f6be9c20e0464e86b87c676))
* Small content auth improvements (#2998) ([2be7847](2be784766f54810f8969e48291ce9181f2854a5b))
* Move update from navigation to app ([3db5ea4](3db5ea45d768d10458eaab0f5ee9dad0df2996e4))
* Improve naming and styles ([eaeddda](eaeddda4e468c2040862d18c9b2d37a1c0ba099e))
* Use klona instead of lodash.clonedeep (#3073) ([7b96397](7b96397e3bfa43a393ca84439069290bc4c8a5c8))
* Refactor to composable ([c502f9b](c502f9b840ee2d65193aa4ef29c7f260b49db0d2))
* Header improvements ([e8db2c2](e8db2c2b458bcae592609d5a5bc3f1b333651b25))
* Persistent menuActive state with Local Storage (#3011) ([e3dd4ef](e3dd4ef78ac818add138d0323bf65abe8a4caa29))
* Fix calculation of token invalidation (#3077) ([d6b55c7](d6b55c757067413bbc34acd48af9fb553f36db8a))
* Use renovate js-app as preset (#3087) ([97c8970](97c8970dd60b2ba1e894ca0039524c8f6a5cd5df))
* Improve recommended vscode settings ([e0f0699](e0f06999beb0a9fb5da817323744307401e85e47))
### Miscellaneous Tasks
* *(refactor)* Improve `stores/config` types (#3190)
* *(services)* Add examples for some functions
* *(services)* Let `getAll`: always return `Model[]`
* Move class name to top ([c6ed925](c6ed9254247efeb43e0763e095b145d6ec1965e1))
* Simplify error handling for login and OpenId Auth ([e67088f](e67088fdb7bd3b24cea6ee37851ef45f1fb7bdad))
* Simplify getting the error text from an exception ([9adf1ab](9adf1aba895a02f416148ddf8b6925689d6e2687))
* Typo ([81a4f2d](81a4f2d9775716bc0056348664fc24185af040d4))
* Update funding links ([7cb0cd2](7cb0cd293d6d277172eccf2558a62427bc86dfe6))
* Update funding links ([b26ea45](b26ea45fe0d1d6f5f070ef42a5d68aa6db8e6b70))
* Remove minimist dependency (not used anywhere) ([f697640](f697640636466e8f035c7d31597ee589379fa017))
* Remove sponsor ([fa0e46a](fa0e46a3991ab423c9364b65439d9e8e5a28cb7b))
* Histoire add logo link ([af4a039](af4a039502b29e9e7e21cf30d44715c7af056c15))
* Improve `@/message` `action` type (#3209) ([0eb78e3](0eb78e32f994e7032725e38d564320a5a04cbf2a))
* Remove an unused duplicate key ([9db3aed](9db3aedde9566fb94717e1dd66a21abdbda6e84a))
### Other
* *(other)* Add Ipv6 support to nginx (#100)
* *(other)* Added ipv6 control script
* *(other)* Disable listening on IPv6 ports when IPv6 is not supported (#102)
* *(other)* Docker refactoring (#3018)
* *(other)* Persist menuActive state in Local Storage
* *(other)* Refactor to only used local storage value when on desktop viewport widths
* *(other)* Solve for resize()
* *(other)* [skip ci] Updated translations via Crowdin
## [0.20.3] - 2023-01-24
### Bug Fixes

View File

@ -66,5 +66,3 @@ RUN chmod 0755 /docker-entrypoint.d/*.sh /etc/nginx/templates && \
chmod -R 0644 /etc/nginx/nginx.conf && \
chown -R nginx:nginx ./ /etc/nginx/conf.d /etc/nginx/templates && \
rm -f /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
# unprivileged user
USER nginx

View File

@ -4,7 +4,7 @@
[![Build Status](https://drone.kolaente.de/api/badges/vikunja/frontend/status.svg)](https://drone.kolaente.de/vikunja/frontend)
[![License: AGPL v3](https://img.shields.io/badge/License-AGPL%20v3-blue.svg)](LICENSE)
[![Download](https://img.shields.io/badge/download-v0.20.3-brightgreen.svg)](https://dl.vikunja.io)
[![Download](https://img.shields.io/badge/download-v0.20.5-brightgreen.svg)](https://dl.vikunja.io)
[![Translation](https://badges.crowdin.net/vikunja/localized.svg)](https://crowdin.com/project/vikunja)
This is the web frontend for Vikunja, written in Vue.js.

View File

@ -28,7 +28,7 @@ export default defineConfig({
// light: './img/light.png',
// dark: './img/dark.png',
// },
// logoHref: 'https://acme.com',
logoHref: 'https://vikunja.io',
// favicon: './favicon.ico',
},
})

View File

@ -13,7 +13,7 @@
},
"homepage": "https://vikunja.io/",
"funding": "https://opencollective.com/vikunja",
"packageManager": "pnpm@7.28.0",
"packageManager": "pnpm@7.29.1",
"keywords": [
"todo",
"productivity",
@ -51,10 +51,10 @@
"@fortawesome/vue-fontawesome": "3.0.3",
"@github/hotkey": "2.0.1",
"@infectoone/vue-ganttastic": "2.1.4",
"@intlify/unplugin-vue-i18n": "0.8.2",
"@intlify/unplugin-vue-i18n": "0.9.2",
"@kyvg/vue3-notification": "2.9.0",
"@sentry/tracing": "7.39.0",
"@sentry/vue": "7.39.0",
"@sentry/tracing": "7.42.0",
"@sentry/vue": "7.42.0",
"@types/is-touch-device": "1.0.0",
"@types/lodash.clonedeep": "4.5.7",
"@types/sortablejs": "1.15.0",
@ -66,7 +66,7 @@
"codemirror": "5.65.12",
"date-fns": "2.29.3",
"dayjs": "1.11.7",
"dompurify": "3.0.0",
"dompurify": "3.0.1",
"easymde": "2.18.0",
"fast-deep-equal": "3.1.3",
"flatpickr": "4.6.13",
@ -78,7 +78,7 @@
"klona": "2.0.6",
"lodash.debounce": "4.0.8",
"marked": "4.2.12",
"pinia": "2.0.32",
"pinia": "2.0.33",
"register-service-worker": "1.7.2",
"snake-case": "3.0.4",
"sortablejs": "1.15.0",
@ -105,40 +105,41 @@
"@types/focus-within": "1.0.1",
"@types/lodash.debounce": "4.0.7",
"@types/marked": "4.0.8",
"@types/node": "18.14.2",
"@types/node": "18.15.1",
"@types/postcss-preset-env": "7.7.0",
"@typescript-eslint/eslint-plugin": "5.54.0",
"@typescript-eslint/parser": "5.54.0",
"@typescript-eslint/eslint-plugin": "5.54.1",
"@typescript-eslint/parser": "5.54.1",
"@vitejs/plugin-legacy": "4.0.1",
"@vitejs/plugin-vue": "4.0.0",
"@vue/eslint-config-typescript": "11.0.2",
"@vue/test-utils": "2.3.0",
"@vue/test-utils": "2.3.1",
"@vue/tsconfig": "0.1.3",
"autoprefixer": "10.4.13",
"autoprefixer": "10.4.14",
"browserslist": "4.21.5",
"caniuse-lite": "1.0.30001458",
"caniuse-lite": "1.0.30001465",
"csstype": "3.1.1",
"cypress": "12.7.0",
"esbuild": "0.17.10",
"eslint": "8.35.0",
"esbuild": "0.17.11",
"eslint": "8.36.0",
"eslint-plugin-vue": "9.9.0",
"happy-dom": "8.9.0",
"histoire": "0.15.8",
"netlify-cli": "13.0.0",
"literal-case": "^1.0.0",
"netlify-cli": "13.1.2",
"postcss": "8.4.21",
"postcss-easing-gradients": "3.0.1",
"postcss-easings": "3.0.1",
"postcss-preset-env": "8.0.1",
"rollup": "3.17.3",
"rollup": "3.19.1",
"rollup-plugin-visualizer": "5.9.0",
"sass": "1.58.3",
"sass": "1.59.2",
"start-server-and-test": "2.0.0",
"typescript": "4.9.5",
"vite": "4.1.4",
"vite-plugin-inject-preload": "1.3.0",
"vite-plugin-inject-preload": "1.3.1",
"vite-plugin-pwa": "0.14.4",
"vite-svg-loader": "4.0.0",
"vitest": "0.29.1",
"vitest": "0.29.2",
"vue-tsc": "1.2.0",
"wait-on": "7.0.1",
"workbox-cli": "6.5.4"

File diff suppressed because it is too large Load Diff

View File

@ -156,6 +156,8 @@ labelStore.loadAllLabels()
z-index: 10;
position: relative;
padding: 1.5rem 0.5rem 1rem;
// TODO refactor: DRY `transition-timing-function` with `./navigation.vue`.
transition: margin-left $transition-duration;
@media screen and (max-width: $tablet) {
margin-left: 0;

View File

@ -221,7 +221,7 @@ function updateActiveLists(namespace: INamespace, activeLists: IList[]) {
// This is a bit hacky: since we do have to filter out the archived items from the list
// for vue draggable updating it is not as simple as replacing it.
// To work around this, we merge the active lists with the archived ones. Doing so breaks the order
// because now all archived lists are sorted after the active ones. This is fine because they are sorted
// because now all archived lists are sorted after the active ones. This is fine because they are sorted
// later when showing them anyway, and it makes the merging happening here a lot easier.
const lists = [
...activeLists,
@ -246,8 +246,8 @@ async function saveListPosition(e: SortableEvent) {
// If the list was dragged to the last position, Safari will report e.newIndex as the size of the listsActive
// array instead of using the position. Because the index is wrong in that case, dragging the list will fail.
// To work around that we're explicitly checking that case here and decrease the index.
const newIndex = e.newIndex === listsActive.length ? e.newIndex - 1 : e.newIndex
const newIndex = e.newIndex === listsActive.length ? e.newIndex - 1 : e.newIndex
const list = listsActive[newIndex]
const listBefore = listsActive[newIndex - 1] ?? null
const listAfter = listsActive[newIndex + 1] ?? null
@ -342,13 +342,20 @@ $vikunja-nav-selected-width: 0.4rem;
}
.menu-list-dropdown {
opacity: 0;
opacity: 1;
transition: $transition;
}
&:hover .menu-list-dropdown {
opacity: 1;
@media(hover: hover) and (pointer: fine) {
.menu-list-dropdown {
opacity: 0;
}
&:hover .menu-list-dropdown {
opacity: 1;
}
}
}
.menu-item-icon {
@ -418,7 +425,6 @@ $vikunja-nav-selected-width: 0.4rem;
opacity: 1;
}
}
&:not(.dragging-disabled) .handle {
cursor: grab;
}
@ -427,7 +433,7 @@ $vikunja-nav-selected-width: 0.4rem;
.top-menu {
margin-top: math.div($navbar-padding, 2);
.menu-list {
li {
font-weight: 600;
@ -482,17 +488,24 @@ $vikunja-nav-selected-width: 0.4rem;
.favorite {
margin-left: .25rem;
transition: opacity $transition, color $transition;
opacity: 0;
opacity: 1;
&:hover,
&.is-favorite {
color: var(--warning);
opacity: 1;
}
}
.favorite.is-favorite,
.list-menu:hover .favorite {
opacity: 1;
@media(hover: hover) and (pointer: fine) {
.list-menu .favorite {
opacity: 0;
}
.list-menu:hover .favorite,
.favorite.is-favorite {
opacity: 1;
}
}
.list-menu-title {

View File

@ -147,7 +147,7 @@ const listStore = useListStore()
top: var(--list-card-padding);
right: var(--list-card-padding);
transition: opacity $transition, color $transition;
opacity: 0;
opacity: 1;
&:hover {
color: var(--warning);
@ -160,8 +160,14 @@ const listStore = useListStore()
}
}
.list-card:hover .favorite {
opacity: 1;
@media(hover: hover) and (pointer: fine) {
.list-card .favorite {
opacity: 0;
}
.list-card:hover .favorite {
opacity: 1;
}
}
.background-fade-in {
@ -173,4 +179,4 @@ const listStore = useListStore()
opacity: 1;
}
}
</style>
</style>

View File

@ -1,6 +1,6 @@
<template>
<modal @close="close()">
<card class="has-background-white has-no-shadow keyboard-shortcuts" :title="$t('keyboardShortcuts.title')">
<card class="has-background-white keyboard-shortcuts" :shadow="false" :title="$t('keyboardShortcuts.title')">
<template v-for="(s, i) in shortcuts" :key="i">
<h3>{{ $t(s.title) }}</h3>

View File

@ -428,7 +428,7 @@ function searchTeams() {
teamService.getAll({}, { s: t }),
)
const teamsResult = await Promise.all(teamSearchPromises)
foundTeams.value = teamsResult.flatMap((team) => {
foundTeams.value = teamsResult.flat().map((team) => {
team.title = team.name
return team
})
@ -458,6 +458,13 @@ async function doAction(type: ACTION_TYPE, item: DoAction) {
params: { id: (item as DoAction<ITask>).id },
})
break
case ACTION_TYPE.TEAM:
closeQuickActions()
await router.push({
name: 'teams.edit',
params: { id: (item as DoAction<ITeam>).id },
})
break
case ACTION_TYPE.CMD:
query.value = ''
selectedCmd.value = item as DoAction<Command>

View File

@ -9,13 +9,13 @@
@change="markAsDone"
v-model="task.done"
/>
<ColorBubble
v-if="showListColor && listColor !== '' && currentList.id !== task.listId"
:color="listColor"
class="mr-1"
/>
<div
:class="{ 'done': task.done, 'show-list': showList && taskList !== null}"
class="tasktext"
@ -242,7 +242,7 @@ async function markAsDone(checked: boolean) {
t('task.doneSuccess') :
t('task.undoneSuccess'),
}, [{
title: 'Undo',
title: t('task.undo'),
callback: () => undoDone(checked),
}])
}
@ -287,7 +287,7 @@ function hideDeferDueDatePopup(e) {
cursor: pointer;
border-radius: $radius;
border: 2px solid transparent;
color: var(--text);
transition: color ease $transition-duration;
@ -339,7 +339,7 @@ function hideDeferDueDatePopup(e) {
}
.favorite {
opacity: 0;
opacity: 1;
text-align: center;
width: 27px;
transition: opacity $transition, color $transition;
@ -354,21 +354,26 @@ function hideDeferDueDatePopup(e) {
}
}
&:hover .favorite {
opacity: 1;
}
.handle {
opacity: 0;
opacity: 1;
transition: opacity $transition;
margin-right: .25rem;
cursor: grab;
}
&:hover .handle {
opacity: 1;
@media(hover: hover) and (pointer: fine) {
& .favorite,
& .handle {
opacity: 0;
}
&:hover .favorite,
&:hover .handle {
opacity: 1;
}
}
:deep(.fancycheckbox) {
height: 18px;
padding-top: 0;
@ -420,4 +425,4 @@ function hideDeferDueDatePopup(e) {
margin-bottom: 0;
}
}
</style>
</style>

View File

@ -1,5 +1,6 @@
import {ref, watch, readonly} from 'vue'
import {useLocalStorage, useMediaQuery} from '@vueuse/core'
import {useRoute} from 'vue-router'
const BULMA_MOBILE_BREAKPOINT = 768
@ -15,7 +16,8 @@ export function useMenuActive() {
)
const menuActive = ref(false)
const route = useRoute()
// set to prefered value
watch(isMobile, (current) => {
menuActive.value = current
@ -31,6 +33,9 @@ export function useMenuActive() {
}
})
// Hide the menu on mobile when the route changes (e.g. when the user taps a menu item)
watch(() => route.fullPath, () => isMobile.value && setMenuActive(false))
function setMenuActive(newMenuActive: boolean) {
menuActive.value = newMenuActive
}
@ -44,4 +49,4 @@ export function useMenuActive() {
setMenuActive,
toggleMenu,
}
}
}

View File

@ -5,6 +5,22 @@ import TaskCollectionService from '@/services/taskCollection'
import type {ITask} from '@/modelTypes/ITask'
import {error} from '@/message'
export type Order = 'asc' | 'desc' | 'none'
export interface SortBy {
id?: Order
index?: Order
done?: Order
title?: Order
priority?: Order
due_date?: Order
start_date?: Order
end_date?: Order
percent_done?: Order
created?: Order
updated?: Order
}
// FIXME: merge with DEFAULT_PARAMS in filters.vue
export const getDefaultParams = () => ({
sort_by: ['position', 'id'],
@ -15,7 +31,7 @@ export const getDefaultParams = () => ({
filter_concat: 'and',
})
const SORT_BY_DEFAULT = {
const SORT_BY_DEFAULT: SortBy = {
id: 'desc',
}
@ -44,7 +60,7 @@ const SORT_BY_DEFAULT = {
/**
* This mixin provides a base set of methods and properties to get tasks on a list.
*/
export function useTaskList(listId, sortByDefault = SORT_BY_DEFAULT) {
export function useTaskList(listId, sortByDefault: SortBy = SORT_BY_DEFAULT) {
const params = ref({...getDefaultParams()})
const search = ref('')

View File

@ -1,10 +1,50 @@
import {camelCase} from 'camel-case'
import {snakeCase} from 'snake-case'
import {camelCase as camelCaseUntyped} from 'camel-case'
import {snakeCase as snakeCaseUntyped} from 'snake-case'
import type {
camelCase as camelCaseTyped,
snakeCase as snakeCaseTyped,
CamelCase,
SnakeCase,
} from 'literal-case'
const camelCase = camelCaseUntyped as typeof camelCaseTyped
const snakeCase = snakeCaseUntyped as typeof snakeCaseTyped
// type ObjectToCamelCase<T> = {
// [P in keyof T as (P extends string
// ? CamelCase<P>
// : P
// )]: T[P] extends (Record<string, unknown> | unknown[])
// ? ObjectToCamelCase<T[P]>
// : T[P]
// }
type NestedObjectsToCamelCase<
// T extends (Record<string, unknown> | unknown[])
T
> = T extends unknown[]
? {
// Change array elements while keeping prototype properties the same.
[P in keyof T]: P extends number
? NestedObjectsToCamelCase<T[P]>
: T[P]
}
// TODO what about class instances here? Methods would also get transformed. Is it right?
// : T extends Record<string, any>
: T extends Record<string, unknown>
? {
[P in keyof T as (P extends string
? CamelCase<P>
: P
)]: NestedObjectsToCamelCase<T[P]>
}
: T
/**
* Transforms field names to camel case.
*/
export function objectToCamelCase(object: Record<string, any>) {
export function objectToCamelCase<T extends Record<string, any>>(
object: T,
): NestedObjectsToCamelCase<T> {
// When calling recursively, this can be called without being and object or array in which case we just return the value
if (typeof object !== 'object') {

View File

@ -113,8 +113,8 @@ export const checkAndSetApiUrl = (url: string): Promise<string> => {
window.API_URL = oldUrl
throw e
})
.then(r => {
if (typeof r !== 'undefined') {
.then(success => {
if (success) {
localStorage.setItem('API_URL', window.API_URL)
return window.API_URL
}

View File

@ -169,14 +169,6 @@
"title": "List Title",
"color": "Color",
"lists": "Lists",
"list": {
"title": "List",
"add": "Add",
"addPlaceholder": "Add a new task…",
"empty": "This list is currently empty.",
"newTaskCta": "Create a new task.",
"editTask": "Edit Task"
},
"search": "Type to search for a list…",
"searchSelect": "Click or press enter to select this list",
"shared": "Shared Lists",
@ -278,6 +270,14 @@
"delete": "Delete"
}
},
"list": {
"title": "List",
"add": "Add",
"addPlaceholder": "Add a new task…",
"empty": "This list is currently empty.",
"newTaskCta": "Create a new task.",
"editTask": "Edit Task"
},
"gantt": {
"title": "Gantt",
"showTasksWithoutDates": "Show tasks which don't have dates set",
@ -602,6 +602,7 @@
"addReminder": "Add a new reminder…",
"doneSuccess": "The task was successfully marked as done.",
"undoneSuccess": "The task was successfully un-marked as done.",
"undo": "Undo",
"openDetail": "Open task detail view",
"checklistTotal": "{checked} of {total} tasks",
"checklistAllDone": "{total} tasks",

View File

@ -169,14 +169,6 @@
"title": "Název seznamu",
"color": "Barva",
"lists": "Seznamy",
"list": {
"title": "Seznam",
"add": "Přidat",
"addPlaceholder": "Přidat nový úkol…",
"empty": "Tento seznam je nyní prázdný.",
"newTaskCta": "Vytvořit nový úkol.",
"editTask": "Upravit úkol"
},
"search": "Začni psát pro vyhledání seznamu…",
"searchSelect": "Klikněte nebo stiskněte Enter pro výběr tohoto seznamu",
"shared": "Sdílené seznamy",
@ -278,6 +270,14 @@
"delete": "Smazat"
}
},
"list": {
"title": "Seznam",
"add": "Přidat",
"addPlaceholder": "Přidat nový úkol…",
"empty": "Tento seznam je nyní prázdný.",
"newTaskCta": "Vytvořit nový úkol.",
"editTask": "Upravit úkol"
},
"gantt": {
"title": "Gantt",
"showTasksWithoutDates": "Zobrazit úkoly, které nemají nastavené datum",
@ -602,6 +602,7 @@
"addReminder": "Přidat novou připomínku…",
"doneSuccess": "Úkol byl úspěšně označen jako dokončený.",
"undoneSuccess": "Úkol byl úspěšně znovu otevřen.",
"undo": "Undo",
"openDetail": "Otevřít zobrazení detailu úkolu",
"checklistTotal": "{checked} z {total} úkolů",
"checklistAllDone": "{total} úkolů",

View File

@ -169,14 +169,6 @@
"title": "Listetitel",
"color": "Farve",
"lists": "Lister",
"list": {
"title": "Liste",
"add": "Tilføj",
"addPlaceholder": "Tilføj en ny opgave…",
"empty": "Denne liste er i øjeblikket tom.",
"newTaskCta": "Opret en ny opgave.",
"editTask": "Rediger opgave"
},
"search": "Skriv for at søge efter en liste…",
"searchSelect": "Klik eller tryk på Enter for at vælge denne liste",
"shared": "Delte Lister",
@ -278,6 +270,14 @@
"delete": "Slet"
}
},
"list": {
"title": "Liste",
"add": "Tilføj",
"addPlaceholder": "Tilføj en ny opgave…",
"empty": "Denne liste er i øjeblikket tom.",
"newTaskCta": "Opret en ny opgave.",
"editTask": "Rediger opgave"
},
"gantt": {
"title": "Gantt",
"showTasksWithoutDates": "Vis opgaver som ikke har angivet datoer",
@ -602,6 +602,7 @@
"addReminder": "Tilføj en ny påmindelse…",
"doneSuccess": "Opgaven blev markeret som udført.",
"undoneSuccess": "Opgaven fik fjernet sin udført-markering.",
"undo": "Undo",
"openDetail": "Åbn detaljeret opgavevisning",
"checklistTotal": "{checked} af {total} opgaver",
"checklistAllDone": "{total} opgaver",

View File

@ -169,14 +169,6 @@
"title": "Listentitel",
"color": "Farbe",
"lists": "Listen",
"list": {
"title": "Liste",
"add": "Hinzufügen",
"addPlaceholder": "Neue Aufgabe hinzufügen …",
"empty": "Diese Liste ist derzeit leer.",
"newTaskCta": "Eine neue Aufgabe erstellen.",
"editTask": "Aufgabe bearbeiten"
},
"search": "Tippe, um nach einer Liste zu suchen…",
"searchSelect": "Klicke auf oder drücke die Eingabetaste, um diese Liste auszuwählen",
"shared": "Geteilte Listen",
@ -278,6 +270,14 @@
"delete": "Löschen"
}
},
"list": {
"title": "Liste",
"add": "Hinzufügen",
"addPlaceholder": "Neue Aufgabe hinzufügen …",
"empty": "Diese Liste ist derzeit leer.",
"newTaskCta": "Eine neue Aufgabe erstellen.",
"editTask": "Aufgabe bearbeiten"
},
"gantt": {
"title": "Gantt",
"showTasksWithoutDates": "Aufgaben anzeigen, für die keine Daten festgelegt sind",
@ -602,6 +602,7 @@
"addReminder": "Eine Erinnerung hinzufügen…",
"doneSuccess": "Die Aufgabe wurde erfolgreich als erledigt markiert.",
"undoneSuccess": "Die Aufgabe wurde erfolgreich als nicht-erledigt markiert.",
"undo": "Rückgängig",
"openDetail": "Aufgabe in der Detailansicht anzeigen",
"checklistTotal": "{checked} von {total} Aufgaben",
"checklistAllDone": "{total} Aufgaben",

View File

@ -169,14 +169,6 @@
"title": "Liste Titl",
"color": "Farb",
"lists": "Listene",
"list": {
"title": "Liste",
"add": "Hinzuefüege",
"addPlaceholder": "E neui Uufgab erstelle…",
"empty": "D'Liste isch momentan leer.",
"newTaskCta": "Neui Uufgab erstelle.",
"editTask": "Uufgab bearbeite"
},
"search": "Schriib, um nachere Liste z'sueche…",
"searchSelect": "Druck uf Enter um die Liste uuszwähle",
"shared": "Teilti Liste",
@ -278,6 +270,14 @@
"delete": "Chüble"
}
},
"list": {
"title": "Liste",
"add": "Hinzuefüege",
"addPlaceholder": "E neui Uufgab erstelle…",
"empty": "D'Liste isch momentan leer.",
"newTaskCta": "Neui Uufgab erstelle.",
"editTask": "Uufgab bearbeite"
},
"gantt": {
"title": "Gantt",
"showTasksWithoutDates": "Zeig Uufgabe, wo kei Date hend",
@ -602,6 +602,7 @@
"addReminder": "Neui Errinnerig erstelle…",
"doneSuccess": "Die Uufgab isch erfolgriich als \"Fertig\" markiert wordä.",
"undoneSuccess": "Die Uufgaab isch nüme als fertig markiert.",
"undo": "Rückgängig",
"openDetail": "Uufgab i de Detailaahsicht öffne",
"checklistTotal": "{checked} von {total} Aufgaben",
"checklistAllDone": "{total} Aufgaben",

View File

@ -169,7 +169,6 @@
"title": "List Title",
"color": "Color",
"lists": "Lists",
"list": "List",
"search": "Type to search for a list…",
"searchSelect": "Click or press enter to select this list",
"shared": "Shared Lists",
@ -606,6 +605,7 @@
"addReminder": "Add a new reminder…",
"doneSuccess": "The task was successfully marked as done.",
"undoneSuccess": "The task was successfully un-marked as done.",
"undo": "Undo",
"openDetail": "Open task detail view",
"checklistTotal": "{checked} of {total} tasks",
"checklistAllDone": "{total} tasks",

View File

@ -169,14 +169,6 @@
"title": "Título de Lista",
"color": "Color",
"lists": "Listas",
"list": {
"title": "Lista",
"add": "Añadir",
"addPlaceholder": "Añadir una nueva tarea…",
"empty": "This list is currently empty.",
"newTaskCta": "Crear una nueva tarea.",
"editTask": "Editar Tarea"
},
"search": "Escribe para buscar una lista…",
"searchSelect": "Haga clic o presione enter para seleccionar esta lista",
"shared": "Listas Compartidas",
@ -278,6 +270,14 @@
"delete": "Eliminar"
}
},
"list": {
"title": "Lista",
"add": "Añadir",
"addPlaceholder": "Añadir una nueva tarea…",
"empty": "This list is currently empty.",
"newTaskCta": "Crear una nueva tarea.",
"editTask": "Editar Tarea"
},
"gantt": {
"title": "Gantt",
"showTasksWithoutDates": "Mostrar tareas que no tienen fechas establecidas",
@ -602,6 +602,7 @@
"addReminder": "Add a new reminder…",
"doneSuccess": "La tarea fue marcada con éxito como realizada.",
"undoneSuccess": "La tarea fue marcada correctamente como incompleta.",
"undo": "Undo",
"openDetail": "Open task detail view",
"checklistTotal": "{checked} of {total} tasks",
"checklistAllDone": "{total} tasks",

View File

@ -169,14 +169,6 @@
"title": "Nom de la liste",
"color": "Couleur",
"lists": "Listes",
"list": {
"title": "Liste",
"add": "Ajouter",
"addPlaceholder": "Ajouter une nouvelle tâche…",
"empty": "Cette liste est actuellement vide.",
"newTaskCta": "Créer une nouvelle tâche.",
"editTask": "Modifier la tâche"
},
"search": "Écris pour rechercher une liste…",
"searchSelect": "Clique ou appuie sur la touche Entrée pour sélectionner cette liste",
"shared": "Listes partagées",
@ -278,6 +270,14 @@
"delete": "Supprimer"
}
},
"list": {
"title": "Liste",
"add": "Ajouter",
"addPlaceholder": "Ajouter une nouvelle tâche…",
"empty": "Cette liste est actuellement vide.",
"newTaskCta": "Créer une nouvelle tâche.",
"editTask": "Modifier la tâche"
},
"gantt": {
"title": "Gantt",
"showTasksWithoutDates": "Afficher les tâches pour lesquelles aucune date na été fixée",
@ -602,6 +602,7 @@
"addReminder": "Ajouter un nouveau rappel…",
"doneSuccess": "Tâche marquée comme terminée.",
"undoneSuccess": "Tâche marquée comme non terminée.",
"undo": "Undo",
"openDetail": "Ouvrir la vue détaillée de la tâche",
"checklistTotal": "{checked} sur {total} tâches",
"checklistAllDone": "{total} tâches",

View File

@ -169,14 +169,6 @@
"title": "Titolo della Lista",
"color": "Colore",
"lists": "Liste",
"list": {
"title": "Lista",
"add": "Aggiungi",
"addPlaceholder": "Aggiungi una nuova attività…",
"empty": "Questa lista è attualmente vuota.",
"newTaskCta": "Crea una nuova attività.",
"editTask": "Modifica Attività"
},
"search": "Digita per cercare una lista…",
"searchSelect": "Fare clic o premere invio per selezionare questa lista",
"shared": "Liste Condivise",
@ -278,6 +270,14 @@
"delete": "Elimina"
}
},
"list": {
"title": "Lista",
"add": "Aggiungi",
"addPlaceholder": "Aggiungi una nuova attività…",
"empty": "Questa lista è attualmente vuota.",
"newTaskCta": "Crea una nuova attività.",
"editTask": "Modifica Attività"
},
"gantt": {
"title": "Gantt",
"showTasksWithoutDates": "Mostra attività che non hanno date impostate",
@ -405,7 +405,7 @@
"title": "Nuovo Filtro Salvato",
"description": "Un filtro salvato è una lista virtuale che viene calcolata da un insieme di filtri di volta in volta. Una volta creato, apparirà in un namespace speciale.",
"action": "Crea nuovo filtro salvato",
"titleRequired": "Please provide a title for the filter."
"titleRequired": "È necessario un titolo per il filtro."
},
"delete": {
"header": "Elimina questo filtro salvato",
@ -602,6 +602,7 @@
"addReminder": "Aggiungi un nuovo promemoria…",
"doneSuccess": "Attività segnata come completata.",
"undoneSuccess": "Attività segnata come non completata.",
"undo": "Undo",
"openDetail": "Apri vista dettagli attività",
"checklistTotal": "{checked} di {total} attività",
"checklistAllDone": "{total} attività",

View File

@ -169,14 +169,6 @@
"title": "Lijst titel",
"color": "Kleur",
"lists": "Lijsten",
"list": {
"title": "Lijst",
"add": "Toevoegen",
"addPlaceholder": "Voeg een nieuwe taak toe…",
"empty": "Deze lijst is momenteel leeg.",
"newTaskCta": "Creëer een nieuwe taak.",
"editTask": "Taak bewerken"
},
"search": "Typ om naar een lijst te zoeken…",
"searchSelect": "Klik of druk op enter om deze lijst te selecteren",
"shared": "Gedeelde lijsten",
@ -278,6 +270,14 @@
"delete": "Verwijderen"
}
},
"list": {
"title": "Lijst",
"add": "Toevoegen",
"addPlaceholder": "Voeg een nieuwe taak toe…",
"empty": "Deze lijst is momenteel leeg.",
"newTaskCta": "Creëer een nieuwe taak.",
"editTask": "Taak bewerken"
},
"gantt": {
"title": "Gantt",
"showTasksWithoutDates": "Toon taken waarvoor geen datums zijn ingesteld",
@ -602,6 +602,7 @@
"addReminder": "Nieuwe herinnering toevoegen…",
"doneSuccess": "The task was successfully marked as done.",
"undoneSuccess": "The task was successfully un-marked as done.",
"undo": "Undo",
"openDetail": "Open task detail view",
"checklistTotal": "{checked} van {total} taken",
"checklistAllDone": "{total} taken",

View File

@ -169,14 +169,6 @@
"title": "Listenavn",
"color": "Farge",
"lists": "Lister",
"list": {
"title": "Liste",
"add": "Legg til",
"addPlaceholder": "Legg til ny oppgave…",
"empty": "Denne listen er for øyeblikket tom.",
"newTaskCta": "Lage en ny oppgave.",
"editTask": "Endre oppgave"
},
"search": "Skriv for å søke etter en liste…",
"searchSelect": "Klikk eller trykk enter for å velge denne listen",
"shared": "Delte lister",
@ -278,6 +270,14 @@
"delete": "Slett"
}
},
"list": {
"title": "Liste",
"add": "Legg til",
"addPlaceholder": "Legg til ny oppgave…",
"empty": "Denne listen er for øyeblikket tom.",
"newTaskCta": "Lage en ny oppgave.",
"editTask": "Endre oppgave"
},
"gantt": {
"title": "Gantt",
"showTasksWithoutDates": "Vis oppgaver som ikke har datoer angitt",
@ -602,6 +602,7 @@
"addReminder": "Legg til en ny påminnelse…",
"doneSuccess": "Oppgaven ble markert som ferdig.",
"undoneSuccess": "Oppgaven ble fjernet som ferdig.",
"undo": "Undo",
"openDetail": "Åpne detaljvisning",
"checklistTotal": "{checked} av {total} oppgaver",
"checklistAllDone": "{total} oppgaver",

View File

@ -169,14 +169,6 @@
"title": "Tytuł listy",
"color": "Kolor",
"lists": "Listy",
"list": {
"title": "Lista",
"add": "Dodaj",
"addPlaceholder": "Dodaj nowe zadanie…",
"empty": "Ta lista jest obecnie pusta.",
"newTaskCta": "Utwórz nowe zadanie.",
"editTask": "Edytuj zadanie"
},
"search": "Wpisz, aby wyszukać listę…",
"searchSelect": "Kliknij lub naciśnij Enter, aby wybrać tę listę",
"shared": "Współdzielone listy",
@ -278,6 +270,14 @@
"delete": "Usuń"
}
},
"list": {
"title": "Lista",
"add": "Dodaj",
"addPlaceholder": "Dodaj nowe zadanie…",
"empty": "Ta lista jest obecnie pusta.",
"newTaskCta": "Utwórz nowe zadanie.",
"editTask": "Edytuj zadanie"
},
"gantt": {
"title": "Gantt",
"showTasksWithoutDates": "Pokaż zadania, które nie mają ustawionych dat",
@ -602,6 +602,7 @@
"addReminder": "Dodaj nowe przypomnienie…",
"doneSuccess": "Zadanie zostało pomyślnie oznaczone jako ukończone.",
"undoneSuccess": "Zadanie zostało pomyślnie otwarte ponownie.",
"undo": "Undo",
"openDetail": "Otwórz szczegółowy widok zadania",
"checklistTotal": "{checked} z {total} zadań",
"checklistAllDone": "{total} zadań",

View File

@ -169,14 +169,6 @@
"title": "List Title",
"color": "Color",
"lists": "Lists",
"list": {
"title": "List",
"add": "Add",
"addPlaceholder": "Add a new task…",
"empty": "Esta lista está atualmente vazia.",
"newTaskCta": "Criar uma nova tarefa.",
"editTask": "Editar Tarefa"
},
"search": "Type to search for a list…",
"searchSelect": "Click or press enter to select this list",
"shared": "Shared Lists",
@ -278,6 +270,14 @@
"delete": "Delete"
}
},
"list": {
"title": "List",
"add": "Add",
"addPlaceholder": "Add a new task…",
"empty": "Esta lista está atualmente vazia.",
"newTaskCta": "Criar uma nova tarefa.",
"editTask": "Editar Tarefa"
},
"gantt": {
"title": "Gantt",
"showTasksWithoutDates": "Mostrar tarefas que não possuem datas definidas",
@ -602,6 +602,7 @@
"addReminder": "Adicionar um novo lembrete…",
"doneSuccess": "A tarefa foi marcada como feita com sucesso.",
"undoneSuccess": "A tarefa foi desmarcada como feita com sucesso.",
"undo": "Undo",
"openDetail": "Abrir detalhes da tarefa",
"checklistTotal": "{checked} de {total} tarefas",
"checklistAllDone": "{total} tarefas",

View File

@ -169,14 +169,6 @@
"title": "Título da Lista",
"color": "Cor",
"lists": "Listas",
"list": {
"title": "Lista",
"add": "Adicionar",
"addPlaceholder": "Adicionar uma nova tarefa…",
"empty": "Esta lista está atualmente vazia.",
"newTaskCta": "Cria uma nova tarefa.",
"editTask": "Editar Tarefa"
},
"search": "Escreve para pesquisar por uma lista…",
"searchSelect": "Clica ou pressiona Enter para selecionar esta lista",
"shared": "Listas Partilhadas",
@ -278,6 +270,14 @@
"delete": "Eliminar"
}
},
"list": {
"title": "Lista",
"add": "Adicionar",
"addPlaceholder": "Adicionar uma nova tarefa…",
"empty": "Esta lista está atualmente vazia.",
"newTaskCta": "Cria uma nova tarefa.",
"editTask": "Editar Tarefa"
},
"gantt": {
"title": "Gantt",
"showTasksWithoutDates": "Mostrar tarefas que não têm datas atríbuidas",
@ -602,6 +602,7 @@
"addReminder": "Adicionar um novo lembrete…",
"doneSuccess": "A tarefa foi marcada como concluída.",
"undoneSuccess": "A tarefa foi desmarcada como concluída.",
"undo": "Desfazer",
"openDetail": "Abrir vista detalhada da tarefa",
"checklistTotal": "{checked} de {total} tarefas",
"checklistAllDone": "{total} tarefas",

View File

@ -169,14 +169,6 @@
"title": "List Title",
"color": "Color",
"lists": "Lists",
"list": {
"title": "List",
"add": "Add",
"addPlaceholder": "Add a new task…",
"empty": "This list is currently empty.",
"newTaskCta": "Create a new task.",
"editTask": "Edit Task"
},
"search": "Type to search for a list…",
"searchSelect": "Click or press enter to select this list",
"shared": "Shared Lists",
@ -278,6 +270,14 @@
"delete": "Delete"
}
},
"list": {
"title": "List",
"add": "Add",
"addPlaceholder": "Add a new task…",
"empty": "This list is currently empty.",
"newTaskCta": "Create a new task.",
"editTask": "Edit Task"
},
"gantt": {
"title": "Gantt",
"showTasksWithoutDates": "Show tasks which don't have dates set",
@ -602,6 +602,7 @@
"addReminder": "Add a new reminder…",
"doneSuccess": "The task was successfully marked as done.",
"undoneSuccess": "The task was successfully un-marked as done.",
"undo": "Undo",
"openDetail": "Open task detail view",
"checklistTotal": "{checked} of {total} tasks",
"checklistAllDone": "{total} tasks",

View File

@ -169,14 +169,6 @@
"title": "Название списка",
"color": "Цвет",
"lists": "Списки",
"list": {
"title": "Список",
"add": "Добавить",
"addPlaceholder": "Добавить новую задачу…",
"empty": "Список сейчас пуст.",
"newTaskCta": "Создать новую задачу.",
"editTask": "Изменить задачу"
},
"search": "Введите запрос для поиска списка…",
"searchSelect": "Кликните или нажмите Enter для выбора этого списка",
"shared": "Общие списки",
@ -278,6 +270,14 @@
"delete": "Удалить"
}
},
"list": {
"title": "Список",
"add": "Добавить",
"addPlaceholder": "Добавить новую задачу…",
"empty": "Список сейчас пуст.",
"newTaskCta": "Создать новую задачу.",
"editTask": "Изменить задачу"
},
"gantt": {
"title": "Гант",
"showTasksWithoutDates": "Показать задачи без установленной даты",
@ -602,6 +602,7 @@
"addReminder": "Добавить напоминание…",
"doneSuccess": "Задача отмечена как завершённая.",
"undoneSuccess": "Задача отмечена как незавершённая.",
"undo": "Undo",
"openDetail": "Открыть подробный просмотр задачи",
"checklistTotal": "{checked} of {total} tasks",
"checklistAllDone": "{total} tasks",

View File

@ -169,14 +169,6 @@
"title": "List Title",
"color": "Color",
"lists": "Lists",
"list": {
"title": "List",
"add": "Add",
"addPlaceholder": "Add a new task…",
"empty": "This list is currently empty.",
"newTaskCta": "Create a new task.",
"editTask": "Edit Task"
},
"search": "Type to search for a list…",
"searchSelect": "Click or press enter to select this list",
"shared": "Shared Lists",
@ -278,6 +270,14 @@
"delete": "Delete"
}
},
"list": {
"title": "List",
"add": "Add",
"addPlaceholder": "Add a new task…",
"empty": "This list is currently empty.",
"newTaskCta": "Create a new task.",
"editTask": "Edit Task"
},
"gantt": {
"title": "Gantt",
"showTasksWithoutDates": "Show tasks which don't have dates set",
@ -602,6 +602,7 @@
"addReminder": "Add a new reminder…",
"doneSuccess": "The task was successfully marked as done.",
"undoneSuccess": "The task was successfully un-marked as done.",
"undo": "Undo",
"openDetail": "Open task detail view",
"checklistTotal": "{checked} of {total} tasks",
"checklistAllDone": "{total} tasks",

View File

@ -169,14 +169,6 @@
"title": "List Title",
"color": "Color",
"lists": "Lists",
"list": {
"title": "List",
"add": "Add",
"addPlaceholder": "Add a new task…",
"empty": "This list is currently empty.",
"newTaskCta": "Create a new task.",
"editTask": "Edit Task"
},
"search": "Type to search for a list…",
"searchSelect": "Click or press enter to select this list",
"shared": "Shared Lists",
@ -278,6 +270,14 @@
"delete": "Delete"
}
},
"list": {
"title": "List",
"add": "Add",
"addPlaceholder": "Add a new task…",
"empty": "This list is currently empty.",
"newTaskCta": "Create a new task.",
"editTask": "Edit Task"
},
"gantt": {
"title": "Gantt",
"showTasksWithoutDates": "Show tasks which don't have dates set",
@ -602,6 +602,7 @@
"addReminder": "Add a new reminder…",
"doneSuccess": "The task was successfully marked as done.",
"undoneSuccess": "The task was successfully un-marked as done.",
"undo": "Undo",
"openDetail": "Open task detail view",
"checklistTotal": "{checked} of {total} tasks",
"checklistAllDone": "{total} tasks",

View File

@ -169,14 +169,6 @@
"title": "List Title",
"color": "Color",
"lists": "Lists",
"list": {
"title": "List",
"add": "Add",
"addPlaceholder": "Add a new task…",
"empty": "This list is currently empty.",
"newTaskCta": "Create a new task.",
"editTask": "Edit Task"
},
"search": "Type to search for a list…",
"searchSelect": "Click or press enter to select this list",
"shared": "Shared Lists",
@ -278,6 +270,14 @@
"delete": "Delete"
}
},
"list": {
"title": "List",
"add": "Add",
"addPlaceholder": "Add a new task…",
"empty": "This list is currently empty.",
"newTaskCta": "Create a new task.",
"editTask": "Edit Task"
},
"gantt": {
"title": "Gantt",
"showTasksWithoutDates": "Show tasks which don't have dates set",
@ -602,6 +602,7 @@
"addReminder": "Add a new reminder…",
"doneSuccess": "The task was successfully marked as done.",
"undoneSuccess": "The task was successfully un-marked as done.",
"undo": "Undo",
"openDetail": "Open task detail view",
"checklistTotal": "{checked} of {total} tasks",
"checklistAllDone": "{total} tasks",

View File

@ -169,14 +169,6 @@
"title": "Tên Danh sách",
"color": "Màu sắc",
"lists": "Danh sách",
"list": {
"title": "Danh sách",
"add": "Thêm",
"addPlaceholder": "Thêm việc cần làm…",
"empty": "Danh sách này đang trống trơn.",
"newTaskCta": "Thêm một công việc mới.",
"editTask": "Chỉnh sửa Công việc"
},
"search": "Gõ để tìm kiếm danh sách…",
"searchSelect": "Nhấp hoặc nhấn enter để chọn danh sách này",
"shared": "Đang tham gia",
@ -278,6 +270,14 @@
"delete": "Xóa"
}
},
"list": {
"title": "Danh sách",
"add": "Thêm",
"addPlaceholder": "Thêm việc cần làm…",
"empty": "Danh sách này đang trống trơn.",
"newTaskCta": "Thêm một công việc mới.",
"editTask": "Chỉnh sửa Công việc"
},
"gantt": {
"title": "Biểu đồ Gantt",
"showTasksWithoutDates": "Hiển thị các nhiệm vụ không cài đặt ngày",
@ -602,6 +602,7 @@
"addReminder": "Thêm lời nhắc mới…",
"doneSuccess": "Công việc đã được đánh dấu Hoàn thành.",
"undoneSuccess": "Công việc đã được bỏ đánh dấu Hoàn thành.",
"undo": "Undo",
"openDetail": "Xem chi tiết công việc",
"checklistTotal": "{checked} trong số {total} công việc",
"checklistAllDone": "{total} coogn việc",

View File

@ -169,14 +169,6 @@
"title": "列表名",
"color": "列表颜色",
"lists": "列表",
"list": {
"title": "列表",
"add": "新建",
"addPlaceholder": "添加新任务",
"empty": "此列表目前为空。",
"newTaskCta": "新建任务。",
"editTask": "编辑任务"
},
"search": "输入以搜索列表…",
"searchSelect": "点击或按下回车键以选择",
"shared": "共享列表",
@ -278,6 +270,14 @@
"delete": "删除"
}
},
"list": {
"title": "列表",
"add": "新建",
"addPlaceholder": "添加新任务",
"empty": "此列表目前为空。",
"newTaskCta": "新建任务。",
"editTask": "编辑任务"
},
"gantt": {
"title": "甘特图",
"showTasksWithoutDates": "显示未设定日期的任务",
@ -602,6 +602,7 @@
"addReminder": "添加一个新的提醒…",
"doneSuccess": "待办事项已标记为完成。",
"undoneSuccess": "待办事项已标记为未完成。",
"undo": "Undo",
"openDetail": "查看任务详细信息",
"checklistTotal": "{checked} 项任务,共 {total} 项。",
"checklistAllDone": "一共 {total} 项任务",

View File

@ -169,14 +169,6 @@
"title": "List Title",
"color": "Color",
"lists": "Lists",
"list": {
"title": "List",
"add": "Add",
"addPlaceholder": "Add a new task…",
"empty": "This list is currently empty.",
"newTaskCta": "Create a new task.",
"editTask": "Edit Task"
},
"search": "Type to search for a list…",
"searchSelect": "Click or press enter to select this list",
"shared": "Shared Lists",
@ -278,6 +270,14 @@
"delete": "Delete"
}
},
"list": {
"title": "List",
"add": "Add",
"addPlaceholder": "Add a new task…",
"empty": "This list is currently empty.",
"newTaskCta": "Create a new task.",
"editTask": "Edit Task"
},
"gantt": {
"title": "Gantt",
"showTasksWithoutDates": "Show tasks which don't have dates set",
@ -602,6 +602,7 @@
"addReminder": "Add a new reminder…",
"doneSuccess": "The task was successfully marked as done.",
"undoneSuccess": "The task was successfully un-marked as done.",
"undo": "Undo",
"openDetail": "Open task detail view",
"checklistTotal": "{checked} of {total} tasks",
"checklistAllDone": "{total} tasks",

View File

@ -39,74 +39,76 @@ if (window.API_URL.slice(window.API_URL.length - 1, window.API_URL.length) === '
window.API_URL = window.API_URL.slice(0, window.API_URL.length - 1)
}
const app = createApp(App)
app.use(Notifications)
// directives
import focus from '@/directives/focus'
import { VTooltip } from 'floating-vue'
import {VTooltip} from 'floating-vue'
import 'floating-vue/dist/style.css'
import shortcut from '@/directives/shortcut'
import cypress from '@/directives/cypress'
app.directive('focus', focus)
app.directive('tooltip', VTooltip)
app.directive('shortcut', shortcut)
app.directive('cy', cypress)
// global components
import FontAwesomeIcon from '@/components/misc/Icon'
import Button from '@/components/input/button.vue'
import Modal from '@/components/misc/modal.vue'
import Card from '@/components/misc/card.vue'
app.component('icon', FontAwesomeIcon)
app.component('x-button', Button)
app.component('modal', Modal)
app.component('card', Card)
app.config.errorHandler = (err, vm, info) => {
if (import.meta.env.DEV) {
console.error(err, vm, info)
}
error(err)
}
if (import.meta.env.DEV) {
app.config.warnHandler = (msg) => {
error(msg)
throw(msg)
}
// https://stackoverflow.com/a/52076738/15522256
window.addEventListener('error', (err) => {
error(err)
throw err
})
window.addEventListener('unhandledrejection', (err) => {
// event.promise contains the promise object
// event.reason contains the reason for the rejection
error(err)
throw err
})
}
app.config.globalProperties.$message = {
error,
success,
}
if (window.SENTRY_ENABLED) {
import('./sentry').then(sentry => sentry.default(app, router))
}
app.use(pinia)
app.use(router)
app.use(i18n)
// We're loading the language before creating the app so that it won't fail to load when the user's
// language file is not yet loaded.
setLanguage().then(() => {
const app = createApp(App)
app.use(Notifications)
app.directive('focus', focus)
app.directive('tooltip', VTooltip)
app.directive('shortcut', shortcut)
app.directive('cy', cypress)
app.component('icon', FontAwesomeIcon)
app.component('x-button', Button)
app.component('modal', Modal)
app.component('card', Card)
app.config.errorHandler = (err, vm, info) => {
if (import.meta.env.DEV) {
console.error(err, vm, info)
}
error(err)
}
if (import.meta.env.DEV) {
app.config.warnHandler = (msg) => {
error(msg)
throw(msg)
}
// https://stackoverflow.com/a/52076738/15522256
window.addEventListener('error', (err) => {
error(err)
throw err
})
window.addEventListener('unhandledrejection', (err) => {
// event.promise contains the promise object
// event.reason contains the reason for the rejection
error(err)
throw err
})
}
app.config.globalProperties.$message = {
error,
success,
}
if (window.SENTRY_ENABLED) {
import('./sentry').then(sentry => sentry.default(app, router))
}
app.use(pinia)
app.use(router)
app.use(i18n)
app.mount('#app')
})
})

View File

@ -17,7 +17,12 @@ export function getErrorText(r): string {
return data?.message || r.message
}
export function error(e, actions = []) {
export interface Action {
title: string,
callback: () => void,
}
export function error(e, actions: Action[] = []) {
notify({
type: 'error',
title: i18n.global.t('error.error'),
@ -26,7 +31,7 @@ export function error(e, actions = []) {
})
}
export function success(e, actions = []) {
export function success(e, actions: Action[] = []) {
notify({
type: 'success',
title: i18n.global.t('error.success'),

View File

@ -126,6 +126,12 @@ export default abstract class AbstractService<Model extends IAbstract = IAbstrac
/**
* Returns an object with all route parameters and their values.
* @example
* getRouteReplacements(
* '/tasks/{taskId}/assignees/{userId}',
* { taskId: 7, userId: 2 },
* )
* // { "{taskId}": 7, "{userId}": 2 }
*/
getRouteReplacements(route : string, parameters : Record<string, unknown> = {}) {
const replace$$1: Record<string, unknown> = {}
@ -148,6 +154,8 @@ export default abstract class AbstractService<Model extends IAbstract = IAbstrac
/**
* Returns a fully-ready-ready-to-make-a-request-to route with replaced parameters.
* @example
* getReplacedRoute('/lists/{listId}/tasks', { listId: 3 }) === '/lists/1/tasks'
*/
getReplacedRoute(path : string, pathparams : Record<string, unknown>) : string {
const replacements = this.getRouteReplacements(path, pathparams)
@ -303,7 +311,7 @@ export default abstract class AbstractService<Model extends IAbstract = IAbstrac
* @param params Optional query parameters
* @param page The page to get
*/
async getAll(model : Model = new AbstractModel({}), params = {}, page = 1) {
async getAll(model : Model = new AbstractModel({}), params = {}, page = 1): Promise<Model[]> {
if (this.paths.getAll === '') {
throw new Error('This model is not able to get data.')
}
@ -323,10 +331,7 @@ export default abstract class AbstractService<Model extends IAbstract = IAbstrac
return []
}
if (Array.isArray(response.data)) {
return response.data.map(entry => this.modelGetAllFactory(entry))
}
return this.modelGetAllFactory(response.data)
return response.data.map(entry => this.modelGetAllFactory(entry))
} finally {
cancel()
}

View File

@ -6,6 +6,7 @@ import {HTTPFactory} from '@/helpers/fetcher'
import {objectToCamelCase} from '@/helpers/case'
import type {IProvider} from '@/types/IProvider'
import type {MIGRATORS} from '@/views/migrate/migrators'
export interface ConfigState {
version: string,
@ -14,10 +15,10 @@ export interface ConfigState {
linkSharingEnabled: boolean,
maxFileSize: string,
registrationEnabled: boolean,
availableMigrators: [],
availableMigrators: Array<keyof typeof MIGRATORS>,
taskAttachmentsEnabled: boolean,
totpEnabled: boolean,
enabledBackgroundProviders: [],
enabledBackgroundProviders: Array<'unsplash' | 'upload'>,
legal: {
imprintUrl: string,
privacyPolicyUrl: string,
@ -78,11 +79,12 @@ export const useConfigStore = defineStore('config', () => {
function setConfig(config: ConfigState) {
Object.assign(state, config)
}
async function update() {
async function update(): Promise<boolean> {
const HTTP = HTTPFactory()
const {data: config} = await HTTP.get('info')
setConfig(objectToCamelCase(config))
return config
const success = !!config
return success
}
return {

View File

@ -196,7 +196,7 @@ import FilterPopup from '@/components/list/partials/filter-popup.vue'
import Pagination from '@/components/misc/pagination.vue'
import Popup from '@/components/misc/popup.vue'
import {useTaskList} from '@/composables/useTaskList'
import {useTaskList, SortBy} from '@/composables/useTaskList'
import type {ITask} from '@/modelTypes/ITask'
const ACTIVE_COLUMNS_DEFAULT = {
@ -222,21 +222,6 @@ const props = defineProps({
},
})
type Order = 'asc' | 'desc' | 'none'
interface SortBy {
index: Order
done?: Order
title?: Order
priority?: Order
due_date?: Order
start_date?: Order
end_date?: Order
percent_done?: Order
created?: Order
updated?: Order
}
const SORT_BY_DEFAULT: SortBy = {
index: 'desc',
}
@ -244,7 +229,7 @@ const SORT_BY_DEFAULT: SortBy = {
const activeColumns = useStorage('tableViewColumns', {...ACTIVE_COLUMNS_DEFAULT})
const sortBy = useStorage<SortBy>('tableViewSortBy', {...SORT_BY_DEFAULT})
const taskList = useTaskList(toRef(props, 'listId'))
const taskList = useTaskList(toRef(props, 'listId'), sortBy.value)
const {
loading,

View File

@ -16,7 +16,7 @@ interface IMigratorRecord {
[key: Migrator['id']]: Migrator
}
export const MIGRATORS: IMigratorRecord = {
export const MIGRATORS = {
wunderlist: {
id: 'wunderlist',
name: 'Wunderlist',
@ -49,4 +49,4 @@ export const MIGRATORS: IMigratorRecord = {
icon: tickTickIcon as string,
isFileMigrator: true,
},
} as const
} as const satisfies IMigratorRecord

View File

@ -496,6 +496,7 @@ import {useKanbanStore} from '@/stores/kanban'
import {useTitle} from '@/composables/useTitle'
import {success} from '@/message'
import type {Action as MessageAction} from '@/message'
const props = defineProps({
taskId: {
@ -728,10 +729,10 @@ async function saveTask(args?: {
Object.assign(task, newTask)
setActiveFields()
let actions = []
let actions: MessageAction[] = []
if (undoCallback !== null) {
actions = [{
title: 'Undo',
title: t('task.undo'),
callback: undoCallback,
}]
}