Compare commits

..

372 Commits

Author SHA1 Message Date
Dominik Pschenitschni 8eba71d448
feat: remove duplicate rel attribute
continuous-integration/drone/pr Build was killed Details
2022-04-02 17:28:40 +02:00
Dominik Pschenitschni da54bb92fe
feat: flatten and reorder after all 2022-04-02 17:28:40 +02:00
Dominik Pschenitschni 8b7f95135b
chore: use BaseButton 2022-04-02 17:28:39 +02:00
kolaente 8909e43410
chore: use .then instead of await 2022-04-02 17:28:39 +02:00
kolaente a53ca6a201
chore: directly use newToken.value 2022-04-02 17:28:39 +02:00
kolaente 99da686a70
chore: rename to useTokens 2022-04-02 17:28:39 +02:00
kolaente cf714f09ff
chore: use h5 2022-04-02 17:28:39 +02:00
kolaente eb196a8260
chore: return new model instead of modifying the existing 2022-04-02 17:28:39 +02:00
kolaente e28d2aab43
chore: fix CalDAV casing 2022-04-02 17:28:39 +02:00
kolaente b7b2a9ff16
chore: move success message after state changes 2022-04-02 17:28:39 +02:00
kolaente d7ca43d6f8
chore: use function statements everywhere 2022-04-02 17:28:39 +02:00
kolaente 36d0c2af20
chore: check for no results 2022-04-02 17:28:39 +02:00
kolaente 11a83dd42c
fix: type 2022-04-02 17:28:38 +02:00
kolaente ddbbf60f49
fix: lint 2022-04-02 17:28:38 +02:00
kolaente 1bb9d9ae3f
chore: extract getting all tokens into a composable 2022-04-02 17:28:38 +02:00
kolaente 727cf79005
chore: make server functions async 2022-04-02 17:28:38 +02:00
kolaente e12691998e
chore: use findIndex to remove caldav token 2022-04-02 17:28:38 +02:00
kolaente 4cfbdd51f7
chore: use ts for caldav component 2022-04-02 17:28:38 +02:00
kolaente d2ffc58088
chore: clarify token is required for non-local users 2022-04-02 17:28:38 +02:00
kolaente dad399dce2
chore: put action buttons right 2022-04-02 17:28:38 +02:00
kolaente 69c5e8bd1c
feat: manage tokens 2022-04-02 17:28:36 +02:00
kolaente 7878e3f30f
chore: move to script setup 2022-04-02 17:28:21 +02:00
konrad 4cff3ebee1 feat: use blurHash when loading list backgrounds (#1188)
continuous-integration/drone/push Build is passing Details
Co-authored-by: kolaente <k@knt.li>
Reviewed-on: #1188
2022-04-02 15:05:30 +00:00
kolaente 53787a65df
fix: lint
continuous-integration/drone/push Build is passing Details
2022-04-02 14:57:03 +02:00
kolaente dfed1f438a
feat: directly create a new task from relations when none was selected
continuous-integration/drone/push Build is failing Details
2022-04-02 13:54:45 +02:00
kolaente ad8ca462cb
fix: indention of nested checklist items
continuous-integration/drone/push Build is passing Details
2022-04-02 12:55:08 +02:00
kolaente 2e537f6d63
fix: loading list views would sometimes not get loaded
continuous-integration/drone/push Build is passing Details
To make sure the tasks of a list are only loaded after the list itself is fetched from the server, we hide the list view until the list is fully loaded. When switching between different views of the same list, this would cause the list view to not be loaded at all because the list was already loaded at that point.

closes #1732
2022-04-02 12:47:13 +02:00
renovate 4bf016f53e chore(deps): update dependency caniuse-lite to v1.0.30001324 (#1759)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1759
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-04-02 08:33:23 +00:00
renovate deff90bd8f chore(deps): update dependency sass to v1.49.11 (#1757)
continuous-integration/drone/push Build is failing Details
Reviewed-on: #1757
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-04-02 07:02:46 +00:00
renovate 5dbdfd3cd5 chore(deps): update dependency esbuild to v0.14.30 (#1758)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1758
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-04-02 07:02:20 +00:00
renovate 2719e93cf1 chore(deps): update dependency vitest to v0.8.2 (#1756)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1756
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-04-01 20:14:17 +00:00
renovate 756104c7b5 chore(deps): update dependency happy-dom to v2.55.0 (#1755)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1755
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-04-01 05:47:11 +00:00
renovate ddec4bd979 fix(deps): update dependency @vueuse/router to v8.2.3 (#1752)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1752
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-31 21:29:57 +00:00
renovate d14d2405d6 fix(deps): update dependency @vueuse/core to v8.2.3 (#1751)
continuous-integration/drone/push Build is failing Details
Reviewed-on: #1751
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-31 21:03:19 +00:00
renovate 753e03dd46 chore(deps): update dependency happy-dom to v2.54.0 (#1753)
continuous-integration/drone/push Build is failing Details
Reviewed-on: #1753
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-31 21:02:55 +00:00
renovate cd9928036d fix(deps): update dependency ufo to v0.8.3 (#1754)
continuous-integration/drone/push Build is failing Details
Reviewed-on: #1754
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-31 21:02:31 +00:00
renovate e29b191fbe chore(deps): update dependency vite to v2.9.1 (#1750)
continuous-integration/drone/push Build is failing Details
Reviewed-on: #1750
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-31 21:02:08 +00:00
renovate e8d8767d31 fix(deps): update dependency @vueuse/router to v8.2.2 (#1745)
continuous-integration/drone/push Build is failing Details
Reviewed-on: #1745
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-31 11:37:49 +00:00
renovate 2966e0846a chore(deps): update dependency vite-svg-loader to v3.2.0 (#1743)
continuous-integration/drone/push Build is failing Details
Reviewed-on: #1743
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-31 11:37:30 +00:00
renovate 7870247ad1 chore(deps): update dependency @vitejs/plugin-vue to v2.3.1 (#1746)
continuous-integration/drone/push Build is failing Details
Reviewed-on: #1746
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-31 11:36:59 +00:00
renovate 1f769ae3ab chore(deps): update dependency happy-dom to v2.53.0 (#1749)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1749
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-31 10:37:09 +00:00
renovate c0ecde5029 chore(deps): update dependency sass to v1.49.10 (#1747)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1747
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-31 10:36:43 +00:00
renovate 94be991ff6 fix(deps): update dependency @vueuse/core to v8.2.2 (#1744)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1744
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-31 10:36:20 +00:00
renovate 5a27973a23 chore(deps): update dependency caniuse-lite to v1.0.30001323 (#1748)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1748
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-31 08:41:00 +00:00
drone e494af094d [skip ci] Updated translations via Crowdin 2022-03-31 00:29:19 +00:00
renovate ae643c49d2 chore(deps): update dependency @vitejs/plugin-vue to v2.3.0 (#1739)
continuous-integration/drone/push Build is failing Details
Reviewed-on: #1739
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-30 17:40:15 +00:00
renovate ab569760ef chore(deps): update dependency @vitejs/plugin-legacy to v1.8.0 (#1738)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1738
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-30 15:52:38 +00:00
renovate 614f15cf4a chore(deps): update dependency vitest to v0.8.1 (#1740)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1740
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-30 15:51:49 +00:00
renovate 4b1003e5e4 chore(deps): update dependency happy-dom to v2.52.0 (#1741)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1741
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-30 15:51:28 +00:00
renovate 78c6d6bb1d chore(deps): update dependency vite to v2.9.0 (#1742)
continuous-integration/drone/push Build is failing Details
Reviewed-on: #1742
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-30 15:50:31 +00:00
renovate 5a214ce22c chore(deps): update dependency esbuild to v0.14.29 (#1736)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1736
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-30 05:59:57 +00:00
renovate 3f68121750 fix(deps): update sentry-javascript monorepo to v6.19.3 (#1735)
continuous-integration/drone/push Build is failing Details
Reviewed-on: #1735
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-30 05:59:12 +00:00
drone f3294ce755 [skip ci] Updated translations via Crowdin 2022-03-30 00:29:13 +00:00
renovate 897ba39037 chore(deps): update dependency caniuse-lite to v1.0.30001322 (#1730)
continuous-integration/drone/push Build is failing Details
Reviewed-on: #1730
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-29 15:25:21 +00:00
renovate 0c12c4ebd6 chore(deps): update dependency vitest to v0.8.0 (#1731)
continuous-integration/drone/push Build is failing Details
Reviewed-on: #1731
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-29 15:24:52 +00:00
renovate 6be67cfb98 chore(deps): update dependency happy-dom to v2.51.0 (#1733)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1733
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-29 15:24:21 +00:00
renovate 160c099ff8 chore(deps): update dependency @faker-js/faker to v6.1.1 (#1728)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1728
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-29 05:25:42 +00:00
renovate 5d7de25a92 chore(deps): update dependency cypress to v9.5.3 (#1729)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1729
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-28 21:26:43 +00:00
konrad 9b09fadbd0 feat: add date math for filters (#1342)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1342
2022-03-28 17:30:42 +00:00
renovate 75c68aa03e chore(deps): update typescript-eslint monorepo to v5.17.0 (#1727)
continuous-integration/drone/push Build is failing Details
Reviewed-on: #1727
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-28 17:28:16 +00:00
renovate c49d582a03 chore(deps): update dependency netlify-cli to v9.13.5 (#1726)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1726
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-28 05:18:34 +00:00
kolaente 46050611d8 fix: forgotten import
continuous-integration/drone/push Build is passing Details
2022-03-27 21:06:30 +00:00
kolaente a055a3ea52 fix: lint 2022-03-27 21:06:30 +00:00
kolaente b7a976a9cf fix: setting the last viewed list after navigating away from it
The new list background was set on the home page when navigating to the list. This was because the `CURRENT_LIST` was set to the last visited list, even after the call to `this.$store.commit(CURRENT_LIST, null)` because everything is async. I tracked the problem down to the call to `watchEffect` in the ListWrapper component. Apparently, `watchEffect` is called every time _the watched variable is assigned to_ and not only when it changes. When navigating away from the list, that watcher is getting called with the list id, the one already loaded, and sets it in store which in turn overrides the call from the contentAuth component.
2022-03-27 21:06:30 +00:00
kolaente 42c0fc6185 fix: make sure a list background is set in store when adding one
When creating a new list, setting a background and then navigating to the home page, the list background would not be shown in the list card. Now, we're setting the newly updated list with all its background information properly in store (why are there even multiple places for this?).
2022-03-27 21:06:30 +00:00
kolaente f9b7e2fd76 feat: use vueuse to lock scrolling
continuous-integration/drone/push Build is failing Details
2022-03-27 20:42:21 +00:00
kolaente 574ecff12d feat: prevent scrolling the rest of the page when a modal is open 2022-03-27 20:42:21 +00:00
kolaente 0af6d79eff
Merge branch 'main' into feature/date-math
continuous-integration/drone/pr Build is passing Details
2022-03-27 22:41:53 +02:00
konrad 3639498b3f fix: add task input layout on mobile (#1615)
continuous-integration/drone/push Build is failing Details
On non-english locales the placeholder text would wrap, making the placeholder longer than it needed to be. To fix that, I've made sure the placeholder will never wrap and reduced the button to a single icon.

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: #1615
2022-03-27 20:37:25 +00:00
konrad 7f56a3537c fix: load the list tasks only after the list itself was loaded (#1251)
continuous-integration/drone/push Build is failing Details
Currently, when opening a list sometimes the tasks are shown before the list itself is loaded. Because the list contains the rights, this means no edit buttons etc are available at that point which is pretty confusing.

This PR ensures the list-specific view is loaded only after the list itself is loaded.

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: #1251
2022-03-27 19:56:56 +00:00
adrinux a8fe2cdcbd Redefine all Bulma variables to fix undefined variables (#1165)
continuous-integration/drone/push Build is failing Details
As per discussion in #1074

This will hopefully eventually be fixed at the root - with missing scss variables properly passed though, possibly by switching to Bulvar.

But in the mean time I experimented with add ALL the bulma css color related variables into color.scss

This fixes the issue with the date picker in light mode. Also has me wondering if it will allow removal of some of other little overrides we made to fix niggling issues with dark mode, so marking this WIP.

Not suggesting this ever be merged, just exploring.

Resolves #1497
Resolves #1074

Co-authored-by: Adrian Simmons <adrian@perlucida.co.uk>
Co-authored-by: kolaente <k@knt.li>
Reviewed-on: #1165
Reviewed-by: konrad <k@knt.li>
Co-authored-by: adrinux <adrian@perlucida.co.uk>
Co-committed-by: adrinux <adrian@perlucida.co.uk>
2022-03-27 19:20:37 +00:00
renovate c8fa0cc6b1 chore(deps): update workbox monorepo to v6.5.2 (#1725)
continuous-integration/drone/push Build is passing Details
Co-authored-by: kolaente <k@knt.li>
Reviewed-on: #1725
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-27 15:12:03 +00:00
renovate fcc096dcf7 chore(deps): update dependency vitest to v0.7.12 (#1724)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1724
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-27 10:31:37 +00:00
renovate d696d16139 chore(deps): update dependency eslint to v8.12.0 (#1722)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1722
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-27 08:52:01 +00:00
renovate 81efe27d50 fix(deps): update dependency @vueuse/router to v8.2.0 (#1721)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1721
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-26 19:12:15 +00:00
renovate bd52ac71aa chore(deps): update dependency esbuild to v0.14.28 (#1723)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1723
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-26 19:11:51 +00:00
renovate b949c9f832 fix(deps): update dependency @vueuse/core to v8.2.0 (#1720)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1720
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-25 17:59:16 +00:00
renovate 1f4a016075 chore(deps): update dependency vitest to v0.7.11 (#1718)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1718
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-25 15:28:48 +00:00
renovate 94c0f6d00f chore(deps): update dependency typescript to v4.6.3 (#1717)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1717
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-25 14:32:08 +00:00
renovate 06f0597b13 chore(deps): update dependency vue-tsc to v0.33.9 (#1719)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1719
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-25 14:30:45 +00:00
renovate bfe28787c3 chore(deps): update dependency caniuse-lite to v1.0.30001320 (#1716)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1716
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-24 06:50:43 +00:00
renovate 8e6aa35f89 fix(deps): update sentry-javascript monorepo to v6.19.2 (#1715)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1715
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-23 21:19:55 +00:00
renovate 25ca3e5eaf chore(deps): update dependency vitest to v0.7.10 (#1714)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1714
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-23 13:51:10 +00:00
renovate 188eb02e07 chore(deps): update dependency vitest to v0.7.8 (#1713)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1713
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-23 10:44:42 +00:00
renovate 3605d61a17 chore(deps): update dependency vue-tsc to v0.33.7 (#1712)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1712
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-23 08:13:59 +00:00
kolaente 87ac22b448
fix: related done tasks strikethrough
continuous-integration/drone/push Build is passing Details
2022-03-22 23:06:36 +01:00
kolaente 8f650316dc
fix: multiselect search results text color
continuous-integration/drone/push Build is passing Details
2022-03-22 23:04:06 +01:00
kolaente d7b1d7da7f
fix: mobile menu backdrop
continuous-integration/drone/push Build is passing Details
2022-03-22 23:00:43 +01:00
kolaente 63e04f874a
fix: modal close icon color in light mode on mobile
continuous-integration/drone/push Build is failing Details
2022-03-22 22:55:28 +01:00
renovate 09f6c0d43e chore(deps): update dependency happy-dom to v2.50.0 (#1711)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1711
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-22 19:17:17 +00:00
renovate 2b6cbe8006 chore(deps): update font awesome to v6.1.1 (#1710)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1710
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-22 18:37:34 +00:00
renovate 501a720b7c fix(deps): update sentry-javascript monorepo to v6.19.1 (#1708)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1708
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-21 19:50:38 +00:00
renovate a72329599b chore(deps): update typescript-eslint monorepo to v5.16.0 (#1707)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1707
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-21 17:28:49 +00:00
renovate 50871beeee chore(deps): update dependency vue-tsc to v0.33.6 (#1706)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1706
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-21 17:28:21 +00:00
renovate 51cafb9d56 fix(deps): update sentry-javascript monorepo to v6.19.0 (#1705)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1705
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-21 17:27:27 +00:00
renovate 73ff2d4407 chore(deps): update dependency happy-dom to v2.49.2 (#1704)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1704
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-21 14:29:28 +00:00
renovate 3f4bb1b64b chore(deps): update dependency vitest to v0.7.7 (#1702)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1702
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-21 13:19:32 +00:00
renovate 6a5f5f81a8 chore(deps): update dependency happy-dom to v2.49.1 (#1703)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1703
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-21 13:18:38 +00:00
renovate c90f87f74a chore(deps): update dependency netlify-cli to v9.13.3 (#1700)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1700
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-21 06:50:00 +00:00
renovate a8da12a894 chore(deps): update dependency vue-tsc to v0.33.5 (#1701)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1701
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-21 06:49:22 +00:00
renovate ae6c982755 chore(deps): update dependency postcss-preset-env to v7.4.3 (#1699)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1699
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-20 10:19:24 +00:00
drone 8f367921cf [skip ci] Updated translations via Crowdin 2022-03-20 00:27:38 +00:00
renovate ea9e84b4d9 fix(deps): update dependency @vueuse/core to v8.1.2 (#1696)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1696
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-19 13:56:50 +00:00
renovate 8aeaa322fe chore(deps): update yarn to v1.22.18 (#1694)
continuous-integration/drone/push Build is failing Details
Reviewed-on: #1694
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-19 11:12:20 +00:00
renovate 83a91e9a11 fix(deps): update dependency @vueuse/router to v8.1.2 (#1697)
continuous-integration/drone/push Build is failing Details
Reviewed-on: #1697
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-19 11:11:54 +00:00
renovate 5e6bce8b7e chore(deps): update dependency vitest to v0.7.6 (#1698)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1698
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-19 11:11:32 +00:00
renovate 574b000b19 chore(deps): update dependency caniuse-lite to v1.0.30001319 (#1695)
continuous-integration/drone/push Build is failing Details
Reviewed-on: #1695
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-19 11:11:11 +00:00
renovate 2c929c1f91 chore(deps): update dependency vitest to v0.7.4 (#1693)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1693
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-17 21:10:10 +00:00
renovate c41f3edc99 chore(deps): update dependency @types/flexsearch to v0.7.3 (#1677)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1677
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-17 12:21:30 +00:00
renovate 9606edbb39 fix(deps): update dependency @vueuse/router to v8.1.1 (#1691)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1691
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-17 07:27:25 +00:00
renovate 360b4da7d3 chore(deps): update dependency vitest to v0.7.0 (#1692)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1692
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-17 06:49:06 +00:00
renovate 7564c26201 fix(deps): update dependency @vueuse/core to v8.1.1 (#1690)
continuous-integration/drone/push Build is failing Details
Reviewed-on: #1690
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-16 21:22:59 +00:00
renovate 6432d18c1b chore(deps): update dependency vitest to v0.6.3 (#1688)
continuous-integration/drone/push Build is failing Details
Reviewed-on: #1688
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-16 15:31:56 +00:00
renovate b57540a8ff fix(deps): update dependency ufo to v0.8.1 (#1689)
continuous-integration/drone/push Build is failing Details
Reviewed-on: #1689
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-16 15:31:24 +00:00
renovate 4c43c87bfe chore(deps): update dependency postcss to v8.4.12 (#1687)
continuous-integration/drone/push Build is failing Details
Reviewed-on: #1687
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-16 15:31:03 +00:00
renovate 83b1333ee5 chore(deps): update dependency happy-dom to v2.49.0 (#1680)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1680
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-16 15:30:32 +00:00
renovate eadfc3442f chore(deps): update dependency autoprefixer to v10.4.4 (#1686)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1686
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-16 13:15:51 +00:00
renovate 14a7676fe4 chore(deps): update dependency @faker-js/faker to v6.0.0 (#1681)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1681
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-15 22:28:20 +00:00
renovate 148046f7b8 chore(deps): update dependency browserslist to v4.20.2 (#1683)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1683
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-15 22:27:34 +00:00
renovate 75ec8889a9 fix(deps): update dependency ufo to v0.8.0 (#1685)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1685
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-15 22:23:04 +00:00
renovate 2292be3ff3 chore(deps): update dependency postcss to v8.4.11 (#1684)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1684
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-15 22:20:49 +00:00
renovate c2ee125ba2 chore(deps): update dependency autoprefixer to v10.4.3 (#1682)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1682
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-15 19:57:22 +00:00
renovate df53dc76ce chore(deps): update font awesome to v6 (major) (#1505)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1505
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-15 19:55:37 +00:00
renovate 1d9fef9172 chore(deps): update dependency esbuild to v0.14.27 (#1678)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1678
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-15 13:24:54 +00:00
renovate 19b4fc20a1 chore(deps): update dependency caniuse-lite to v1.0.30001317 (#1679)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1679
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-15 13:24:01 +00:00
renovate d1e8931600 chore(deps): update dependency cypress to v9.5.2 (#1676)
continuous-integration/drone/push Build is failing Details
Reviewed-on: #1676
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-15 12:31:00 +00:00
renovate 2dc888790f chore(deps): update dependency vue-tsc to v0.33.2 (#1674)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1674
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-14 20:25:22 +00:00
renovate 811d62eb52 chore(deps): update dependency happy-dom to v2.47.0 (#1673)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1673
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-14 20:24:53 +00:00
renovate 83159b44d0 chore(deps): update typescript-eslint monorepo to v5.15.0 (#1675)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1675
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-14 20:24:13 +00:00
renovate b9c677e871 chore(deps): update dependency caniuse-lite to v1.0.30001316 (#1672)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1672
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-14 13:52:19 +00:00
renovate 4fab17f798 fix(deps): update dependency @vueuse/router to v8.0.1 (#1669)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1669
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-14 13:51:55 +00:00
renovate e95705f45f fix(deps): update dependency @vueuse/core to v8.0.1 (#1668)
continuous-integration/drone/push Build was killed Details
Reviewed-on: #1668
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-14 07:08:26 +00:00
renovate 562f84d962 chore(deps): update dependency netlify-cli to v9.13.0 (#1667)
continuous-integration/drone/push Build was killed Details
Reviewed-on: #1667
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-14 07:07:55 +00:00
renovate d29c7db4b6 chore(deps): update dependency esbuild to v0.14.26 (#1670)
continuous-integration/drone/push Build was killed Details
Reviewed-on: #1670
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-14 07:01:04 +00:00
renovate d0a2b248e0 chore(deps): update dependency rollup to v2.70.1 (#1671)
continuous-integration/drone/push Build was killed Details
Reviewed-on: #1671
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-14 07:00:31 +00:00
renovate f36c7783ee chore(deps): update dependency vitest to v0.6.1 (#1666)
continuous-integration/drone/push Build was killed Details
Reviewed-on: #1666
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-14 07:00:09 +00:00
drone 42fa8bda71 [skip ci] Updated translations via Crowdin 2022-03-14 00:21:14 +00:00
renovate 2786f7a7bc fix(deps): update dependency @vueuse/router to v8 (#1664)
continuous-integration/drone/push Build is failing Details
Reviewed-on: #1664
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-13 21:35:17 +00:00
renovate a534229bf5 fix(deps): update dependency vue-router to v4.0.14 (#1660)
continuous-integration/drone/push Build was killed Details
Reviewed-on: #1660
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-13 20:44:00 +00:00
renovate 89ed8913fd fix(deps): update dependency @vueuse/core to v8 (#1663)
continuous-integration/drone/push Build encountered an error Details
Reviewed-on: #1663
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-13 20:19:54 +00:00
renovate 5328c3d6b0 chore(deps): update dependency vue-tsc to v0.33.1 (#1665)
continuous-integration/drone/push Build encountered an error Details
Reviewed-on: #1665
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-13 20:19:31 +00:00
renovate 6a3290b052 chore(deps): update dependency eslint to v8.11.0 (#1661)
continuous-integration/drone/push Build is failing Details
Reviewed-on: #1661
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-13 17:41:01 +00:00
renovate 8ca64e9e1d fix(deps): update dependency highlight.js to v11.5.0 (#1662)
continuous-integration/drone/push Build is failing Details
Reviewed-on: #1662
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-13 17:40:43 +00:00
renovate 276fc7a875 fix(deps): update dependency flatpickr to v4.6.11 (#1659)
continuous-integration/drone/push Build is failing Details
Reviewed-on: #1659
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-13 17:40:08 +00:00
renovate 40e5945d5f chore(deps): update dependency happy-dom to v2.46.3 (#1658)
continuous-integration/drone/push Build is failing Details
Reviewed-on: #1658
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-13 15:15:58 +00:00
renovate 1fd1645c04 chore(deps): update dependency caniuse-lite to v1.0.30001315 (#1657)
continuous-integration/drone/push Build is failing Details
Reviewed-on: #1657
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-13 15:15:30 +00:00
renovate e96532d59f chore(deps): update dependency axios to v0.26.1 (#1656)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1656
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-09 18:30:50 +00:00
renovate c6b3a39a84 fix(deps): update sentry-javascript monorepo to v6.18.2 (#1655)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1655
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-08 20:37:21 +00:00
renovate 675d45cf9c chore(deps): update dependency caniuse-lite to v1.0.30001314 (#1654)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1654
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-08 08:25:54 +00:00
renovate 1fd5ab8d98 chore(deps): update dependency @faker-js/faker to v6.0.0-beta.0 (#1653)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1653
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-07 20:55:42 +00:00
renovate e19b338335 chore(deps): update typescript-eslint monorepo to v5.14.0 (#1652)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1652
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-07 20:55:20 +00:00
renovate 50c8077d7e chore(deps): update dependency happy-dom to v2.46.0 (#1650)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1650
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-07 15:24:02 +00:00
renovate 4136ed2f96 chore(deps): update dependency vitest to v0.6.0 (#1651)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1651
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-07 15:23:32 +00:00
renovate 4d362c0462 chore(deps): update dependency happy-dom to v2.45.1 (#1649)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1649
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-07 13:04:17 +00:00
renovate c82d2d4c2d chore(deps): update dependency postcss to v8.4.8 (#1647)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1647
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-07 08:33:31 +00:00
renovate 9622096115 chore(deps): update dependency netlify-cli to v9.12.3 (#1646)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1646
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-07 07:40:58 +00:00
renovate 9d6aed1a70 chore(deps): update dependency browserslist to v4.20.0 (#1645)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1645
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-07 07:40:31 +00:00
renovate 91a537c379 chore(deps): update dependency rollup to v2.70.0 (#1648)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1648
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-07 07:40:12 +00:00
renovate 59a5b7021c fix(deps): update dependency flatpickr to v4.6.10 (#1644)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1644
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-06 15:53:02 +00:00
kolaente 81993cc2e6
fix: aria-label for password field
continuous-integration/drone/push Build is passing Details
2022-03-06 13:31:57 +01:00
renovate 666d076801 chore(deps): update dependency rollup to v2.69.2 (#1643)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1643
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-06 11:50:35 +00:00
renovate 880976f960 fix(deps): update dependency @vueuse/core to v7.7.1 (#1641)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1641
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-05 09:20:48 +00:00
renovate db648a458a fix(deps): update dependency @vueuse/router to v7.7.1 (#1642)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1642
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-05 08:17:12 +00:00
drone 9b67f5627e [skip ci] Updated translations via Crowdin 2022-03-05 00:14:52 +00:00
renovate d1bf513e39 chore(deps): update dependency happy-dom to v2.45.0 (#1640)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1640
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-04 18:23:39 +00:00
renovate e2af71f577 chore(deps): update dependency rollup to v2.69.1 (#1638)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1638
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-04 14:25:08 +00:00
renovate 210e782c6a chore(deps): update workbox monorepo to v6.5.1 (#1635)
continuous-integration/drone/push Build is passing Details
Co-authored-by: kolaente <k@knt.li>
Reviewed-on: #1635
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-04 14:24:44 +00:00
renovate 08b087f590 chore(deps): update dependency esbuild to v0.14.25 (#1637)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1637
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-04 10:49:22 +00:00
renovate 280ada0e2f chore(deps): update dependency caniuse-lite to v1.0.30001313 (#1636)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1636
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-04 10:48:32 +00:00
drone 913ec95982 [skip ci] Updated translations via Crowdin 2022-03-04 00:10:15 +00:00
renovate 2ec7856cfe chore(deps): update dependency esbuild to v0.14.24 (#1634)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1634
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-03 08:22:46 +00:00
kolaente cf5460d298
fix: keyboard shortcut text indicating what works where
continuous-integration/drone/push Build is passing Details
2022-03-02 22:05:16 +01:00
kolaente f4b0e68322
feat: add a few new keyboard shortcuts
continuous-integration/drone/push Build is passing Details
2022-03-02 21:59:51 +01:00
renovate 8849e5bee1 chore(deps): update dependency happy-dom to v2.43.1 (#1632)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1632
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-02 16:48:26 +00:00
renovate 690c696d13 chore(deps): update dependency postcss-preset-env to v7.4.2 (#1633)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1633
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-02 16:47:48 +00:00
renovate 22d10a3f6b chore(deps): update dependency vue-tsc to v0.32.1 (#1629)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1629
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-02 14:20:34 +00:00
renovate 98f86b91a2 chore(deps): update dependency rollup to v2.69.0 (#1631)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1631
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-02 14:20:14 +00:00
renovate a9160d223d chore(deps): update dependency vite to v2.8.6 (#1630)
continuous-integration/drone/push Build is failing Details
Reviewed-on: #1630
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-02 12:51:25 +00:00
renovate 3d15d6e3d4 chore(deps): update dependency happy-dom to v2.43.0 (#1628)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1628
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-02 12:50:55 +00:00
renovate 28fdc98d1d chore(deps): update dependency vitest to v0.5.9 (#1627)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1627
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-02 12:50:09 +00:00
renovate e1a16ac5af chore(deps): update dependency cypress to v9.5.1 (#1625)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1625
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-02 12:49:30 +00:00
renovate b171cfbf67 chore(deps): update dependency typescript to v4.6.2 (#1626)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1626
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-03-02 10:37:56 +00:00
renovate ba0c0342fd chore(deps): update typescript-eslint monorepo to v5.13.0 (#1624)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1624
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-28 19:20:59 +00:00
renovate 1081e7ea50 chore(deps): update dependency @vitejs/plugin-vue to v2.2.4 (#1622)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1622
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-28 18:51:07 +00:00
renovate ae51c44a5e chore(deps): update dependency vite to v2.8.5 (#1623)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1623
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-28 18:50:54 +00:00
renovate 7be75c998c fix(deps): update dependency vue-router to v4.0.13 (#1620)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1620
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-28 17:10:27 +00:00
renovate 600fba6b71 fix(deps): update sentry-javascript monorepo to v6.18.1 (#1621)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1621
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-28 17:10:15 +00:00
renovate 4aad36333d chore(deps): update dependency netlify-cli to v9.8.3 (#1619)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1619
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-28 06:52:05 +00:00
renovate e901aef521 chore(deps): update dependency vitest to v0.5.8 (#1618)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1618
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-27 21:17:08 +00:00
kolaente 7f2189b455
fix: don't rotate kanban cards while dragging
continuous-integration/drone/push Build is passing Details
The way I implemented that had a few annoying side effects like wiggling around when clicking on the bucket
2022-02-27 19:43:05 +01:00
kolaente db47c1f10c
chore: move converting params to service
continuous-integration/drone/pr Build is passing Details
2022-02-27 17:21:07 +01:00
kolaente a8ee54d626
Merge branch 'main' into feature/date-math 2022-02-27 16:40:49 +01:00
kolaente b144802203
fix: "invalid date" error when trying to set a date and none was set before
continuous-integration/drone/push Build is passing Details
2022-02-27 16:39:21 +01:00
kolaente a23b4a96ee
fix: kanban board layout on mobile
continuous-integration/drone/push Build is passing Details
2022-02-27 16:36:20 +01:00
renovate fc0e3e0d51 fix(deps): update dependency @vueuse/core to v7.7.0 (#1613)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1613
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-26 17:14:08 +00:00
renovate fd857d3db3 fix(deps): update dependency @vueuse/router to v7.7.0 (#1614)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1614
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-26 16:26:11 +00:00
kolaente c06cc6ad7a
fix: pop sound not saved and played when marking tasks done
continuous-integration/drone/push Build is passing Details
2022-02-26 14:48:46 +01:00
kolaente 553fd54f78
fix(kanban): background content scrolling when opening a task
continuous-integration/drone/push Build is passing Details
2022-02-26 14:39:25 +01:00
kolaente 74ab197dc6
fix: don't always show a scrollbar
continuous-integration/drone/push Build is passing Details
2022-02-26 14:36:43 +01:00
kolaente 5b509da215
fix(kanban): make sure the buckets don't appear glued to the bottom 2022-02-26 14:28:55 +01:00
kolaente f54f533700
fix(kanban): transition animation for bucket footer when adding a new task
continuous-integration/drone/push Build is passing Details
2022-02-26 14:20:53 +01:00
kolaente 6d0cbc51f6
fix: missing app padding when opening the task detail modal
continuous-integration/drone/push Build is passing Details
2022-02-26 14:13:37 +01:00
kolaente 17ba56f12d
feat: rotate task cards slightly while moving them between buckets
continuous-integration/drone/push Build is passing Details
2022-02-26 14:03:30 +01:00
kolaente d5f0158b04
Merge branch 'main' into feature/date-math
continuous-integration/drone/pr Build is passing Details
# Conflicts:
#	src/views/tasks/ShowTasks.vue
2022-02-26 13:30:07 +01:00
kolaente 051dd98ff7
fix: undo task done from list view
continuous-integration/drone/push Build is passing Details
2022-02-26 13:18:44 +01:00
kolaente 7b62a0895d
fix: update page title when changing the task title
continuous-integration/drone/push Build is passing Details
2022-02-26 13:14:08 +01:00
kolaente 45c05296a6
fix: hide "title required" error after entering text
continuous-integration/drone/push Build is passing Details
2022-02-26 13:05:39 +01:00
kolaente 1256c37b69
fix: removing a label from a task
continuous-integration/drone/push Build is passing Details
2022-02-26 12:57:59 +01:00
kolaente 9a55482681
fix: don't fire close event multiple times
continuous-integration/drone/push Build is passing Details
2022-02-26 12:55:38 +01:00
kolaente b83cec2f0e
fix: don't try to validate nonexisting fields
continuous-integration/drone/push Build is passing Details
2022-02-26 12:35:09 +01:00
kolaente 731506fab7
fix: don't try to filter notifications if there are none
continuous-integration/drone/push Build is passing Details
2022-02-26 12:33:49 +01:00
kolaente 8cdcfaf071
fix: don't try to sort tasks when none were returned
continuous-integration/drone/push Build is passing Details
2022-02-26 12:30:56 +01:00
renovate 42303e37df chore(deps): update dependency eslint to v8.10.0 (#1611)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1611
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-26 11:11:10 +00:00
renovate 683a68f3ef chore(deps): update dependency vitest to v0.5.7 (#1612)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1612
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-26 11:10:50 +00:00
renovate f2a0a444b5 fix(deps): update dependency ufo to v0.7.11 (#1610)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1610
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-25 22:16:35 +00:00
renovate 4dd914af13 chore(deps): update dependency rollup-plugin-visualizer to v5.6.0 (#1609)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1609
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-25 11:43:34 +00:00
renovate c7a35fa251 chore(deps): update dependency vue-tsc to v0.32.0 (#1608)
continuous-integration/drone/push Build is running Details
Reviewed-on: #1608
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-25 08:07:02 +00:00
renovate e5e546bc0f chore(deps): update dependency postcss to v8.4.7 (#1607)
continuous-integration/drone/push Build is running Details
Reviewed-on: #1607
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-25 08:06:11 +00:00
renovate bdad9dadc8 chore(deps): update dependency sass to v1.49.9 (#1606)
continuous-integration/drone/push Build is running Details
Reviewed-on: #1606
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-24 21:47:06 +00:00
renovate 46cc8e0cec fix(deps): update sentry-javascript monorepo to v6.18.0 (#1605)
continuous-integration/drone/push Build is failing Details
Reviewed-on: #1605
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-24 15:18:04 +00:00
renovate d8a60779ef chore(deps): update dependency vitest to v0.5.5 (#1604)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1604
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-24 11:02:02 +00:00
renovate 52948864ad chore(deps): update workbox monorepo to v6.5.0 (#1603)
continuous-integration/drone/push Build is passing Details
Co-authored-by: kolaente <k@knt.li>
Reviewed-on: #1603
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-24 08:15:11 +00:00
renovate eb505bbc25 chore(deps): update dependency vitest to v0.5.4 (#1602)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1602
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-23 15:19:00 +00:00
Dominik Pschenitschni 9f5e68a125 feat: change preview api url (#1584)
continuous-integration/drone/push Build is passing Details
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: #1584
Co-authored-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-committed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
2022-02-23 12:05:06 +00:00
drone 9bb73d9f64 [skip ci] Updated translations via Crowdin 2022-02-23 00:10:44 +00:00
renovate 1a50eb100c chore(deps): update dependency happy-dom to v2.41.0 (#1600)
continuous-integration/drone/push Build is failing Details
Reviewed-on: #1600
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-22 20:52:11 +00:00
renovate 7e787fd99d chore(deps): update dependency vitest to v0.5.3 (#1599)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1599
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-22 13:56:22 +00:00
renovate 3aec819e46 chore(deps): update dependency eslint-plugin-vue to v8.5.0 (#1598)
continuous-integration/drone/push Build is failing Details
Reviewed-on: #1598
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-22 09:28:24 +00:00
renovate 64d9de2aa6 chore(deps): update dependency rollup to v2.68.0 (#1597)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1597
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-22 07:14:57 +00:00
renovate 29675670c4 chore(deps): update dependency vitest to v0.5.1 (#1596)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1596
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-22 07:14:29 +00:00
drone b512f4a6b8 [skip ci] Updated translations via Crowdin 2022-02-22 00:10:46 +00:00
renovate 6d6220627c chore(deps): update typescript-eslint monorepo to v5.12.1 (#1595)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1595
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-21 19:16:25 +00:00
renovate e855728a3e fix(deps): update dependency codemirror to v5.65.2 (#1593)
continuous-integration/drone/push Build is failing Details
Reviewed-on: #1593
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-21 09:19:15 +00:00
renovate 15a966cf0d chore(deps): update dependency netlify-cli to v9 (#1590)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1590
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-21 07:42:47 +00:00
renovate 54d8ea443d chore(deps): update dependency vitest to v0.5.0 (#1592)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1592
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-21 07:17:29 +00:00
renovate 213ddc0acb chore(deps): update dependency vitest to v0.4.3 (#1591)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1591
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-21 06:39:39 +00:00
renovate f6bb2d1aee chore(deps): update dependency netlify-cli to v8.19.3 (#1589)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1589
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-21 06:38:35 +00:00
drone 76566d3941 [skip ci] Updated translations via Crowdin 2022-02-21 00:13:32 +00:00
konrad bdb53ec8ee fix: api config domain name contains the current domain instead of the provided one (#1581)
continuous-integration/drone/push Build is passing Details
Co-authored-by: kolaente <k@knt.li>
Reviewed-on: #1581
Reviewed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
2022-02-20 22:07:59 +00:00
kolaente da162d5652
fix: modal not scrolling content when open
continuous-integration/drone/pr Build is passing Details
2022-02-20 22:32:41 +01:00
kolaente c7943ef823
fix: popup not really hidden when hidden
continuous-integration/drone/pr Build is failing Details
2022-02-20 22:02:59 +01:00
kolaente 622f08fb1b
fix: lint
continuous-integration/drone/pr Build was killed Details
2022-02-20 21:34:45 +01:00
kolaente 4ce9ac9c66
chore: remove showAll prop and make it a computed instead
continuous-integration/drone/pr Build was killed Details
2022-02-20 21:32:02 +01:00
kolaente 95d8cdffe4
chore: return the title directly
continuous-integration/drone/pr Build is failing Details
2022-02-20 21:22:31 +01:00
kolaente 564f669ed4
chore: return key directly
continuous-integration/drone/pr Build was killed Details
2022-02-20 21:21:06 +01:00
kolaente 74766ce1d0
chore: hack the planet
continuous-integration/drone/pr Build was killed Details
2022-02-20 21:17:24 +01:00
kolaente 18f5f8da7d
chore: remove abstractions 2022-02-20 21:15:56 +01:00
kolaente 4195953696
chore: rename i18n key for datemath help
continuous-integration/drone/pr Build was killed Details
2022-02-20 21:13:42 +01:00
kolaente a6480cdb75
chore: remove rel for help docs
continuous-integration/drone/pr Build was killed Details
2022-02-20 21:07:49 +01:00
kolaente 0b6a74d11e
Merge branch 'main' into feature/date-math 2022-02-20 20:25:06 +01:00
renovate f9309c30b0 chore(deps): update dependency @faker-js/faker to v6.0.0-alpha.7 (#1587)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1587
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-20 19:15:58 +00:00
Dominik Pschenitschni 60f58af41a
chore: align wording in task detail view
continuous-integration/drone/pr Build is passing Details
continuous-integration/drone/push Build is passing Details
Changes only in task detail view. Probably this should be done everywhere:

- some buttons were using the uppercase words consistently, some were not
- some were using articles, some were not  => I removed them everywhere to shorten the label length
- some buttons were refering to the task, some were not. Since we are already in the context of the task (we are not the task detail page) I removed the reference everywhere.
2022-02-20 12:03:45 +01:00
drone 15d681122a [skip ci] Updated translations via Crowdin 2022-02-20 00:12:43 +00:00
renovate 90d184f7ad chore(deps): update dependency vitest to v0.4.2 (#1580)
continuous-integration/drone/push Build is failing Details
Reviewed-on: #1580
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-19 12:19:00 +00:00
renovate e14cfd985c chore(deps): update dependency browserslist to v4.19.3 (#1579)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1579
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-19 10:12:07 +00:00
drone 894792b207 [skip ci] Updated translations via Crowdin 2022-02-19 00:12:08 +00:00
renovate 6d66ee788c chore(deps): update dependency esbuild to v0.14.23
continuous-integration/drone/pr Build is passing Details
continuous-integration/drone/push Build is passing Details
2022-02-18 21:03:19 +00:00
Dominik Pschenitschni c419062e49 fix: direct store manipulation in tasks (#1534)
continuous-integration/drone/push Build is passing Details
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: #1534
Reviewed-by: konrad <k@knt.li>
Co-authored-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-committed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
2022-02-18 19:48:49 +00:00
Dominik Pschenitschni 8df73c973b feat: use AuthenticatedHTTPFactory for refreshToken (#1546)
continuous-integration/drone/push Build is passing Details
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: #1546
Reviewed-by: konrad <k@knt.li>
Co-authored-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-committed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
2022-02-18 19:14:38 +00:00
renovate 026ee3e8da chore(deps): update dependency @vitejs/plugin-vue to v2.2.2 (#1577)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1577
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-18 17:10:56 +00:00
Dominik Pschenitschni 8ea9d7541f feat: rename percent done to progress (#1542)
continuous-integration/drone/push Build is passing Details
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: #1542
Reviewed-by: konrad <k@knt.li>
Co-authored-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-committed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
2022-02-18 16:56:15 +00:00
renovate c0670e6bfc chore(deps): update dependency vitest to v0.4.1 (#1576)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1576
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-18 15:22:19 +00:00
renovate 3cda4c8478 chore(deps): update dependency vite to v2.8.4 (#1575)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1575
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-18 15:21:52 +00:00
renovate e895c8d5d9 chore(deps): update dependency rollup to v2.67.3
continuous-integration/drone/pr Build is passing Details
continuous-integration/drone/push Build is passing Details
2022-02-18 14:14:36 +00:00
renovate bde0b252bc chore(deps): update dependency sass to v1.49.8 (#1574)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1574
Reviewed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-18 14:14:17 +00:00
renovate 1b46bc9c47 chore(deps): update dependency browserslist to v4.19.2
continuous-integration/drone/pr Build is passing Details
continuous-integration/drone/push Build is passing Details
2022-02-18 13:02:39 +00:00
Dominik Pschenitschni 98cb14a86c
feat: change port to 4173
continuous-integration/drone/pr Build is passing Details
continuous-integration/drone/push Build is passing Details
See: https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md#default-preview-port
2022-02-18 13:00:20 +01:00
renovate 95390390a7
chore(deps): update dependency vite to v2.8.3
For `<script setup>`
Wee need to change "preserveValueImports": true
See: <https://devblogs.microsoft.com/typescript/announcing-typescript-4-5-beta/#preserve-value-imports>
2022-02-18 13:00:16 +01:00
renovate 11d450d651 chore(deps): update dependency vitest to v0.4.1 (#1570)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1570
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-18 09:36:14 +00:00
renovate 0f3ba86efd chore(deps): update dependency vitest to v0.4.0 (#1568)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1568
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-18 07:05:28 +00:00
renovate 91e92ef772 chore(deps): update dependency rollup to v2.67.3 (#1569)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1569
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-18 07:04:54 +00:00
renovate 9a46540ebc chore(deps): update dependency sass to v1.49.8
continuous-integration/drone/pr Build is passing Details
continuous-integration/drone/push Build is passing Details
2022-02-17 22:02:39 +00:00
renovate 64027d1ee0 chore(deps): update dependency happy-dom to v2.39.1
continuous-integration/drone/pr Build is passing Details
continuous-integration/drone/push Build is passing Details
2022-02-17 18:02:48 +00:00
renovate fff113d418 chore(deps): update typescript-eslint monorepo to v5.12.0
continuous-integration/drone/push Build is passing Details
2022-02-17 16:34:16 +00:00
renovate fc8d2d1a57 chore(deps): update dependency happy-dom to v2.36.0
continuous-integration/drone/pr Build is passing Details
continuous-integration/drone/push Build is passing Details
2022-02-17 16:02:50 +00:00
renovate 6a959b2e53 chore(deps): update dependency postcss-preset-env to v7.4.1
continuous-integration/drone/push Build is passing Details
2022-02-17 15:35:29 +00:00
renovate 56f48cab31 chore(deps): update dependency cypress to v9.5.0
continuous-integration/drone/push Build is passing Details
2022-02-17 15:35:01 +00:00
renovate cd3244e0f9 chore(deps): update dependency happy-dom to v2.34.0
continuous-integration/drone/push Build is passing Details
2022-02-17 15:34:31 +00:00
renovate b3f207eaff chore(deps): update dependency axios to v0.26.0
continuous-integration/drone/push Build is passing Details
2022-02-17 15:34:09 +00:00
renovate 34990946f6 fix(deps): update dependency vue-advanced-cropper to v2.8.1
continuous-integration/drone/pr Build is passing Details
continuous-integration/drone/push Build is passing Details
2022-02-17 15:02:59 +00:00
renovate a557a0085d fix(deps): update sentry-javascript monorepo to v6.17.9
continuous-integration/drone/push Build is passing Details
2022-02-17 14:53:46 +00:00
renovate 762f21188d fix(deps): update dependency vue to v3.2.31
continuous-integration/drone/pr Build is passing Details
continuous-integration/drone/push Build is passing Details
2022-02-17 13:01:38 +00:00
renovate a7a3dd7872 fix(deps): update dependency @vueuse/core to v7.6.2
continuous-integration/drone/push Build is passing Details
2022-02-17 12:51:54 +00:00
renovate e9498b200d chore(deps): update dependency caniuse-lite to v1.0.30001312
continuous-integration/drone/push Build is passing Details
2022-02-17 12:50:28 +00:00
renovate cd15a756d7 fix(deps): update dependency dompurify to v2.3.6
continuous-integration/drone/push Build is passing Details
2022-02-17 12:50:03 +00:00
renovate 2c6ba1fa89 chore(deps): update dependency esbuild to v0.14.22 (#1549)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1549
Reviewed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-17 11:16:14 +00:00
renovate 51a93b5fd2 chore(deps): update dependency vue-tsc to v0.31.4 (#1552)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1552
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-17 11:15:54 +00:00
renovate d4061d1b10 fix(deps): update dependency @vue/compat to v3.2.31 (#1553)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1553
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-17 11:15:36 +00:00
renovate 7f9ba0c727 fix(deps): update dependency @vueuse/router to v7.6.2 (#1555)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1555
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-17 11:15:11 +00:00
renovate 7020c99a7a chore(deps): update dependency express to v4.17.3 (#1550)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #1550
Reviewed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-02-17 11:14:46 +00:00
renovate befa2d4004 chore(deps): update dependency vitest to v0.3.6
continuous-integration/drone/pr Build is passing Details
continuous-integration/drone/push Build is passing Details
2022-02-17 09:03:34 +00:00
saibotk 28af46bcd3 fix: Replace slugify in deploy-preview-netlify with simple regex solution (#1543)
continuous-integration/drone/push Build is passing Details
Co-authored-by: saibotk <git@saibotk.de>
Reviewed-on: #1543
Reviewed-by: konrad <k@knt.li>
Co-authored-by: saibotk <kolaente-dev@saibotk.de>
Co-committed-by: saibotk <kolaente-dev@saibotk.de>
2022-02-14 18:09:20 +00:00
Dominik Pschenitschni 17dc276971 fix: property spelling
continuous-integration/drone/push Build is failing Details
2022-02-14 17:00:10 +00:00
Dominik Pschenitschni ede8bc5015 [skip ci] Updated translations via Crowdin 2022-02-14 00:12:21 +00:00
Dominik Pschenitschni 924359f739 fix(button): min-height
continuous-integration/drone/push Build is passing Details
2022-02-13 22:12:10 +00:00
Dominik Pschenitschni b84fe4c88b feat: convert api-config to script setup and ts (#1535)
continuous-integration/drone/push Build is passing Details
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: #1535
Reviewed-by: konrad <k@knt.li>
Co-authored-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-committed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
2022-02-13 22:06:26 +00:00
Dominik Pschenitschni d57c9af332 fix: use BaseButton in MenuButton and fix computed (#1532)
continuous-integration/drone/push Build is passing Details
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: #1532
Reviewed-by: konrad <k@knt.li>
Co-authored-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-committed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
2022-02-13 22:01:36 +00:00
Dominik Pschenitschni eac07d3169 feat: make profile picture clickable (#1531)
continuous-integration/drone/push Build is passing Details
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: #1531
Reviewed-by: konrad <k@knt.li>
Co-authored-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-committed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
2022-02-13 21:57:33 +00:00
Dominik Pschenitschni 72d6701404 feat: enable strictNullChecks ts setting (#1538)
continuous-integration/drone/push Build is passing Details
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: #1538
Reviewed-by: konrad <k@knt.li>
Co-authored-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-committed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
2022-02-13 21:55:46 +00:00
Dominik Pschenitschni badbae0e9a
fix: mark query parameter as string
continuous-integration/drone/pr Build is failing Details
2022-02-09 17:52:27 +01:00
kolaente 4ac7d6b9df
fix: don't reset flatpickr date
continuous-integration/drone/pr Build is failing Details
2022-02-06 23:10:35 +01:00
kolaente 7cd89b7bf1
chore: rename el
continuous-integration/drone/pr Build is failing Details
2022-02-06 23:08:34 +01:00
kolaente a22792a4b4
fix: styling
continuous-integration/drone/pr Build is failing Details
2022-02-06 23:05:40 +01:00
kolaente b1ec5b58ee
chore: use BaseButton 2022-02-06 23:05:34 +01:00
kolaente 77bf347155
chore: move styling to the correct component 2022-02-06 23:03:58 +01:00
kolaente 204e94aa74
chore: programmatically convert filter values to snake_case
continuous-integration/drone/pr Build is failing Details
2022-02-06 20:48:37 +01:00
kolaente aac777e286
fix: lint
continuous-integration/drone/pr Build was killed Details
2022-02-06 20:32:21 +01:00
kolaente 84f177c80e
feat: reduce dependency on router and move everything to route props instead
continuous-integration/drone/pr Build is failing Details
2022-02-06 20:11:13 +01:00
kolaente 1e4ef96150
chore: cleanup unnecessary css
continuous-integration/drone/pr Build is failing Details
2022-02-06 19:41:20 +01:00
kolaente 4268eee1f2
chore: simplify nesting 2022-02-06 19:40:11 +01:00
kolaente 436c0416d7
chore: use a primary button to select range in upcoming
continuous-integration/drone/pr Build is failing Details
2022-02-06 19:39:05 +01:00
kolaente a78ca6fad3
chore: fix nesting and positioning 2022-02-06 19:38:36 +01:00
kolaente 356b291a57
chore: change return
continuous-integration/drone/pr Build is failing Details
2022-02-06 19:35:30 +01:00
kolaente 60be8b428e
chore: rename date ranges export
continuous-integration/drone/pr Build is failing Details
2022-02-06 19:33:52 +01:00
kolaente f435ca99f4
chore: change import order and useStore
continuous-integration/drone/pr Build is failing Details
2022-02-06 19:31:48 +01:00
kolaente eefe6bd413
chore: move date math explanation to separate component
continuous-integration/drone/pr Build is failing Details
2022-02-06 19:29:15 +01:00
kolaente 204136266f
chore: watch values instead of listening to changes
continuous-integration/drone/pr Build is failing Details
2022-02-06 18:56:45 +01:00
kolaente 18f7adf420
chore: use more BaseButtons
continuous-integration/drone/pr Build is failing Details
2022-02-06 18:51:47 +01:00
kolaente c5d598cac4
chore: refactor trigger to slot
continuous-integration/drone/pr Build is failing Details
2022-02-06 18:46:53 +01:00
kolaente eeee1c842a
fix: correctly send filter values
continuous-integration/drone/pr Build is failing Details
2022-02-06 16:58:23 +01:00
kolaente 6d6f2b4e33
chore: cleanup 2022-02-06 16:48:28 +01:00
kolaente cbbcb7ef23
fix: setTitle import
continuous-integration/drone/pr Build is failing Details
2022-02-06 16:36:12 +01:00
kolaente bcd34efe91
chore: convert ShowTasks component to script setup and ts
continuous-integration/drone/pr Build is failing Details
2022-02-06 16:04:49 +01:00
kolaente 6c0d091e36
Merge branch 'fix/upcoming' into feature/date-math 2022-02-06 15:29:38 +01:00
kolaente 1abd36ef6e
Merge branch 'main' into fix/upcoming
continuous-integration/drone/pr Build is passing Details
2022-02-06 12:45:17 +01:00
kolaente 9e7c258347
fix: sort tasks correctly by due date
continuous-integration/drone/pr Build is failing Details
2022-02-06 12:43:42 +01:00
kolaente 7135288800
fix: lint 2022-02-06 12:43:42 +01:00
kolaente 7aa2cfc8d4
feat: add date range filter to task filters 2022-02-06 12:43:40 +01:00
kolaente 3a12be505d
feat: add prop to maybe show selected date 2022-02-06 12:42:50 +01:00
kolaente a74fc47335
fix: llama position 2022-02-06 12:42:13 +01:00
kolaente 0ae8a0e6ef
feat: add more pre-defined ranges 2022-02-06 12:42:13 +01:00
kolaente e7fa1d3383
feat: add explanation of how date math works 2022-02-06 12:42:12 +01:00
kolaente 6c55411f71
fix: now correctly showing the title of predefined ranges 2022-02-06 12:41:41 +01:00
kolaente 4d23fae9ad
fix: reset the flatpickr range when setting a date either manually or through a quick setting 2022-02-06 12:41:40 +01:00
kolaente 16f48bcc2d
fix: custom date range with nothing specified 2022-02-06 12:41:40 +01:00
kolaente 1e46849c78
feat: make sure date ranges work with date picker and vice-versa 2022-02-06 12:41:39 +01:00
kolaente 8d5bfbe828
feat: add two inputs to toggle flatpickr 2022-02-06 12:41:20 +01:00
kolaente dabe87af4b
feat: make sure showTasks can handle dynamic dates 2022-02-06 12:41:19 +01:00
kolaente 6667df5f1f
feat: move everything to fancy date math ranges 2022-02-06 12:40:23 +01:00
kolaente 32bdf16892
feat: use object and loop to set date options 2022-02-06 12:40:23 +01:00
kolaente 210a78be86
fix: don't try to load a langauge if there's none provided
continuous-integration/drone/pr Build is passing Details
2022-02-05 21:41:22 +01:00
kolaente ecf679d8e1
chore: completely move logic of ShowTasksInRange component to ShowTasks and remove it
continuous-integration/drone/pr Build is failing Details
2022-02-05 21:14:40 +01:00
kolaente 43e83350bd
feat: move logic of ShowTasksInRange component to ShowTasks
continuous-integration/drone/pr Build is failing Details
2022-02-05 21:12:35 +01:00
kolaente c41397f5db
feat: add slot for trigger button in <datepicker-with-range> component
continuous-integration/drone/pr Build is passing Details
2022-02-05 20:29:57 +01:00
kolaente ccd8602bfd
chore: remove unused style
continuous-integration/drone/pr Build is passing Details
2022-02-05 20:18:42 +01:00
kolaente 4e8a03066e
chore: use v-else 2022-02-05 20:17:34 +01:00
kolaente 8d13b979ec
chore: remove unrequired type 2022-02-05 20:03:16 +01:00
kolaente d272eb2a7a
Merge branch 'main' into fix/upcoming
# Conflicts:
#	src/views/tasks/ShowTasks.vue
2022-02-05 20:02:30 +01:00
kolaente 01323a1b45
Merge branch 'main' into fix/upcoming
continuous-integration/drone/pr Build is passing Details
# Conflicts:
#	src/views/tasks/ShowTasks.vue
2022-01-09 11:48:37 +01:00
kolaente 7dddfea79e
fix: test
continuous-integration/drone/pr Build is failing Details
2021-12-30 16:14:51 +01:00
kolaente 1648bcdb70
chore: make select date button actually a button
continuous-integration/drone/pr Build is failing Details
2021-12-30 16:12:44 +01:00
kolaente 0710cea9e5
fix: lint
continuous-integration/drone/pr Build is failing Details
2021-12-29 21:33:55 +01:00
kolaente 294e89b6f7
fix: z-index
continuous-integration/drone/pr Build is failing Details
2021-12-29 21:12:43 +01:00
kolaente 75cbc73b33
fix: loading spinner
continuous-integration/drone/pr Build is failing Details
2021-12-29 20:59:30 +01:00
kolaente 950fdce111
chore: move datepicker popup to real popup component 2021-12-29 20:54:01 +01:00
kolaente 932f1774ec
feat: move date filter to popup and improve styling 2021-12-29 20:36:53 +01:00
kolaente d825960836
chore: make showNulls and showOverdue computed 2021-12-29 18:12:43 +01:00
kolaente f691e96e22
fix: checkboxes 2021-12-29 18:06:12 +01:00
kolaente 0d6ef8f18a
chore: move task sorting to computed 2021-12-29 17:24:56 +01:00
kolaente d6dd1fc0e3
fix: date range 2021-12-29 17:22:14 +01:00
kolaente 729aa7d4cc
fix: date format 2021-12-29 17:08:33 +01:00
kolaente c24b8af00d
fix: pay attention to week start setting 2021-12-29 16:51:21 +01:00
kolaente 8f8d25ece1
feat: add more date ranges and make sure they actually make sense 2021-12-29 16:48:34 +01:00
kolaente e93be0d04c
chore: cleanup old stuff 2021-12-29 16:06:05 +01:00
kolaente a5b23a7048
feat: disable time 2021-12-29 16:03:29 +01:00
kolaente 858e7d60a6
docs: add fixmes 2021-12-29 16:03:05 +01:00
kolaente 12317c56b3
feat: make the custom button actually do stuff 2021-12-29 16:01:59 +01:00
kolaente 378f782d44
fix: disable broken stuff 2021-12-29 16:01:23 +01:00
kolaente b274a796d4
chore: use ts 2021-12-29 16:00:06 +01:00
kolaente 3d1c1e41c7
feat: make active class work 2021-12-29 15:56:50 +01:00
kolaente 8115563d67
feat: add new component for a datepicker with range 2021-12-29 15:44:13 +01:00
kolaente 7408c37dec
chore: cleanup and reorganize the date selection 2021-12-28 23:50:04 +01:00
86 changed files with 5673 additions and 3412 deletions

View File

@ -120,10 +120,9 @@ steps:
from_secret: cypress_project_key
commands:
- sed -i 's/localhost/api/g' dist/index.html
- yarn serve:dist & npx wait-on http://localhost:5000
- yarn serve:dist & npx wait-on http://localhost:4173
- yarn test:frontend --browser chrome --record
depends_on:
- dependencies
- build-prod
- name: deploy-preview
@ -137,6 +136,9 @@ steps:
GITEA_TOKEN:
from_secret: gitea_token
commands:
- cp -r dist dist-preview
# Override the default api url used for preview
- sed -i 's|localhost:3456|try.vikunja.io|g' dist-preview/index.html
- shasum -a 384 -c ./scripts/deploy-preview-netlify.js.sha384
- node ./scripts/deploy-preview-netlify.js
depends_on:

View File

@ -1,5 +1,5 @@
{
"baseUrl": "http://localhost:5000",
"baseUrl": "http://localhost:4173",
"env": {
"API_URL": "http://localhost:3456/api/v1",
"TEST_SECRET": "averyLongSecretToSe33dtheDB"

View File

@ -176,7 +176,7 @@ describe('List View Kanban', () => {
.click()
cy.get('.task-view .action-buttons .button', { timeout: 3000 })
.contains('Move task')
.contains('Move')
.click()
cy.get('.task-view .content.details .field .multiselect.control .input-wrapper input')
.type(`${lists[1].title}{enter}`)

View File

@ -72,7 +72,7 @@ describe('Lists', () => {
.should('contain', newListName)
.should('not.contain', lists[0].title)
cy.visit('/')
cy.get('.card-content .tasks')
cy.get('.card-content')
.should('contain', newListName)
.should('not.contain', lists[0].title)
})

View File

@ -210,7 +210,7 @@ describe('Task', () => {
cy.visit(`/tasks/${tasks[0].id}`)
cy.get('.task-view .action-buttons .button')
.contains('Move task')
.contains('Move')
.click()
cy.get('.task-view .content.details .field .multiselect.control .input-wrapper input')
.type(`${lists[1].title}{enter}`)
@ -237,7 +237,7 @@ describe('Task', () => {
cy.get('.task-view .action-buttons .button')
.should('be.visible')
.contains('Delete task')
.contains('Delete')
.click()
cy.get('.modal-mask .modal-container .modal-content .header')
.should('contain', 'Delete this task')
@ -317,7 +317,7 @@ describe('Task', () => {
cy.visit(`/tasks/${tasks[0].id}`)
cy.get('.task-view .action-buttons .button')
.contains('Add labels')
.contains('Add Labels')
.should('be.visible')
.click()
cy.get('.task-view .details.labels-list .multiselect input')
@ -344,7 +344,7 @@ describe('Task', () => {
cy.visit(`/tasks/${tasks[0].id}`)
cy.get('.task-view .action-buttons .button')
.contains('Add labels')
.contains('Add Labels')
.click()
cy.get('.task-view .details.labels-list .multiselect input')
.type(labels[0].title)

View File

@ -6,7 +6,7 @@ describe('Log out', () => {
cy.get('.navbar .user .username')
.click()
cy.get('.navbar .user .dropdown-menu a.dropdown-item')
cy.get('.navbar .user .dropdown-menu .dropdown-item')
.contains('Logout')
.click()

View File

@ -1,6 +1,6 @@
[build]
command = "yarn build"
publish = "dist"
publish = "dist-preview"
[[redirects]]
from = "/*"

View File

@ -5,7 +5,7 @@
"scripts": {
"serve": "vite",
"serve:dist-dev": "node scripts/serve-dist.js",
"serve:dist": "vite preview",
"serve:dist": "vite preview --port 4173",
"build": "vite build && workbox copyLibraries dist/",
"build:modern-only": "BUILD_MODERN_ONLY=true vite build && workbox copyLibraries dist/",
"build:dev": "vite build -m development --outDir dist-dev/",
@ -20,78 +20,78 @@
"dependencies": {
"@github/hotkey": "2.0.0",
"@kyvg/vue3-notification": "2.3.4",
"@sentry/tracing": "6.17.7",
"@sentry/vue": "6.17.7",
"@sentry/tracing": "6.19.3",
"@sentry/vue": "6.19.3",
"@types/is-touch-device": "1.0.0",
"@vue/compat": "3.2.30",
"@vueuse/core": "7.6.0",
"@vueuse/router": "7.6.1",
"@vue/compat": "3.2.31",
"@vueuse/core": "8.2.3",
"@vueuse/router": "8.2.3",
"blurhash": "^1.1.4",
"bulma-css-variables": "0.9.33",
"camel-case": "4.1.2",
"codemirror": "5.65.1",
"codemirror": "5.65.2",
"copy-to-clipboard": "3.3.1",
"date-fns": "2.28.0",
"dompurify": "2.3.5",
"dompurify": "2.3.6",
"easymde": "2.16.1",
"flatpickr": "4.6.9",
"flatpickr": "4.6.11",
"flexsearch": "0.7.21",
"highlight.js": "11.4.0",
"highlight.js": "11.5.0",
"is-touch-device": "1.0.1",
"lodash.clonedeep": "4.5.0",
"lodash.debounce": "4.0.8",
"marked": "4.0.12",
"register-service-worker": "1.7.2",
"snake-case": "3.0.4",
"ufo": "0.7.10",
"ufo": "0.8.3",
"v-tooltip": "4.0.0-beta.17",
"vue": "3.2.30",
"vue-advanced-cropper": "2.8.0",
"vue": "3.2.31",
"vue-advanced-cropper": "2.8.1",
"vue-drag-resize": "2.0.3",
"vue-flatpickr-component": "9.0.5",
"vue-i18n": "9.2.0-beta.30",
"vue-router": "4.0.12",
"vue-router": "4.0.14",
"vuedraggable": "4.1.0",
"vuex": "4.0.2",
"workbox-precaching": "6.4.2"
"workbox-precaching": "6.5.2"
},
"devDependencies": {
"@4tw/cypress-drag-drop": "2.1.0",
"@faker-js/faker": "6.0.0-alpha.6",
"@fortawesome/fontawesome-svg-core": "1.3.0",
"@fortawesome/free-regular-svg-icons": "5.15.4",
"@fortawesome/free-solid-svg-icons": "5.15.4",
"@faker-js/faker": "6.1.1",
"@fortawesome/fontawesome-svg-core": "6.1.1",
"@fortawesome/free-regular-svg-icons": "6.1.1",
"@fortawesome/free-solid-svg-icons": "6.1.1",
"@fortawesome/vue-fontawesome": "3.0.0-5",
"@types/flexsearch": "0.7.2",
"@typescript-eslint/eslint-plugin": "5.11.0",
"@typescript-eslint/parser": "5.11.0",
"@vitejs/plugin-legacy": "1.7.1",
"@vitejs/plugin-vue": "2.2.0",
"@types/flexsearch": "0.7.3",
"@typescript-eslint/eslint-plugin": "5.17.0",
"@typescript-eslint/parser": "5.17.0",
"@vitejs/plugin-legacy": "1.8.0",
"@vitejs/plugin-vue": "2.3.1",
"@vue/eslint-config-typescript": "10.0.0",
"autoprefixer": "10.4.2",
"axios": "0.25.0",
"browserslist": "4.19.1",
"caniuse-lite": "1.0.30001311",
"cypress": "9.4.1",
"esbuild": "0.14.21",
"eslint": "8.9.0",
"eslint-plugin-vue": "8.4.1",
"express": "4.17.2",
"happy-dom": "2.31.1",
"netlify-cli": "8.16.1",
"postcss": "8.4.6",
"postcss-preset-env": "7.3.1",
"rollup": "2.67.2",
"rollup-plugin-visualizer": "5.5.4",
"sass": "1.49.7",
"slugify": "1.6.5",
"typescript": "4.5.5",
"vite": "2.7.13",
"autoprefixer": "10.4.4",
"axios": "0.26.1",
"browserslist": "4.20.2",
"caniuse-lite": "1.0.30001324",
"cypress": "9.5.3",
"esbuild": "0.14.30",
"eslint": "8.12.0",
"eslint-plugin-vue": "8.5.0",
"express": "4.17.3",
"happy-dom": "2.55.0",
"netlify-cli": "9.13.5",
"postcss": "8.4.12",
"postcss-preset-env": "7.4.3",
"rollup": "2.70.1",
"rollup-plugin-visualizer": "5.6.0",
"sass": "1.49.11",
"typescript": "4.6.3",
"vite": "2.9.1",
"vite-plugin-pwa": "0.11.13",
"vite-svg-loader": "3.1.2",
"vitest": "0.3.2",
"vue-tsc": "0.31.2",
"vite-svg-loader": "3.2.0",
"vitest": "0.8.2",
"vue-tsc": "0.33.9",
"wait-on": "6.0.1",
"workbox-cli": "6.4.2"
"workbox-cli": "6.5.2"
},
"eslintConfig": {
"root": true,
@ -145,5 +145,5 @@
}
},
"license": "AGPL-3.0-or-later",
"packageManager": "yarn@1.22.17"
"packageManager": "yarn@1.22.18"
}

View File

@ -1,20 +1,24 @@
const slugify = require('slugify')
const {exec} = require('child_process')
const axios = require('axios')
const BOT_USER_ID = 513
const giteaToken = process.env.GITEA_TOKEN
const siteId = process.env.NETLIFY_SITE_ID
const branchSlug = slugify(process.env.DRONE_SOURCE_BRANCH)
const branchSlug = String(process.env.DRONE_SOURCE_BRANCH)
.trim()
.normalize('NFKD')
.toLowerCase()
.replace(/[.\s/]/g, '-')
.replace(/[^A-Za-z\d-]/g, '')
const prNumber = process.env.DRONE_PULL_REQUEST
const prIssueCommentsUrl = `https://kolaente.dev/api/v1/repos/vikunja/frontend/issues/${prNumber}/comments`
const alias = `${prNumber}-${branchSlug}`
const alias = `${prNumber}-${branchSlug}`.substring(0,37)
const fullPreviewUrl = `https://${alias}--vikunja-frontend-preview.netlify.app`
const promiseExec = cmd => {
return new Promise((resolve, reject) => {
exec(cmd, (error, stdout, stderr) => {
exec(cmd, (error, stdout) => {
if (error) {
reject(error)
return

View File

@ -1 +1 @@
55ce0faaa2c1919341617ccfaeccbb6029ac12107964ff488985cff13dd952f1a991df3ab0d4b0705deb761e508e6434 ./scripts/deploy-preview-netlify.js
bb46342a0a08105b340ba7976cff9d80ef89901120ec0639669caa70bb7d2dbc43e78b1f635a7654ab2456e8358c98a4 ./scripts/deploy-preview-netlify.js

View File

@ -3,7 +3,7 @@ const express = require('express')
const app = express()
const p = path.join(__dirname, '..', 'dist-dev')
const port = 5000
const port = 4173
app.use(express.static(p))
// Handle urls set by the frontend

View File

@ -1,7 +1,7 @@
<template>
<ready>
<template v-if="authUser">
<top-navigation/>
<TheNavigation/>
<content-auth/>
</template>
<content-link-share v-else-if="authLinkShare"/>
@ -27,7 +27,7 @@ import {success} from '@/message'
import Notification from '@/components/misc/notification.vue'
import KeyboardShortcuts from './components/misc/keyboard-shortcuts/index.vue'
import TopNavigation from './components/home/topNavigation.vue'
import TheNavigation from '@/components/home/TheNavigation.vue'
import ContentAuth from './components/home/contentAuth.vue'
import ContentLinkShare from './components/home/contentLinkShare.vue'
import NoAuthWrapper from '@/components/misc/no-auth-wrapper.vue'

View File

@ -0,0 +1,21 @@
export const DATE_RANGES = {
// Format:
// Key is the title, as a translation string, the first entry of the value array
// is the "from" date, the second one is the "to" date.
'today': ['now/d', 'now/d+1d'],
'lastWeek': ['now/w-1w', 'now/w-2w'],
'thisWeek': ['now/w', 'now/w+1w'],
'restOfThisWeek': ['now', 'now/w+1w'],
'nextWeek': ['now/w+1w', 'now/w+2w'],
'next7Days': ['now', 'now+7d'],
'lastMonth': ['now/M-1M', 'now/M-2M'],
'thisMonth': ['now/M', 'now/M+1M'],
'restOfThisMonth': ['now', 'now/M+1M'],
'nextMonth': ['now/M+1M', 'now/M+2M'],
'next30Days': ['now', 'now+30d'],
'thisYear': ['now/y', 'now/y+1y'],
'restOfThisYear': ['now', 'now/y+1y'],
}

View File

@ -0,0 +1,131 @@
<template>
<card
class="has-no-shadow how-it-works-modal"
:title="$t('input.datemathHelp.title')">
<p>
{{ $t('input.datemathHelp.intro') }}
</p>
<p>
<i18n-t keypath="input.datemathHelp.expression">
<code>now</code>
<code>||</code>
</i18n-t>
</p>
<p>
<i18n-t keypath="input.datemathHelp.similar">
<BaseButton
href="https://grafana.com/docs/grafana/latest/dashboards/time-range-controls/"
target="_blank">
Grafana
</BaseButton>
<BaseButton
href="https://www.elastic.co/guide/en/elasticsearch/reference/7.3/common-options.html#date-math"
target="_blank">
Elasticsearch
</BaseButton>
</i18n-t>
</p>
<p>{{ $t('misc.forExample') }}</p>
<ul>
<li><code>+1d</code>{{ $t('input.datemathHelp.add1Day') }}</li>
<li><code>-1d</code>{{ $t('input.datemathHelp.minus1Day') }}</li>
<li><code>/d</code>{{ $t('input.datemathHelp.roundDay') }}</li>
</ul>
<p>{{ $t('input.datemathHelp.supportedUnits') }}</p>
<table class="table">
<tbody>
<tr>
<td><code>s</code></td>
<td>{{ $t('input.datemathHelp.units.seconds') }}</td>
</tr>
<tr>
<td><code>m</code></td>
<td>{{ $t('input.datemathHelp.units.minutes') }}</td>
</tr>
<tr>
<td><code>h</code></td>
<td>{{ $t('input.datemathHelp.units.hours') }}</td>
</tr>
<tr>
<td><code>H</code></td>
<td>{{ $t('input.datemathHelp.units.hours') }}</td>
</tr>
<tr>
<td><code>d</code></td>
<td>{{ $t('input.datemathHelp.units.days') }}</td>
</tr>
<tr>
<td><code>w</code></td>
<td>{{ $t('input.datemathHelp.units.weeks') }}</td>
</tr>
<tr>
<td><code>M</code></td>
<td>{{ $t('input.datemathHelp.units.months') }}</td>
</tr>
<tr>
<td><code>y</code></td>
<td>{{ $t('input.datemathHelp.units.years') }}</td>
</tr>
</tbody>
</table>
<p>{{ $t('input.datemathHelp.someExamples') }}</p>
<table class="table">
<tbody>
<tr>
<td><code>now</code></td>
<td>{{ $t('input.datemathHelp.examples.now') }}</td>
</tr>
<tr>
<td><code>now+24h</code></td>
<td>{{ $t('input.datemathHelp.examples.in24h') }}</td>
</tr>
<tr>
<td><code>now/d</code></td>
<td>{{ $t('input.datemathHelp.examples.today') }}</td>
</tr>
<tr>
<td><code>now/w</code></td>
<td>{{ $t('input.datemathHelp.examples.beginningOfThisWeek') }}</td>
</tr>
<tr>
<td><code>now/w+1w</code></td>
<td>{{ $t('input.datemathHelp.examples.endOfThisWeek') }}</td>
</tr>
<tr>
<td><code>now+30d</code></td>
<td>{{ $t('input.datemathHelp.examples.in30Days') }}</td>
</tr>
<tr>
<td><code>{{ exampleDate }}||+1M/d</code></td>
<td>
<i18n-t keypath="input.datemathHelp.examples.datePlusMonth">
<code>{{ exampleDate }}</code>
</i18n-t>
</td>
</tr>
</tbody>
</table>
</card>
</template>
<script lang="ts" setup>
import {format} from 'date-fns'
import BaseButton from '@/components/base/BaseButton.vue'
const exampleDate = format(new Date(), 'yyyy-MM-dd')
</script>
<style scoped>
.how-it-works-modal {
font-size: 1rem;
}
p {
display: inline-block !important;
}
.base-button {
display: inline;
}
</style>

View File

@ -0,0 +1,254 @@
<template>
<div class="datepicker-with-range-container">
<popup>
<template #trigger="{toggle}">
<slot name="trigger" :toggle="toggle" :buttonText="buttonText"></slot>
</template>
<template #content="{isOpen}">
<div class="datepicker-with-range" :class="{'is-open': isOpen}">
<div class="selections">
<BaseButton @click="setDateRange(null)" :class="{'is-active': customRangeActive}">
{{ $t('misc.custom') }}
</BaseButton>
<BaseButton
v-for="(value, text) in DATE_RANGES"
:key="text"
@click="setDateRange(value)"
:class="{'is-active': from === value[0] && to === value[1]}">
{{ $t(`input.datepickerRange.ranges.${text}`) }}
</BaseButton>
</div>
<div class="flatpickr-container input-group">
<label class="label">
{{ $t('input.datepickerRange.from') }}
<div class="field has-addons">
<div class="control is-fullwidth">
<input class="input" type="text" v-model="from"/>
</div>
<div class="control">
<x-button icon="calendar" variant="secondary" data-toggle/>
</div>
</div>
</label>
<label class="label">
{{ $t('input.datepickerRange.to') }}
<div class="field has-addons">
<div class="control is-fullwidth">
<input class="input" type="text" v-model="to"/>
</div>
<div class="control">
<x-button icon="calendar" variant="secondary" data-toggle/>
</div>
</div>
</label>
<flat-pickr
:config="flatPickerConfig"
v-model="flatpickrRange"
/>
<p>
{{ $t('input.datemathHelp.canuse') }}
<BaseButton class="has-text-primary" @click="showHowItWorks = true">
{{ $t('input.datemathHelp.learnhow') }}
</BaseButton>
</p>
<modal
@close="() => showHowItWorks = false"
:enabled="showHowItWorks"
transition-name="fade"
:overflow="true"
variant="hint-modal"
>
<DatemathHelp/>
</modal>
</div>
</div>
</template>
</popup>
</div>
</template>
<script lang="ts" setup>
import {computed, ref, watch} from 'vue'
import {useStore} from 'vuex'
import {useI18n} from 'vue-i18n'
import flatPickr from 'vue-flatpickr-component'
import 'flatpickr/dist/flatpickr.css'
import Popup from '@/components/misc/popup.vue'
import {DATE_RANGES} from '@/components/date/dateRanges'
import BaseButton from '@/components/base/BaseButton.vue'
import DatemathHelp from '@/components/date/datemathHelp.vue'
const store = useStore()
const {t} = useI18n()
const emit = defineEmits(['dateChanged'])
// FIXME: This seems to always contain the default value - that breaks the picker
const weekStart = computed<number>(() => store.state.auth.settings.weekStart ?? 0)
const flatPickerConfig = computed(() => ({
altFormat: t('date.altFormatLong'),
altInput: true,
dateFormat: 'Y-m-d H:i',
enableTime: false,
wrap: true,
mode: 'range',
locale: {
firstDayOf7Days: weekStart.value,
},
}))
const showHowItWorks = ref(false)
const flatpickrRange = ref('')
const from = ref('')
const to = ref('')
function emitChanged() {
emit('dateChanged', {
dateFrom: from.value === '' ? null : from.value,
dateTo: to.value === '' ? null : to.value,
})
}
watch(
() => flatpickrRange.value,
(newVal: string | null) => {
if (newVal === null) {
return
}
const [fromDate, toDate] = newVal.split(' to ')
if (typeof fromDate === 'undefined' || typeof toDate === 'undefined') {
return
}
from.value = fromDate
to.value = toDate
emitChanged()
},
)
watch(() => from.value, emitChanged)
watch(() => to.value, emitChanged)
function setDateRange(range: string[] | null) {
if (range === null) {
from.value = ''
to.value = ''
return
}
from.value = range[0]
to.value = range[1]
}
const customRangeActive = computed<boolean>(() => {
return !Object.values(DATE_RANGES).some(range => from.value === range[0] && to.value === range[1])
})
const buttonText = computed<string>(() => {
if (from.value !== '' && to.value !== '') {
return t('input.datepickerRange.fromto', {
from: from.value,
to: to.value,
})
}
return t('task.show.select')
})
</script>
<style lang="scss" scoped>
.datepicker-with-range-container {
position: relative;
}
:deep(.popup) {
z-index: 10;
margin-top: 1rem;
border-radius: $radius;
border: 1px solid var(--grey-200);
background-color: var(--white);
box-shadow: $shadow;
&.is-open {
width: 500px;
height: 320px;
}
}
.datepicker-with-range {
display: flex;
width: 100%;
height: 100%;
position: absolute;
}
:deep(.flatpickr-calendar) {
margin: 0 auto 8px;
box-shadow: none;
}
.flatpickr-container {
width: 70%;
border-left: 1px solid var(--grey-200);
padding: 1rem;
font-size: .9rem;
// Flatpickr has no option to use it without an input field so we're hiding it instead
:deep(input.form-control.input) {
height: 0;
padding: 0;
border: 0;
}
.field .control :deep(.button) {
border: 1px solid var(--input-border-color);
height: 2.25rem;
&:hover {
border: 1px solid var(--input-hover-border-color);
}
}
.label, .input, :deep(.button) {
font-size: .9rem;
}
}
.selections {
width: 30%;
display: flex;
flex-direction: column;
padding-top: .5rem;
overflow-y: scroll;
button {
display: block;
width: 100%;
text-align: left;
padding: .5rem 1rem;
transition: $transition;
font-size: .9rem;
color: var(--text);
background: transparent;
border: 0;
cursor: pointer;
&.is-active {
color: var(--primary);
}
&:hover, &.is-active {
background-color: var(--grey-100);
}
}
}
</style>

View File

@ -1,8 +1,7 @@
<template>
<button
type="button"
@click="$store.commit('toggleMenu')"
<BaseButton
class="menu-show-button"
@click="$store.commit('toggleMenu')"
@shortkey="() => $store.commit('toggleMenu')"
v-shortcut="'Control+e'"
:title="$t('keyboardShortcuts.toggleMenu')"
@ -10,11 +9,14 @@
/>
</template>
<script setup>
<script setup lang="ts">
import {computed} from 'vue'
import {store} from '@/store'
import {useStore} from 'vuex'
const menuActive = computed(() => store.menuActive)
import BaseButton from '@/components/base/BaseButton.vue'
const store = useStore()
const menuActive = computed(() => store.state.menuActive)
</script>
<style lang="scss" scoped>
@ -22,11 +24,6 @@ $lineWidth: 2rem;
$size: $lineWidth + 1rem;
.menu-show-button {
// FIXME: create general button component
appearance: none;
background-color: transparent;
border: 0;
min-height: $size;
width: $size;

View File

@ -32,12 +32,13 @@
</a>
<notifications/>
<div class="user">
<img :src="userAvatar" alt="" class="avatar" width="40" height="40"/>
<dropdown class="is-right" ref="usernameDropdown">
<template #trigger>
<x-button
variant="secondary"
:shadow="false">
:shadow="false"
>
<img :src="userAvatar" alt="" class="avatar" width="40" height="40"/>
<span class="username">{{ userInfo.name !== '' ? userInfo.name : userInfo.username }}</span>
<span class="icon is-small">
<icon icon="chevron-down"/>
@ -45,92 +46,96 @@
</x-button>
</template>
<router-link :to="{name: 'user.settings'}" class="dropdown-item">
<BaseButton
:to="{name: 'user.settings'}"
class="dropdown-item"
>
{{ $t('user.settings.title') }}
</router-link>
<a
</BaseButton>
<BaseButton
v-if="imprintUrl"
:href="imprintUrl"
class="dropdown-item"
target="_blank"
rel="noreferrer noopener nofollow"
v-if="imprintUrl">
>
{{ $t('navigation.imprint') }}
</a>
<a
</BaseButton>
<BaseButton
v-if="privacyPolicyUrl"
:href="privacyPolicyUrl"
class="dropdown-item"
target="_blank"
rel="noreferrer noopener nofollow"
v-if="privacyPolicyUrl">
>
{{ $t('navigation.privacy') }}
</a>
<a @click="$store.commit('keyboardShortcutsActive', true)" class="dropdown-item">
</BaseButton>
<BaseButton
@click="$store.commit('keyboardShortcutsActive', true)"
class="dropdown-item"
>
{{ $t('keyboardShortcuts.title') }}
</a>
<router-link :to="{name: 'about'}" class="dropdown-item">
</BaseButton>
<BaseButton
:to="{name: 'about'}"
class="dropdown-item"
>
{{ $t('about.title') }}
</router-link>
<a @click="logout()" class="dropdown-item">
</BaseButton>
<BaseButton
@click="logout()"
class="dropdown-item"
>
{{ $t('user.auth.logout') }}
</a>
</BaseButton>
</dropdown>
</div>
</div>
</header>
</template>
<script>
import {mapState} from 'vuex'
import {CURRENT_LIST, QUICK_ACTIONS_ACTIVE} from '@/store/mutation-types'
<script setup langs="ts">
import {ref, computed, onMounted, nextTick} from 'vue'
import {useStore} from 'vuex'
import {useRouter} from 'vue-router'
import {QUICK_ACTIONS_ACTIVE} from '@/store/mutation-types'
import Rights from '@/models/constants/rights.json'
import Update from '@/components/home/update.vue'
import ListSettingsDropdown from '@/components/list/list-settings-dropdown.vue'
import Dropdown from '@/components/misc/dropdown.vue'
import Notifications from '@/components/notifications/notifications.vue'
import Logo from '@/components/home/Logo.vue'
import BaseButton from '@/components/base/BaseButton.vue'
import MenuButton from '@/components/home/MenuButton.vue'
export default {
name: 'topNavigation',
components: {
Notifications,
Dropdown,
ListSettingsDropdown,
Update,
Logo,
MenuButton,
},
computed: {
...mapState({
userInfo: state => state.auth.info,
userAvatar: state => state.auth.avatarUrl,
userAuthenticated: state => state.auth.authenticated,
currentList: CURRENT_LIST,
background: 'background',
imprintUrl: state => state.config.legal.imprintUrl,
privacyPolicyUrl: state => state.config.legal.privacyPolicyUrl,
canWriteCurrentList: state => state.currentList.maxRight > Rights.READ,
}),
},
mounted() {
this.$nextTick(() => {
if (typeof this.$refs.usernameDropdown === 'undefined' || typeof this.$refs.listTitle === 'undefined') {
return
}
const store = useStore()
const usernameWidth = this.$refs.usernameDropdown.$el.clientWidth
this.$refs.listTitle.style.setProperty('--nav-username-width', `${usernameWidth}px`)
})
},
methods: {
logout() {
this.$store.dispatch('auth/logout')
this.$router.push({name: 'user.login'})
},
openQuickActions() {
this.$store.commit(QUICK_ACTIONS_ACTIVE, true)
},
},
const userInfo = computed(() => store.state.auth.info)
const userAvatar = computed(() => store.state.auth.avatarUrl)
const currentList = computed(() => store.state.currentList)
const background = computed(() => store.state.background)
const imprintUrl = computed(() => store.state.config.legal.imprintUrl)
const privacyPolicyUrl = computed(() => store.state.config.legal.privacyPolicyUrl)
const canWriteCurrentList = computed(() => store.state.currentList.maxRight > Rights.READ)
const usernameDropdown = ref()
const listTitle = ref()
onMounted(async () => {
await nextTick()
if (typeof usernameDropdown.value === 'undefined' || typeof listTitle.value === 'undefined') {
return
}
const usernameWidth = usernameDropdown.value.$el.clientWidth
listTitle.value.style.setProperty('--nav-username-width', `${usernameWidth}px`)
})
const router = useRouter()
function logout() {
store.dispatch('auth/logout')
router.push({name: 'user.login'})
}
function openQuickActions() {
store.commit(QUICK_ACTIONS_ACTIVE, true)
}
</script>
@ -246,6 +251,7 @@ $hamburger-menu-icon-width: 28px;
border-radius: 100%;
vertical-align: middle;
height: 40px;
margin-right: var(--button-padding-horizontal);
}
:deep(.dropdown-trigger .button) {

View File

@ -1,17 +1,21 @@
<template>
<div>
<div class="content-auth" :class="{'modal-active': modalActive}">
<BaseButton
v-if="menuActive"
@click="$store.commit('menuActive', false)"
class="menu-hide-button"
class="menu-hide-button"
>
<icon icon="times" />
<icon icon="times"/>
</BaseButton>
<div
:class="{'has-background': background}"
:style="{'background-image': background && `url(${background})`}"
:class="{'has-background': background || blurHash}"
:style="{'background-image': blurHash && `url(${blurHash})`}"
class="app-container"
>
<div
:class="{'is-visible': background}"
class="app-container-background background-fade-in"
:style="{'background-image': background && `url(${background})`}"></div>
<navigation/>
<main
:class="[
@ -31,18 +35,18 @@
<router-view :route="routeWithModal" v-slot="{ Component }">
<keep-alive :include="['list.list', 'list.gantt', 'list.table', 'list.kanban']">
<component :is="Component" />
<component :is="Component"/>
</keep-alive>
</router-view>
<transition name="modal">
<modal
v-if="currentModal"
v-if="currentModal"
@close="closeModal()"
variant="scrolling"
class="task-detail-view-modal"
>
<component :is="currentModal" />
<component :is="currentModal"/>
</modal>
</transition>
@ -115,16 +119,17 @@ function useRouteWithModal() {
}
}
return { routeWithModal, currentModal, closeModal }
return {routeWithModal, currentModal, closeModal}
}
const { routeWithModal, currentModal, closeModal } = useRouteWithModal()
const {routeWithModal, currentModal, closeModal} = useRouteWithModal()
const store = useStore()
const background = computed(() => store.state.background)
const blurHash = computed(() => store.state.blurHash)
const menuActive = computed(() => store.state.menuActive)
const modalActive = computed(() => store.state.modalActive)
function showKeyboardShortcuts() {
store.commit(KEYBOARD_SHORTCUTS_ACTIVE, true)
@ -151,7 +156,7 @@ watch(() => route.name as string, (routeName) => {
'migrate.start',
'migrate.wunderlist',
'namespaces.index',
].includes(routeName) ||
].includes(routeName) ||
routeName.startsWith('user.settings')
)
) {
@ -163,7 +168,7 @@ watch(() => route.name as string, (routeName) => {
function useRenewTokenOnFocus() {
const router = useRouter()
const userInfo = computed(() => store.state.auth.info)
const authenticated = computed(() => store.state.auth.authenticated)
@ -227,40 +232,41 @@ store.dispatch('labels/loadAllLabels')
}
.app-container {
min-height: calc(100vh - 65px);
min-height: calc(100vh - 65px);
@media screen and (max-width: $tablet) {
padding-top: $navbar-height;
}
.app-content {
padding: $navbar-height + 1.5rem 1.5rem 1rem 1.5rem;
z-index: 2;
@media screen and (max-width: $tablet) {
margin-left: 0;
padding-top: 1.5rem;
min-height: calc(100vh - 4rem);
}
&.is-menu-enabled {
margin-left: $navbar-width;
@media screen and (max-width: $tablet) {
min-width: 100%;
margin-left: 0;
}
}
&.task\.detail {
padding-left: 0;
padding-right: 0;
@media screen and (max-width: $tablet) {
padding-top: $navbar-height;
}
.card {
background: var(--white);
}
}
.app-content {
padding: $navbar-height + 1.5rem 1.5rem 1rem 1.5rem;
z-index: 10;
position: relative;
// Used to make sure the spinner is always in the middle while loading
> .loader-container {
min-height: calc(100vh - #{$navbar-height + 1.5rem + 1rem});
}
@media screen and (max-width: $tablet) {
margin-left: 0;
padding-top: 1.5rem;
min-height: calc(100vh - 4rem);
}
&.is-menu-enabled {
margin-left: $navbar-width;
@media screen and (max-width: $tablet) {
min-width: 100%;
margin-left: 0;
}
}
.card {
background: var(--white);
}
}
}
.mobile-overlay {
@ -270,7 +276,9 @@ store.dispatch('labels/loadAllLabels')
bottom: 0;
left: 0;
right: 0;
background: rgba(250, 250, 250, 0.8);
height: 100vh;
width: 100vw;
background: hsla(var(--grey-100-hsl), 0.8);
z-index: 5;
opacity: 0;
transition: all $transition;
@ -289,11 +297,20 @@ store.dispatch('labels/loadAllLabels')
color: var(--grey-500);
transition: color $transition;
@media screen and (max-width: $tablet) {
display: none;
}
}
.content-auth {
position: relative;
z-index: 1;
&.modal-active {
z-index: unset;
}
}
@include modal-transition();
</style>

View File

@ -6,7 +6,7 @@
</router-link>
<ul class="menu-list">
<li>
<router-link :to="{ name: 'home'}">
<router-link :to="{ name: 'home'}" v-shortcut="'g o'">
<span class="icon">
<icon icon="calendar"/>
</span>
@ -14,7 +14,7 @@
</router-link>
</li>
<li>
<router-link :to="{ name: 'tasks.range'}">
<router-link :to="{ name: 'tasks.range'}" v-shortcut="'g u'">
<span class="icon">
<icon :icon="['far', 'calendar-alt']"/>
</span>
@ -22,7 +22,7 @@
</router-link>
</li>
<li>
<router-link :to="{ name: 'namespaces.index'}">
<router-link :to="{ name: 'namespaces.index'}" v-shortcut="'g n'">
<span class="icon">
<icon icon="layer-group"/>
</span>
@ -30,7 +30,7 @@
</router-link>
</li>
<li>
<router-link :to="{ name: 'labels.index'}">
<router-link :to="{ name: 'labels.index'}" v-shortcut="'g a'">
<span class="icon">
<icon icon="tags"/>
</span>
@ -38,7 +38,7 @@
</router-link>
</li>
<li>
<router-link :to="{ name: 'teams.index'}">
<router-link :to="{ name: 'teams.index'}" v-shortcut="'g m'">
<span class="icon">
<icon icon="users"/>
</span>

View File

@ -66,7 +66,7 @@ const showIconOnly = computed(() => props.icon !== '' && typeof slots.default ==
text-transform: uppercase;
font-size: 0.85rem;
font-weight: bold;
height: $button-height;
min-height: $button-height;
box-shadow: var(--shadow-sm);
display: inline-flex;

View File

@ -183,6 +183,10 @@ export default {
this.updateData()
},
get() {
if(!this.date) {
return ''
}
return format(this.date, 'yyy-LL-dd H:mm')
},
},

View File

@ -326,7 +326,7 @@ export default {
}
&.has-checkbox {
margin-left: -2em;
margin-left: -1.25rem;
list-style: none;
}
}

View File

@ -450,7 +450,6 @@ export default {
button {
background: transparent;
display: block;
text-align: left;
box-shadow: none;
border-radius: 0;
@ -460,6 +459,7 @@ export default {
padding: .5rem;
border: none;
cursor: pointer;
color: var(--grey-800);
display: flex;
justify-content: space-between;

View File

@ -16,7 +16,7 @@
<a
@click="togglePasswordFieldType"
class="password-field-type-toggle"
aria-label="passwordFieldType === 'password' ? $t('user.auth.showPassword') : $t('user.auth.hidePassword')"
:aria-label="passwordFieldType === 'password' ? $t('user.auth.showPassword') : $t('user.auth.hidePassword')"
v-tooltip="passwordFieldType === 'password' ? $t('user.auth.showPassword') : $t('user.auth.hidePassword')">
<icon :icon="passwordFieldType === 'password' ? 'eye' : 'eye-slash'"/>
</a>

View File

@ -6,7 +6,7 @@
>
{{ $t('filters.clear') }}
</x-button>
<popup>
<popup :has-overflow="true">
<template #trigger="{toggle}">
<x-button
@click.prevent.stop="toggle()"

View File

@ -67,49 +67,49 @@
<div class="field">
<label class="label">{{ $t('task.attributes.dueDate') }}</label>
<div class="control">
<flat-pickr
:config="flatPickerConfig"
@on-close="setDueDateFilter"
class="input"
:placeholder="$t('filters.attributes.dueDateRange')"
v-model="filters.dueDate"
/>
<datepicker-with-range @dateChanged="values => setDateFilter('due_date', values)">
<template #trigger="{toggle, buttonText}">
<x-button @click.prevent.stop="toggle()" variant="secondary" :shadow="false" class="mb-2">
{{ buttonText }}
</x-button>
</template>
</datepicker-with-range>
</div>
</div>
<div class="field">
<label class="label">{{ $t('task.attributes.startDate') }}</label>
<div class="control">
<flat-pickr
:config="flatPickerConfig"
@on-close="setStartDateFilter"
class="input"
:placeholder="$t('filters.attributes.startDateRange')"
v-model="filters.startDate"
/>
<datepicker-with-range @dateChanged="values => setDateFilter('start_date', values)">
<template #trigger="{toggle, buttonText}">
<x-button @click.prevent.stop="toggle()" variant="secondary" :shadow="false" class="mb-2">
{{ buttonText }}
</x-button>
</template>
</datepicker-with-range>
</div>
</div>
<div class="field">
<label class="label">{{ $t('task.attributes.endDate') }}</label>
<div class="control">
<flat-pickr
:config="flatPickerConfig"
@on-close="setEndDateFilter"
class="input"
:placeholder="$t('filters.attributes.endDateRange')"
v-model="filters.endDate"
/>
<datepicker-with-range @dateChanged="values => setDateFilter('end_date', values)">
<template #trigger="{toggle, buttonText}">
<x-button @click.prevent.stop="toggle()" variant="secondary" :shadow="false" class="mb-2">
{{ buttonText }}
</x-button>
</template>
</datepicker-with-range>
</div>
</div>
<div class="field">
<label class="label">{{ $t('task.attributes.reminders') }}</label>
<div class="control">
<flat-pickr
:config="flatPickerConfig"
@on-close="setReminderFilter"
class="input"
:placeholder="$t('filters.attributes.reminderRange')"
v-model="filters.reminders"
/>
<datepicker-with-range @dateChanged="values => setDateFilter('reminders', values)">
<template #trigger="{toggle, buttonText}">
<x-button @click.prevent.stop="toggle()" variant="secondary" :shadow="false" class="mb-2">
{{ buttonText }}
</x-button>
</template>
</datepicker-with-range>
</div>
</div>
@ -175,15 +175,14 @@
</template>
<script>
import DatepickerWithRange from '@/components/date/datepickerWithRange'
import Fancycheckbox from '../../input/fancycheckbox'
import flatPickr from 'vue-flatpickr-component'
import 'flatpickr/dist/flatpickr.css'
import {includesById} from '@/helpers/utils'
import {formatISO} from 'date-fns'
import PrioritySelect from '@/components/tasks/partials/prioritySelect.vue'
import PercentDoneSelect from '@/components/tasks/partials/percentDoneSelect.vue'
import Multiselect from '@/components/input/multiselect.vue'
import {parseDateOrString} from '@/helpers/time/parseDateOrString'
import UserService from '@/services/user'
import ListService from '@/services/list'
@ -222,15 +221,15 @@ const DEFAULT_FILTERS = {
namespace: '',
}
export const ALPHABETICAL_SORT = 'title'
export const ALPHABETICAL_SORT = 'title'
export default {
name: 'filters',
components: {
DatepickerWithRange,
EditLabels,
PrioritySelect,
Fancycheckbox,
flatPickr,
PercentDoneSelect,
Multiselect,
},
@ -281,7 +280,7 @@ export default {
return this.params?.sort_by?.find(sortBy => sortBy === ALPHABETICAL_SORT) !== undefined
},
set(sortAlphabetically) {
this.params.sort_by = sortAlphabetically
this.params.sort_by = sortAlphabetically
? [ALPHABETICAL_SORT]
: getDefaultParams().sort_by
@ -291,19 +290,6 @@ export default {
foundLabels() {
return this.$store.getters['labels/filterLabelsByQuery'](this.labels, this.query)
},
flatPickerConfig() {
return {
altFormat: this.$t('date.altFormatLong'),
altInput: true,
dateFormat: 'Y-m-d H:i',
enableTime: true,
time_24hr: true,
mode: 'range',
locale: {
firstDayOfWeek: this.$store.state.auth.settings.weekStart,
},
}
},
},
methods: {
change() {
@ -343,19 +329,12 @@ export default {
}
}
},
setDateFilter(filterName, variableName = null) {
if (variableName === null) {
variableName = filterName
}
// Only filter if we have a start and end due date
if (this.filters[variableName] !== '') {
setDateFilter(filterName, {dateFrom, dateTo}) {
dateFrom = parseDateOrString(dateFrom, null)
dateTo = parseDateOrString(dateTo, null)
const parts = this.filters[variableName].split(' to ')
if (parts.length < 2) {
return
}
// Only filter if we have a date
if (dateFrom !== null && dateTo !== null) {
// Check if we already have values in params and only update them if we do
let foundStart = false
@ -363,23 +342,23 @@ export default {
this.params.filter_by.forEach((f, i) => {
if (f === filterName && this.params.filter_comparator[i] === 'greater_equals') {
foundStart = true
this.params.filter_value[i] = formatISO(new Date(parts[0]))
this.params.filter_value[i] = dateFrom
}
if (f === filterName && this.params.filter_comparator[i] === 'less_equals') {
foundEnd = true
this.params.filter_value[i] = formatISO(new Date(parts[1]))
this.params.filter_value[i] = dateTo
}
})
if (!foundStart) {
this.params.filter_by.push(filterName)
this.params.filter_comparator.push('greater_equals')
this.params.filter_value.push(formatISO(new Date(parts[0])))
this.params.filter_value.push(dateFrom)
}
if (!foundEnd) {
this.params.filter_by.push(filterName)
this.params.filter_comparator.push('less_equals')
this.params.filter_value.push(formatISO(new Date(parts[1])))
this.params.filter_value.push(dateTo)
}
this.change()
return
@ -513,24 +492,12 @@ export default {
this.params.filter_concat = 'or'
}
},
setDueDateFilter() {
this.setDateFilter('due_date', 'dueDate')
},
setPriority() {
this.setSingleValueFilter('priority', 'priority', 'usePriority')
},
setStartDateFilter() {
this.setDateFilter('start_date', 'startDate')
},
setEndDateFilter() {
this.setDateFilter('end_date', 'endDate')
},
setPercentDoneFilter() {
this.setSingleValueFilter('percent_done', 'percentDone', 'usePercentDone')
},
setReminderFilter() {
this.setDateFilter('reminders')
},
clear(kind) {
this[`found${kind}`] = []
},
@ -609,7 +576,7 @@ export default {
}
</script>
<style lang="scss">
<style lang="scss" scoped>
.single-value-control {
display: flex;
align-items: center;
@ -618,4 +585,8 @@ export default {
margin-left: .5rem;
}
}
:deep(.datepicker-with-range-container .popup) {
right: 0;
}
</style>

View File

@ -2,28 +2,34 @@
<router-link
:class="{
'has-light-text': !colorIsDark(list.hexColor),
'has-background': background !== null
'has-background': blurHashUrl !== ''
}"
:style="{
'background-color': list.hexColor,
'background-image': background !== null ? `url(${background})` : false,
'background-image': blurHashUrl !== null ? `url(${blurHashUrl})` : false,
}"
:to="{ name: 'list.index', params: { listId: list.id} }"
class="list-card"
v-if="list !== null && (showArchived ? true : !list.isArchived)"
>
<div class="is-archived-container">
<div
class="list-background background-fade-in"
:class="{'is-visible': background}"
:style="{'background-image': background !== null ? `url(${background})` : false}"></div>
<div class="list-content">
<div class="is-archived-container">
<span class="is-archived" v-if="list.isArchived">
{{ $t('namespace.archived') }}
</span>
<span
:class="{'is-favorite': list.isFavorite, 'is-archived': list.isArchived}"
@click.stop="toggleFavoriteList(list)"
class="favorite">
<icon :icon="list.isFavorite ? 'star' : ['far', 'star']" />
<span
:class="{'is-favorite': list.isFavorite, 'is-archived': list.isArchived}"
@click.stop="toggleFavoriteList(list)"
class="favorite">
<icon :icon="list.isFavorite ? 'star' : ['far', 'star']"/>
</span>
</div>
<div class="title">{{ list.title }}</div>
</div>
<div class="title">{{ list.title }}</div>
</router-link>
</template>
@ -32,12 +38,14 @@ import {PropType, ref, watch} from 'vue'
import {useStore} from 'vuex'
import ListService from '@/services/list'
import {getBlobFromBlurHash} from '@/helpers/getBlobFromBlurHash'
import {colorIsDark} from '@/helpers/color/colorIsDark'
import ListModel from '@/models/list'
const background = ref<string | null>(null)
const backgroundLoading = ref(false)
const blurHashUrl = ref('')
const props = defineProps({
list: {
@ -50,13 +58,18 @@ const props = defineProps({
},
})
watch(props.list, loadBackground, { immediate: true })
watch(props.list, loadBackground, {immediate: true})
async function loadBackground() {
if (props.list === null || !props.list.backgroundInformation || backgroundLoading.value) {
return
}
const blurHash = await getBlobFromBlurHash(props.list.backgroundBlurHash)
if (blurHash) {
blurHashUrl.value = window.URL.createObjectURL(blurHash)
}
backgroundLoading.value = true
const listService = new ListService()
@ -81,129 +94,145 @@ function toggleFavoriteList(list: ListModel) {
<style lang="scss" scoped>
.list-card {
cursor: pointer;
width: calc((100% - #{($lists-per-row - 1) * 1rem}) / #{$lists-per-row});
height: $list-height;
background: var(--white);
margin: 0 $list-spacing $list-spacing 0;
padding: 1rem;
border-radius: $radius;
box-shadow: var(--shadow-sm);
transition: box-shadow $transition;
cursor: pointer;
width: calc((100% - #{($lists-per-row - 1) * 1rem}) / #{$lists-per-row});
height: $list-height;
background: var(--white);
margin: 0 $list-spacing $list-spacing 0;
border-radius: $radius;
box-shadow: var(--shadow-sm);
transition: box-shadow $transition;
position: relative;
overflow: hidden;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
&.has-light-text .title {
color: var(--light);
}
&:hover {
box-shadow: var(--shadow-md);
}
&.has-background, .list-background {
background-size: cover;
background-repeat: no-repeat;
background-position: center;
}
&:active,
&:focus,
&:focus:not(:active) {
box-shadow: var(--shadow-xs) !important;
}
&.has-background .list-content .title {
text-shadow: 0 0 10px var(--black), 1px 1px 5px var(--grey-700), -1px -1px 5px var(--grey-700);
color: var(--white);
}
@media screen and (min-width: $widescreen) {
&:nth-child(#{$lists-per-row}n) {
margin-right: 0;
}
}
.list-background {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
@media screen and (max-width: $widescreen) and (min-width: $tablet) {
$lists-per-row: 3;
& {
width: calc((100% - #{($lists-per-row - 1) * 1rem}) / #{$lists-per-row});
}
&:hover {
box-shadow: var(--shadow-md);
}
&:nth-child(#{$lists-per-row}n) {
margin-right: 0;
}
}
&:active,
&:focus,
&:focus:not(:active) {
box-shadow: var(--shadow-xs) !important;
}
@media screen and (max-width: $tablet) {
$lists-per-row: 2;
& {
width: calc((100% - #{($lists-per-row - 1) * 1rem}) / #{$lists-per-row});
}
@media screen and (min-width: $widescreen) {
&:nth-child(#{$lists-per-row}n) {
margin-right: 0;
}
}
&:nth-child(#{$lists-per-row}n) {
margin-right: 0;
}
}
@media screen and (max-width: $widescreen) and (min-width: $tablet) {
$lists-per-row: 3;
& {
width: calc((100% - #{($lists-per-row - 1) * 1rem}) / #{$lists-per-row});
}
@media screen and (max-width: $mobile) {
$lists-per-row: 1;
& {
width: 100%;
margin-right: 0;
}
}
&:nth-child(#{$lists-per-row}n) {
margin-right: 0;
}
}
.is-archived-container {
width: 100%;
text-align: right;
@media screen and (max-width: $tablet) {
$lists-per-row: 2;
& {
width: calc((100% - #{($lists-per-row - 1) * 1rem}) / #{$lists-per-row});
}
.is-archived {
font-size: .75rem;
float: left;
}
}
&:nth-child(#{$lists-per-row}n) {
margin-right: 0;
}
}
.title {
align-self: flex-end;
font-family: $vikunja-font;
font-weight: 400;
font-size: 1.5rem;
color: var(--text);
width: 100%;
margin-bottom: 0;
max-height: calc(100% - 2rem); // 1rem padding, 1rem height of the "is archived" badge
overflow: hidden;
text-overflow: ellipsis;
@media screen and (max-width: $mobile) {
$lists-per-row: 1;
& {
width: 100%;
margin-right: 0;
}
}
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
}
.list-content {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
padding: 1rem;
position: absolute;
height: 100%;
width: 100%;
&.has-light-text .title {
color: var(--light);
}
.is-archived-container {
width: 100%;
text-align: right;
&.has-background {
background-size: cover;
background-repeat: no-repeat;
background-position: center;
.is-archived {
font-size: .75rem;
float: left;
}
}
.title {
text-shadow: 0 0 10px var(--black), 1px 1px 5px var(--grey-700), -1px -1px 5px var(--grey-700);
color: var(--white);
}
}
.title {
align-self: flex-end;
font-family: $vikunja-font;
font-weight: 400;
font-size: 1.5rem;
color: var(--text);
width: 100%;
margin-bottom: 0;
max-height: calc(100% - 2rem); // 1rem padding, 1rem height of the "is archived" badge
overflow: hidden;
text-overflow: ellipsis;
.favorite {
transition: opacity $transition, color $transition;
opacity: 0;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
}
&:hover {
color: var(--warning);
}
.favorite {
transition: opacity $transition, color $transition;
opacity: 0;
&.is-archived {
display: none;
}
&:hover {
color: var(--warning);
}
&.is-favorite {
display: inline-block;
opacity: 1;
color: var(--warning);
}
}
&.is-archived {
display: none;
}
&:hover .favorite {
opacity: 1;
}
&.is-favorite {
display: inline-block;
opacity: 1;
color: var(--warning);
}
}
&:hover .favorite {
opacity: 1;
}
}
}
</style>

View File

@ -39,79 +39,68 @@
</div>
</template>
<script>
import Message from '@/components/misc/message'
<script setup lang="ts">
import {ref, computed, watch} from 'vue'
import {useI18n} from 'vue-i18n'
import {parseURL} from 'ufo'
import {checkAndSetApiUrl} from '@/helpers/checkAndSetApiUrl'
import {success} from '@/message'
export default {
name: 'apiConfig',
components: {
Message,
import Message from '@/components/misc/message.vue'
const props = defineProps({
configureOpen: {
type: Boolean,
required: false,
default: false,
},
data() {
return {
configureApi: false,
apiUrl: window.API_URL,
errorMsg: '',
successMsg: '',
})
const emit = defineEmits(['foundApi'])
const apiUrl = ref(window.API_URL)
const configureApi = ref(apiUrl.value === '')
// Because we're only using this to parse the hostname, it should be fine to just prefix with http://
// regardless of whether the url is actually reachable under http.
const apiDomain = computed(() => parseURL(apiUrl.value, 'http://').host || parseURL(window.location.href).host)
watch(() => props.configureOpen, (value) => {
configureApi.value = value
}, {immediate: true})
const {t} = useI18n()
const errorMsg = ref('')
const successMsg = ref('')
async function setApiUrl() {
if (apiUrl.value === '') {
// Don't try to check and set an empty url
errorMsg.value = t('apiConfig.urlRequired')
return
}
try {
const url = await checkAndSetApiUrl(apiUrl.value)
if (url === '') {
// If the config setter function could not figure out a url
throw new Error('URL cannot be empty.')
}
},
emits: ['foundApi'],
created() {
if (this.apiUrl === '') {
this.configureApi = true
}
},
computed: {
apiDomain() {
return parseURL(this.apiUrl).host || parseURL(window.location.href).host
},
},
props: {
configureOpen: {
type: Boolean,
required: false,
default: false,
},
},
watch: {
configureOpen: {
handler(value) {
this.configureApi = value
},
immediate: true,
},
},
methods: {
async setApiUrl() {
if (this.apiUrl === '') {
// Don't try to check and set an empty url
this.errorMsg = this.$t('apiConfig.urlRequired')
return
}
try {
const url = await checkAndSetApiUrl(this.apiUrl)
if (url === '') {
// If the config setter function could not figure out a url
throw new Error('URL cannot be empty.')
}
// Set it + save it to local storage to save us the hoops
this.errorMsg = ''
this.$message.success({message: this.$t('apiConfig.success', {domain: this.apiDomain})})
this.configureApi = false
this.apiUrl = url
this.$emit('foundApi', this.apiUrl)
} catch (e) {
// Still not found, url is still invalid
this.successMsg = ''
this.errorMsg = this.$t('apiConfig.error', {domain: this.apiDomain})
}
},
},
// Set it + save it to local storage to save us the hoops
errorMsg.value = ''
apiUrl.value = url
success({message: t('apiConfig.success', {domain: apiDomain.value})})
configureApi.value = false
emit('foundApi', apiUrl.value)
} catch (e) {
// Still not found, url is still invalid
successMsg.value = ''
errorMsg.value = t('apiConfig.error', {domain: apiDomain.value})
}
}
</script>

View File

@ -6,9 +6,13 @@
<message class="mb-4" v-if="s.available">
{{
s.available($route)
? $t('keyboardShortcuts.currentPageOnly')
: $t('keyboardShortcuts.allPages')
typeof s.available === 'undefined' ?
$t('keyboardShortcuts.allPages') :
(
s.available($route)
? $t('keyboardShortcuts.currentPageOnly')
: $t('keyboardShortcuts.somePagesOnly')
)
}}
</message>
@ -38,6 +42,7 @@ import {KEYBOARD_SHORTCUTS_ACTIVE} from '@/store/mutation-types'
import {KEYBOARD_SHORTCUTS as shortcuts} from './shortcuts'
const store = useStore()
function close() {
store.commit(KEYBOARD_SHORTCUTS_ACTIVE, false)
}

View File

@ -30,6 +30,36 @@ export const KEYBOARD_SHORTCUTS : ShortcutGroup[] = [
},
],
},
{
title: 'keyboardShortcuts.navigation.title',
shortcuts: [
{
title: 'keyboardShortcuts.navigation.overview',
keys: ['g', 'o'],
combination: 'then',
},
{
title: 'keyboardShortcuts.navigation.upcoming',
keys: ['g', 'u'],
combination: 'then',
},
{
title: 'keyboardShortcuts.navigation.namespaces',
keys: ['g', 'n'],
combination: 'then',
},
{
title: 'keyboardShortcuts.navigation.labels',
keys: ['g', 'a'],
combination: 'then',
},
{
title: 'keyboardShortcuts.navigation.teams',
keys: ['g', 'm'],
combination: 'then',
},
],
},
{
title: 'list.kanban.title',
available: (route) => route.name === 'list.kanban',
@ -70,6 +100,10 @@ export const KEYBOARD_SHORTCUTS : ShortcutGroup[] = [
title: 'keyboardShortcuts.task.title',
available: (route) => route.name === 'task.detail',
shortcuts: [
{
title: 'keyboardShortcuts.task.done',
keys: ['t'],
},
{
title: 'keyboardShortcuts.task.assign',
keys: ['a'],
@ -90,6 +124,14 @@ export const KEYBOARD_SHORTCUTS : ShortcutGroup[] = [
title: 'keyboardShortcuts.task.related',
keys: ['r'],
},
{
title: 'keyboardShortcuts.task.move',
keys: ['m'],
},
{
title: 'keyboardShortcuts.task.color',
keys: ['c'],
},
],
},
]

View File

@ -1,6 +1,6 @@
<template>
<slot name="trigger" :isOpen="open" :toggle="toggle"></slot>
<div class="popup" :class="{'is-open': open}" ref="popup">
<div class="popup" :class="{'is-open': open, 'has-overflow': props.hasOverflow && open}" ref="popup">
<slot name="content" :isOpen="open"/>
</div>
</template>
@ -16,6 +16,13 @@ const toggle = () => {
open.value = !open.value
}
const props = defineProps({
hasOverflow: {
type: Boolean,
default: false,
},
})
function hidePopup(e) {
if (!open.value) {
return

View File

@ -8,10 +8,10 @@
{ 'has-overflow': overflow },
variant,
]"
ref="modal"
>
<div
class="modal-container"
:class="{'has-overflow': overflow}"
@click.self.prevent.stop="$emit('close')"
v-shortcut="'Escape'"
>
@ -60,65 +60,41 @@
</transition>
</template>
<script>
<script lang="ts" setup>
import BaseButton from '@/components/base/BaseButton.vue'
import {ref, watch} from 'vue'
import {useScrollLock} from '@vueuse/core'
import {useStore} from 'vuex'
export const TRANSITION_NAMES = {
MODAL: 'modal',
FADE: 'fade',
}
const store = useStore()
export const VARIANTS = {
DEFAULT: 'default',
HINT_MODAL: 'hint-modal',
SCROLLING: 'scrolling',
}
const props = withDefaults(defineProps<{
enabled?: boolean,
overflow?: boolean,
wide?: boolean,
transitionName?: 'modal' | 'fade',
variant?: 'default' | 'hint-modal' | 'scrolling',
}>(), {
enabled: true,
transitionName: 'modal',
variant: 'default',
})
function validValue(values) {
return (value) => Object.values(values).includes(value)
}
defineEmits(['close', 'submit'])
export default {
name: 'modal',
const modal = ref<HTMLElement | null>(null)
const scrollLock = useScrollLock(modal)
components: {
BaseButton,
watch(
() => props.enabled,
enabled => {
scrollLock.value = enabled
store.commit('modalActive', enabled)
},
mounted() {
document.addEventListener('keydown', (e) => {
// Close the model when escape is pressed
if (e.keyCode === 27) {
this.$emit('close')
}
})
{
immediate: true,
},
props: {
enabled: {
type: Boolean,
default: true,
},
overflow: {
type: Boolean,
default: false,
},
wide: {
type: Boolean,
default: false,
},
transitionName: {
type: String,
default: TRANSITION_NAMES.MODAL,
validator: validValue(TRANSITION_NAMES),
},
variant: {
type: String,
default: VARIANTS.DEFAULT,
validator: validValue(VARIANTS),
},
},
emits: ['close', 'submit'],
}
)
</script>
<style lang="scss" scoped>
@ -207,7 +183,6 @@ export default {
display: flex;
justify-content: space-between;
align-items: center;
}
}
}
@ -220,14 +195,14 @@ export default {
font-size: 2rem;
@media screen and (max-width: $desktop) {
color: var(--dark);
color: var(--grey-900);
}
}
</style>
<style lang="scss">
// Close icon SVG uses currentColor, change the color to keep it visible
.dark .task-detail-view-modal .close {
.dark .close {
color: var(--grey-900);
}
</style>

View File

@ -81,7 +81,7 @@ export default {
return this.notifications.filter(n => n.readAt === null).length
},
notifications() {
return this.allNotifications.filter(n => n.name !== '')
return this.allNotifications ? this.allNotifications.filter(n => n.name !== '') : []
},
...mapState({
userInfo: state => state.auth.info,

View File

@ -5,12 +5,13 @@
<textarea
:disabled="taskService.loading || undefined"
class="add-task-textarea input"
:class="{'textarea-empty': newTaskTitle === ''}"
:placeholder="$t('list.list.addPlaceholder')"
rows="1"
v-focus
v-model="newTaskTitle"
ref="newTaskInput"
@keyup="errorMessage = ''"
@keyup="resetEmptyTitleError"
@keydown.enter="handleEnter"
/>
<span class="icon is-small is-left">
@ -24,15 +25,18 @@
@click="addTask()"
icon="plus"
:loading="taskService.loading"
:aria-label="$t('list.list.add')"
>
{{ $t('list.list.add') }}
<span class="button-text">
{{ $t('list.list.add') }}
</span>
</x-button>
</p>
</div>
<p class="help is-danger" v-if="errorMessage !== ''">
{{ errorMessage }}
</p>
<quick-add-magic v-else />
<quick-add-magic v-else/>
</div>
</template>
@ -40,7 +44,7 @@
import {ref, watch, unref, shallowReactive} from 'vue'
import {useI18n} from 'vue-i18n'
import {useStore} from 'vuex'
import { tryOnMounted, debouncedWatch, useWindowSize, MaybeRef } from '@vueuse/core'
import {tryOnMounted, debouncedWatch, useWindowSize, MaybeRef} from '@vueuse/core'
import TaskService from '@/services/task'
import QuickAddMagic from '@/components/tasks/partials/quick-add-magic.vue'
@ -54,12 +58,12 @@ function useAutoHeightTextarea(value: MaybeRef<string>) {
const minHeight = ref(0)
// adapted from https://github.com/LeaVerou/stretchy/blob/47f5f065c733029acccb755cae793009645809e2/src/stretchy.js#L34
function resize(textareaEl: HTMLInputElement|undefined) {
function resize(textareaEl: HTMLInputElement | undefined) {
if (!textareaEl) return
let empty
// the value here is the the attribute value
// the value here is the attribute value
if (!textareaEl.value && textareaEl.placeholder) {
empty = true
textareaEl.value = textareaEl.placeholder
@ -95,12 +99,12 @@ function useAutoHeightTextarea(value: MaybeRef<string>) {
}
})
const { width: windowWidth } = useWindowSize()
const {width: windowWidth} = useWindowSize()
debouncedWatch(
windowWidth,
() => resize(textarea.value),
{ debounce: 200 },
{debounce: 200},
)
// It is not possible to get notified of a change of the value attribute of a textarea without workarounds (setTimeout)
@ -129,12 +133,18 @@ const emit = defineEmits(['taskAdded'])
const newTaskTitle = ref('')
const newTaskInput = useAutoHeightTextarea(newTaskTitle)
const { t } = useI18n()
const {t} = useI18n()
const store = useStore()
const taskService = shallowReactive(new TaskService())
const errorMessage = ref('')
function resetEmptyTitleError() {
if (newTaskTitle.value !== '') {
errorMessage.value = ''
}
}
async function addTask() {
if (newTaskTitle.value === '') {
errorMessage.value = t('list.create.addTitleRequired')
@ -194,9 +204,26 @@ function handleEnter(e: KeyboardEvent) {
.add-task-button {
height: 2.5rem;
@media screen and (max-width: $mobile) {
.button-text {
display: none;
}
:deep(.icon) {
margin: 0 !important;
}
}
}
.add-task-textarea {
transition: border-color $transition;
resize: none;
}
// Adding this class when the textarea has no text prevents the textarea from wrapping the placeholder.
.textarea-empty {
white-space: nowrap;
text-overflow: ellipsis;
}
</style>

View File

@ -114,7 +114,7 @@ export default {
},
async removeLabel(label) {
if (!this.taskId === 0) {
if (this.taskId !== 0) {
await this.$store.dispatch('tasks/removeLabel', {label: label, taskId: this.taskId})
}

View File

@ -104,11 +104,12 @@ export default {
async toggleTaskDone(task) {
this.loadingInternal = true
try {
const done = !task.done
await this.$store.dispatch('tasks/update', {
...task,
done: !task.done,
done,
})
if (task.done) {
if (done) {
playPop()
}
} finally {

View File

@ -83,7 +83,9 @@
<span class="title">{{ rts.title }}</span>
<div class="tasks">
<div :key="t.id" class="task" v-for="t in rts.tasks">
<router-link :to="{ name: $route.name, params: { id: t.id } }" :class="{ 'done': t.done}">
<router-link
:to="{ name: $route.name, params: { id: t.id } }"
:class="{ 'is-strikethrough': t.done}">
<span
class="different-list"
v-if="t.listId !== listId"
@ -156,6 +158,7 @@ export default {
relationToDelete: {},
saved: false,
showNewRelationForm: false,
query: '',
}
},
components: {
@ -211,10 +214,20 @@ export default {
},
methods: {
async findTasks(query) {
this.query = query
this.foundTasks = await this.taskService.getAll({}, {s: query})
},
async addTaskRelation() {
if (this.newTaskRelationTask.id === 0 && this.query !== '') {
return this.createAndRelateTask(this.query)
}
if (this.newTaskRelationTask.id === 0) {
this.$message.error({message: this.$t('task.relation.taskRequired')})
return
}
const rel = new TaskRelationModel({
taskId: this.taskId,
otherTaskId: this.newTaskRelationTask.id,

View File

@ -190,10 +190,7 @@ export default {
this.$t('task.undoneSuccess'),
}, [{
title: 'Undo',
callback() {
this.task.done = !this.task.done
this.markAsDone(!checked)
},
callback: () => this.undoDone(checked),
}])
}
@ -203,6 +200,11 @@ export default {
await updateFunc() // Don't delay it when un-marking it as it doesn't have an animation the other way around
}
},
undoDone(checked) {
this.task.done = !this.task.done
this.markAsDone(!checked)
},
async toggleFavorite() {
this.task.isFavorite = !this.task.isFavorite

View File

@ -1,4 +1,4 @@
import {HTTPFactory} from '@/http-common'
import {AuthenticatedHTTPFactory} from '@/http-common'
import {AxiosResponse} from 'axios'
let savedToken: string | null = null
@ -6,8 +6,6 @@ let savedToken: string | null = null
/**
* Saves a token while optionally saving it to lacal storage. This is used when viewing a link share:
* It enables viewing multiple link shares indipendently from each in multiple tabs other without overriding any other open ones.
* @param token
* @param persist
*/
export const saveToken = (token: string, persist: boolean) => {
savedToken = token
@ -18,7 +16,6 @@ export const saveToken = (token: string, persist: boolean) => {
/**
* Returns a saved token. If there is one saved in memory it will use that before anything else.
* @returns {string|null}
*/
export const getToken = (): string | null => {
if (savedToken !== null) {
@ -39,16 +36,11 @@ export const removeToken = () => {
/**
* Refreshes an auth token while ensuring it is updated everywhere.
* @returns {Promise<AxiosResponse<any>>}
*/
export async function refreshToken(persist: boolean): Promise<AxiosResponse> {
const HTTP = HTTPFactory()
const HTTP = AuthenticatedHTTPFactory()
try {
const response = await HTTP.post('user/token', null, {
headers: {
Authorization: `Bearer ${getToken()}`,
},
})
const response = await HTTP.post('user/token')
saveToken(response.data.token, persist)
return response

View File

@ -0,0 +1,31 @@
import {decode} from 'blurhash'
export async function getBlobFromBlurHash(blurHash: string): Promise<Blob | null> {
if (blurHash === '') {
return null
}
const pixels = decode(blurHash, 32, 32)
const canvas = document.createElement('canvas')
canvas.width = 32
canvas.height = 32
const ctx = canvas.getContext('2d')
if (ctx === null) {
return null
}
const imageData = ctx.createImageData(32, 32)
imageData.data.set(pixels)
ctx.putImageData(imageData, 0, 0)
return new Promise<Blob>((resolve, reject) => {
canvas.toBlob(b => {
if (b === null) {
reject(b)
return
}
resolve(b)
})
})
}

View File

@ -3,11 +3,15 @@ import popSoundFile from '@/assets/audio/pop.mp3'
export const playSoundWhenDoneKey = 'playSoundWhenTaskDone'
export function playPop() {
const enabled = Boolean(localStorage.getItem(playSoundWhenDoneKey))
if(!enabled) {
const enabled = localStorage.getItem(playSoundWhenDoneKey) === 'true'
if (!enabled) {
return
}
playPopSound()
}
export function playPopSound() {
const popSound = new Audio(popSoundFile)
popSound.play()
}
}

View File

@ -0,0 +1,3 @@
export function getNextWeekDate(): Date {
return new Date((new Date()).getTime() + 7 * 24 * 60 * 60 * 1000)
}

View File

@ -0,0 +1,12 @@
export function parseDateOrString(rawValue: string | undefined, fallback: any): string | Date {
if (typeof rawValue === 'undefined') {
return fallback
}
const d = new Date(rawValue)
// @ts-ignore if rawValue is an invalid date, isNan will return false.
return !isNaN(d)
? d
: rawValue
}

View File

@ -335,6 +335,7 @@
"archiveText": "Nebudete moci upravovat tento jmenný prostor ani vytvářet nové seznamy, dokud jej neodarchivujete. Všechny seznamy v tomto prostoru budou také archivovány.",
"unarchiveText": "Budete moci vytvářet nové úkoly nebo je upravovat.",
"success": "Prostor byl úspěšně archivován.",
"unarchiveSuccess": "The namespace was successfully un-archived.",
"description": "Pokud je prostor archivován, nelze vytvořit nové seznamy nebo je upravit."
},
"delete": {
@ -384,7 +385,7 @@
"showDoneTasks": "Zobrazit dokončené úkoly",
"sortAlphabetically": "Řadit podle abecedy",
"enablePriority": "Povolit filtrování podle priority",
"enablePercentDone": "Povolit filtrování dle dokončenosti",
"enablePercentDone": "Enable Filter By Progress",
"dueDateRange": "Rozsah termínu",
"startDateRange": "Začátek období",
"endDateRange": "Konec období",
@ -484,7 +485,8 @@
"showMenu": "Zobrazit nabídku",
"hideMenu": "Skrýt nabídku",
"forExample": "Například:",
"welcomeBack": "Vítejte zpět!"
"welcomeBack": "Vítejte zpět!",
"custom": "Custom"
},
"input": {
"resetColor": "Obnovit barvu",
@ -523,6 +525,57 @@
"multiselect": {
"createPlaceholder": "Vytvořit nový",
"selectPlaceholder": "Kliknutím nebo stisknutím klávesy Enter vyberte"
},
"datepickerRange": {
"to": "To",
"from": "From",
"fromto": "{from} to {to}",
"ranges": {
"today": "Today",
"thisWeek": "This Week",
"restOfThisWeek": "The Rest of This Week",
"nextWeek": "Next Week",
"next7Days": "Next 7 Days",
"lastWeek": "Last Week",
"thisMonth": "This Month",
"restOfThisMonth": "The Rest of This Month",
"nextMonth": "Next Month",
"next30Days": "Next 30 Days",
"lastMonth": "Last Month",
"thisYear": "This Year",
"restOfThisYear": "The Rest of This Year"
}
},
"datemathHelp": {
"canuse": "You can use date math to filter for relative dates.",
"learnhow": "Check out how it works",
"title": "Date Math",
"intro": "Date Math allows you to specifiy relative dates which are resolved on the fly by Vikunja when applying the filter.",
"expression": "Each Date Math expression starts with an anchor date, which can either be {0}, or a date string ending with {1}. This anchor date can optionally be followed by one or more maths expressions.",
"similar": "These expressions are similar to the ones provided by {0} and {1}.",
"add1Day": "Add one day",
"minus1Day": "Subtract one day",
"roundDay": "Round down to the nearest day",
"supportedUnits": "Supported time units are:",
"someExamples": "Some examples of time expressions:",
"units": {
"seconds": "Seconds",
"minutes": "Minutes",
"hours": "Hours",
"days": "Days",
"weeks": "Weeks",
"months": "Months",
"years": "Years"
},
"examples": {
"now": "Right now",
"in24h": "In 24h",
"today": "Today at 00:00",
"beginningOfThisWeek": "The beginning of this week at 00:00",
"endOfThisWeek": "The end of this week",
"in30Days": "In 30 days",
"datePlusMonth": "{0} plus one month at 00:00 of that day"
}
}
},
"task": {
@ -540,12 +593,9 @@
"titleCurrent": "Aktuální úkoly",
"titleDates": "Úkoly od {from} do {to}",
"noDates": "Zobrazit úkoly bez datumu",
"current": "Aktuální úkoly",
"from": "Úkoly od",
"until": "do",
"today": "Dnes",
"nextWeek": "Příští týden",
"nextMonth": "Příští měsíc",
"overdue": "Show overdue tasks",
"fromuntil": "Tasks from {from} until {until}",
"select": "Select a date range",
"noTasks": "Nic na práci - užij si pěkný den!"
},
"detail": {
@ -569,22 +619,22 @@
"text2": "Tímto také odstraníte všechny přílohy, připomenutí a vztahy spojené s tímto úkolem a nelze je vrátit zpět!"
},
"actions": {
"assign": "Přiřadit uživateli",
"label": "Přidat štítky",
"assign": "Assign to User",
"label": "Add Labels",
"priority": "Nastavit prioritu",
"dueDate": "Nastavit termín",
"startDate": "Nastavit počáteční datum",
"endDate": "Nastavit koncové datum",
"startDate": "Set Start Date",
"endDate": "Set End Date",
"reminders": "Nastavit připomenutí",
"repeatAfter": "Nastavit interval opakování",
"percentDone": "Nastavit procenta dokončeno",
"attachments": "Přidat přílohy",
"relatedTasks": "Přidat vztahy úkolu",
"moveList": "Přesunout úkol",
"color": "Nastavit barvu úkolu",
"delete": "Smazat úkol",
"favorite": "Uložit jako oblíbené",
"unfavorite": "Odebrat z oblíbených"
"repeatAfter": "Set Repeating Interval",
"percentDone": "Set Progress",
"attachments": "Add Attachments",
"relatedTasks": "Add Relation",
"moveList": "Move",
"color": "Set Color",
"delete": "Delete",
"favorite": "Add to Favorites",
"unfavorite": "Remove from Favorites"
}
},
"attributes": {
@ -597,7 +647,7 @@
"dueDate": "Termín",
"endDate": "Datum ukončení",
"labels": "Štítky",
"percentDone": "% Hotovo",
"percentDone": "Progress",
"priority": "Priorita",
"relatedTasks": "Související úkoly",
"reminders": "Připomínky",
@ -784,17 +834,20 @@
"general": "Obecné",
"allPages": "Tyto zkratky fungují na všech stránkách.",
"currentPageOnly": "Tyto zkratky fungují pouze na aktuální stránce.",
"somePagesOnly": "These shortcuts work only on some pages.",
"toggleMenu": "Přepnout nabídku",
"quickSearch": "Otevřít vyhledávání / panel rychlých akcí",
"then": "potom",
"task": {
"title": "Stránka úkolů",
"done": "Hotovo",
"assign": "Přiřadit uživateli",
"done": "Mark task done / undone",
"assign": "Assign this task to a user",
"labels": "Přidat štítky k tomuto úkolu",
"dueDate": "Změnit termín tohoto úkolu",
"attachment": "Přidat přílohu k tomuto úkolu",
"related": "Upravit související úkoly tohoto úkolu"
"related": "Upravit související úkoly tohoto úkolu",
"color": "Change the color of this task",
"move": "Move this task to another list"
},
"list": {
"title": "Zobrazení seznamů",
@ -802,6 +855,14 @@
"switchToGanttView": "Přepnout na zobrazení gantt",
"switchToKanbanView": "Přepnout na zobrazení kanbanu",
"switchToTableView": "Přepnout na zobrazení tabulky"
},
"navigation": {
"title": "Navigation",
"overview": "Navigato to overview",
"upcoming": "Navigato to upcoming taks",
"namespaces": "Navigate to namepaces & lists",
"labels": "Navigate to labels",
"teams": "Navigate to teams"
}
},
"update": {

View File

@ -57,7 +57,7 @@
"hidePassword": "Passwort verbergen",
"noAccountYet": "Noch kein Account?",
"alreadyHaveAnAccount": "Hast du bereits einen Account?",
"remember": "Stay logged in"
"remember": "Angemeldet bleiben"
},
"settings": {
"title": "Einstellungen",
@ -86,7 +86,7 @@
"weekStartMonday": "Montag",
"language": "Sprache",
"defaultList": "Standard-Liste",
"timezone": "Time Zone"
"timezone": "Zeitzone"
},
"totp": {
"title": "Zwei-Faktor-Authentifizierung",
@ -335,7 +335,7 @@
"archiveText": "Du kannst diesen Namespace nicht mehr bearbeiten oder neue Listen erstellen, bis du die Archivierung rückgängig machst. Das gilt auch für alle Listen in diesem Namespace.",
"unarchiveText": "Du kannst neue Aufgaben erstellen oder diese bearbeiten.",
"success": "Der Namespace wurde erfolgreich archiviert.",
"unarchiveSuccess": "The namespace was successfully un-archived.",
"unarchiveSuccess": "Der Namespace wurde erfolgreich wiederhergestellt.",
"description": "In einem archivierten Namespace können Listen weder angelegt noch editiert werden."
},
"delete": {
@ -385,7 +385,7 @@
"showDoneTasks": "Erledigte Aufgaben anzeigen",
"sortAlphabetically": "Alphabetisch sortieren",
"enablePriority": "Filter nach Priorität aktivieren",
"enablePercentDone": "Filter nach % Erledigt aktivieren",
"enablePercentDone": "Filter nach Fortschritt aktivieren",
"dueDateRange": "Fälligkeitsbereich",
"startDateRange": "Startdatumsbereich",
"endDateRange": "Enddatumsbereich",
@ -485,7 +485,8 @@
"showMenu": "Menü anzeigen",
"hideMenu": "Menü ausblenden",
"forExample": "Zum Beispiel:",
"welcomeBack": "Willkommen zurück!"
"welcomeBack": "Willkommen zurück!",
"custom": "Benutzerdefiniert"
},
"input": {
"resetColor": "Farbe zurücksetzen",
@ -524,6 +525,57 @@
"multiselect": {
"createPlaceholder": "Neu erstellen",
"selectPlaceholder": "Klicken oder Enter drücken zum Auswählen"
},
"datepickerRange": {
"to": "Bis",
"from": "Von",
"fromto": "{from} bis {to}",
"ranges": {
"today": "Heute",
"thisWeek": "Diese Woche",
"restOfThisWeek": "Der Rest dieser Woche",
"nextWeek": "Nächste Woche",
"next7Days": "Nächsten 7 Tage",
"lastWeek": "Letzte Woche",
"thisMonth": "Dieser Monat",
"restOfThisMonth": "Der Rest dieses Monats",
"nextMonth": "Nächster Monat",
"next30Days": "Nächsten 30 Tage",
"lastMonth": "Letzter Monat",
"thisYear": "Dieses Jahr",
"restOfThisYear": "Der Rest des Jahres"
}
},
"datemathHelp": {
"canuse": "Du kannst Datumsberechnung verwenden, um nach relativen Daten zu filtern.",
"learnhow": "Sieh dir an, wie es funktioniert",
"title": "Datumsberechnung",
"intro": "Die Datumsberechnung erlaubt es, relative Daten anzugeben, die bei der Anwendung des Filters von Vikunja aufgelöst werden.",
"expression": "Jeder Ausdruck der Datumsberechnung beginnt mit einem Datumswert, welcher entweder {0} sein kann oder mit {1} endet. Auf diesen Datumswert kann optional ein oder mehrere mathematische Ausdrücke folgen.",
"similar": "Diese Ausdrücke ähneln denen von {0} und {1}.",
"add1Day": "Einen Tag hinzufügen",
"minus1Day": "Einen Tag abziehen",
"roundDay": "Auf den nächsten Tag abrunden",
"supportedUnits": "Unterstützte Zeiteinheiten sind:",
"someExamples": "Einige Beispiele für Zeitausdrücke:",
"units": {
"seconds": "Sekunden",
"minutes": "Minuten",
"hours": "Stunden",
"days": "Tage",
"weeks": "Wochen",
"months": "Monate",
"years": "Jahre"
},
"examples": {
"now": "Jetzt",
"in24h": "In 24 Stunden",
"today": "Heute um 00:00 Uhr",
"beginningOfThisWeek": "Der Anfang dieser Woche um 00:00 Uhr",
"endOfThisWeek": "Das Ende dieser Woche",
"in30Days": "In 30 Tagen",
"datePlusMonth": "{0} plus einen Monat um 00:00 des Tages"
}
}
},
"task": {
@ -541,12 +593,9 @@
"titleCurrent": "Aktuelle Aufgaben",
"titleDates": "Aufgaben von {from} bis {to}",
"noDates": "Aufgaben ohne Datum anzeigen",
"current": "Aktuelle Aufgaben",
"from": "Aufgaben von",
"until": "bis",
"today": "Heute",
"nextWeek": "Nächste Woche",
"nextMonth": "Nächster Monat",
"overdue": "Überfällige Aufgaben anzeigen",
"fromuntil": "Aufgaben von {from} bis {until}",
"select": "Datumsbereich wählen",
"noTasks": "Nichts zu tun Einen schönen Tag noch!"
},
"detail": {
@ -578,13 +627,13 @@
"endDate": "Enddatum setzen",
"reminders": "Erinnerungen setzen",
"repeatAfter": "Wiederholung setzen",
"percentDone": "Prozent erledigt setzen",
"percentDone": "Fortschritt einstellen",
"attachments": "Anhänge hinzufügen",
"relatedTasks": "Aufgabenbeziehungen hinzufügen",
"moveList": "Aufgabe verschieben",
"color": "Taskfarbe setzen",
"delete": "Aufgabe löschen",
"favorite": "In Favoriten speichern",
"relatedTasks": "Beziehung hinzufügen",
"moveList": "Verschieben",
"color": "Farbe setzen",
"delete": "Löschen",
"favorite": "Zu Favoriten hinzufügen",
"unfavorite": "Aus Favoriten entfernen"
}
},
@ -598,7 +647,7 @@
"dueDate": "Fälligkeitsdatum",
"endDate": "Enddatum",
"labels": "Labels",
"percentDone": "% erledigt",
"percentDone": "Fortschritt",
"priority": "Priorität",
"relatedTasks": "Verwandte Aufgaben",
"reminders": "Erinnerungen",
@ -785,17 +834,20 @@
"general": "Allgemein",
"allPages": "Diese Tastenkürzel funktionieren auf allen Seiten.",
"currentPageOnly": "Diese Tastenkürzel funktionieren nur auf der aktuellen Seite.",
"somePagesOnly": "Funktioniert nur auf manchen Seiten.",
"toggleMenu": "Das Menü umschalten",
"quickSearch": "Such-/Schnellaktionsleiste öffnen",
"then": "dann",
"task": {
"title": "Aufgabenseite",
"done": "Fertig",
"assign": "Benutzer:in zuweisen",
"done": "Aufgabe als erledigt / unerledigt markieren",
"assign": "Diese Aufgabe jemandem zuweisen",
"labels": "Dieser Aufgabe ein Label hinzufügen",
"dueDate": "Ändere das Fälligkeitsdatum dieser Aufgabe",
"attachment": "Einen Anhang dieser Aufgabe hinzufügen",
"related": "Ändere die Abhängigen Aufgaben dieser Aufgabe"
"related": "Ändere die Abhängigen Aufgaben dieser Aufgabe",
"color": "Die Farbe dieser Aufgabe ändern",
"move": "Diese Aufgabe in eine andere Liste verschieben"
},
"list": {
"title": "Listenansicht",
@ -803,6 +855,14 @@
"switchToGanttView": "Zur Ganttansicht wechseln",
"switchToKanbanView": "Zur Kanbanansicht wechseln",
"switchToTableView": "Zur Tabellenansicht wechseln"
},
"navigation": {
"title": "Navigation",
"overview": "Die Startseite aufrufen",
"upcoming": "Anstehende Aufgaben aufrufen",
"namespaces": "Namespaces & Listen aufrufen",
"labels": "Labels aufrufen",
"teams": "Teams aufrufen"
}
},
"update": {

View File

@ -57,7 +57,7 @@
"hidePassword": "Passwort verbergen",
"noAccountYet": "Noch kein Account?",
"alreadyHaveAnAccount": "Hast du bereits einen Account?",
"remember": "Stay logged in"
"remember": "Angemeldet bleiben"
},
"settings": {
"title": "Iihstellige",
@ -86,7 +86,7 @@
"weekStartMonday": "Määntig",
"language": "Sproch",
"defaultList": "Standard Liste",
"timezone": "Time Zone"
"timezone": "Zeitzone"
},
"totp": {
"title": "Zweifaktor Authentifizierig",
@ -103,9 +103,9 @@
"disableSuccess": "Zweifaktor Authentifizierig isch erfolgriich uusgschalte wore."
},
"caldav": {
"title": "Caldav",
"howTo": "Du chasch Vikunja zu Caldav Applikatione verbinde, um dini Uufgabe vo verschidene Gräät zgseh. Gib die Url i dim Client iih:",
"more": "Meh Informatione über Caldav in Vikunja"
"title": "CalDAV",
"howTo": "Du chasch Vikunja zu CalDAV Applikatione verbinde, um dini Uufgabe vo verschidene Gräät zgseh. Gib die Url i dim Client iih:",
"more": "Meh Informatione über CalDAV in Vikunja"
},
"avatar": {
"title": "Herr Der Elemente",
@ -335,7 +335,7 @@
"archiveText": "Du hesch kei möglichkeit meh de Namensruum z'bearbeite oder neui Listene drin z'erstelle, bis du si wider ent-archiviert hesch. Das archiviert au grad alli Liste im Namensruum.",
"unarchiveText": "Du chasch neui Liste erstelle oder bearbeite.",
"success": "De Namensruum isch erfolgriich archiviert worde.",
"unarchiveSuccess": "The namespace was successfully un-archived.",
"unarchiveSuccess": "Der Namespace wurde erfolgreich wiederhergestellt.",
"description": "Wenn en Namensruum archiviert isch, chasch du kei neui Liste erstelle oder die bearbeite."
},
"delete": {
@ -385,7 +385,7 @@
"showDoneTasks": "Zeig die fertige Uufgabe",
"sortAlphabetically": "Alphabetisch sortieren",
"enablePriority": "Filter nach Priorität aktiviere",
"enablePercentDone": "Filter nach Prozent iihschalte",
"enablePercentDone": "Filter nach Fortschritt aktivieren",
"dueDateRange": "Fälligkeitsberiich",
"startDateRange": "Startdatumsbreiich",
"endDateRange": "Enddatumsberiich",
@ -485,7 +485,8 @@
"showMenu": "Menü anzeigen",
"hideMenu": "Menü ausblenden",
"forExample": "Zum Beispiel:",
"welcomeBack": "Willkommen zurück!"
"welcomeBack": "Willkommen zurück!",
"custom": "Benutzerdefiniert"
},
"input": {
"resetColor": "Farb zruggsetze",
@ -524,6 +525,57 @@
"multiselect": {
"createPlaceholder": "Neu erstelle",
"selectPlaceholder": "Druck uf Enter zum uuswähle"
},
"datepickerRange": {
"to": "Bis",
"from": "Von",
"fromto": "{from} bis {to}",
"ranges": {
"today": "Heute",
"thisWeek": "Diese Woche",
"restOfThisWeek": "Der Rest dieser Woche",
"nextWeek": "Nächste Woche",
"next7Days": "Nächsten 7 Tage",
"lastWeek": "Letzte Woche",
"thisMonth": "Dieser Monat",
"restOfThisMonth": "Der Rest dieses Monats",
"nextMonth": "Nächster Monat",
"next30Days": "Nächsten 30 Tage",
"lastMonth": "Letzter Monat",
"thisYear": "Dieses Jahr",
"restOfThisYear": "Der Rest des Jahres"
}
},
"datemathHelp": {
"canuse": "Du kannst Datumsberechnung verwenden, um nach relativen Daten zu filtern.",
"learnhow": "Sieh dir an, wie es funktioniert",
"title": "Datumsberechnung",
"intro": "Die Datumsberechnung erlaubt es, relative Daten anzugeben, die bei der Anwendung des Filters von Vikunja aufgelöst werden.",
"expression": "Jeder Ausdruck der Datumsberechnung beginnt mit einem Datumswert, welcher entweder {0} sein kann oder mit {1} endet. Auf diesen Datumswert kann optional ein oder mehrere mathematische Ausdrücke folgen.",
"similar": "Diese Ausdrücke ähneln denen von {0} und {1}.",
"add1Day": "Einen Tag hinzufügen",
"minus1Day": "Einen Tag abziehen",
"roundDay": "Auf den nächsten Tag abrunden",
"supportedUnits": "Unterstützte Zeiteinheiten sind:",
"someExamples": "Einige Beispiele für Zeitausdrücke:",
"units": {
"seconds": "Sekunden",
"minutes": "Minuten",
"hours": "Stunden",
"days": "Tage",
"weeks": "Wochen",
"months": "Monate",
"years": "Jahre"
},
"examples": {
"now": "Jetzt",
"in24h": "In 24 Stunden",
"today": "Heute um 00:00 Uhr",
"beginningOfThisWeek": "Der Anfang dieser Woche um 00:00 Uhr",
"endOfThisWeek": "Das Ende dieser Woche",
"in30Days": "In 30 Tagen",
"datePlusMonth": "{0} plus einen Monat um 00:00 des Tages"
}
}
},
"task": {
@ -541,12 +593,9 @@
"titleCurrent": "Momentani Uufgabe",
"titleDates": "Uufgabe vo {from} bis {to}",
"noDates": "Zeig Uufgabe ohni Datum",
"current": "Momentani Uufgabe",
"from": "Uufgabe vo",
"until": "bis",
"today": "Hütt",
"nextWeek": "Negst Wuchä",
"nextMonth": "Negste Monet",
"overdue": "Überfällige Aufgaben anzeigen",
"fromuntil": "Aufgaben von {from} bis {until}",
"select": "Datumsbereich wählen",
"noTasks": "Nichts zu tun Einen schönen Tag noch!"
},
"detail": {
@ -571,20 +620,20 @@
},
"actions": {
"assign": "Benutzer:in zuweisen",
"label": "Label hinzueege",
"label": "Label hinzufügen",
"priority": "Priorität setzä",
"dueDate": "Fälligkeitsdatum setze",
"startDate": "Startdatum setze",
"endDate": "Enddatum setze",
"startDate": "Startdatum setzen",
"endDate": "Enddatum setzen",
"reminders": "Errinnerig iihstelle",
"repeatAfter": "En wiederholende Intervall setze",
"percentDone": "Prozentuelli Erledigung setze",
"attachments": "Aahang hinzuefüege",
"relatedTasks": "Uufgabsbeziehig hinzufüege",
"moveList": "Uufgab verschiebe",
"color": "Uufgab Farb setze",
"delete": "Uufgab chüble",
"favorite": "In Favoriten speichern",
"repeatAfter": "Wiederholung setzen",
"percentDone": "Fortschritt einstellen",
"attachments": "Anhänge hinzufügen",
"relatedTasks": "Beziehung hinzufügen",
"moveList": "Verschieben",
"color": "Farbe setzen",
"delete": "Löschen",
"favorite": "Zu Favoriten hinzufügen",
"unfavorite": "Aus Favoriten entfernen"
}
},
@ -598,7 +647,7 @@
"dueDate": "Fälligkeitsdatum",
"endDate": "Enddatum",
"labels": "Labels",
"percentDone": "% fertig",
"percentDone": "Fortschritt",
"priority": "Priorität",
"relatedTasks": "Verwandti Uufgabe",
"reminders": "Errinnerige",
@ -785,17 +834,20 @@
"general": "Allgemein",
"allPages": "Die Chürzl funktioniered uf allne Siitene.",
"currentPageOnly": "Die Chürzl funktioniered nur uf de momentane Siite.",
"somePagesOnly": "Funktioniert nur auf manchen Seiten.",
"toggleMenu": "Menü umschalte",
"quickSearch": "Suechi und Schnellaktionsliste öffne",
"then": "dann",
"task": {
"title": "Uufgabesiite",
"done": "Fertig",
"assign": "Benutzer:in zuweisen",
"done": "Aufgabe als erledigt / unerledigt markieren",
"assign": "Diese Aufgabe jemandem zuweisen",
"labels": "Labels ennere Uufgab hinzuefüege",
"dueDate": "S'Fälligkeitsdatum für die Uufgab ändere",
"attachment": "En Aahang dere Uufgab hinzuefüege",
"related": "Beziehige vo dere Uufgab bearbeite"
"related": "Beziehige vo dere Uufgab bearbeite",
"color": "Die Farbe dieser Aufgabe ändern",
"move": "Diese Aufgabe in eine andere Liste verschieben"
},
"list": {
"title": "Listenansicht",
@ -803,6 +855,14 @@
"switchToGanttView": "Zur Ganttansicht wechseln",
"switchToKanbanView": "Zur Kanbanansicht wechseln",
"switchToTableView": "Zur Tabellenansicht wechseln"
},
"navigation": {
"title": "Navigation",
"overview": "Die Startseite aufrufen",
"upcoming": "Anstehende Aufgaben aufrufen",
"namespaces": "Namespaces & Listen aufrufen",
"labels": "Labels aufrufen",
"teams": "Teams aufrufen"
}
},
"update": {

View File

@ -392,7 +392,7 @@
"showDoneTasks": "Show Done Tasks",
"sortAlphabetically": "Sort Alphabetically",
"enablePriority": "Enable Filter By Priority",
"enablePercentDone": "Enable Filter By Percent Done",
"enablePercentDone": "Enable Filter By Progress",
"dueDateRange": "Due Date Range",
"startDateRange": "Start Date Range",
"endDateRange": "End Date Range",
@ -493,6 +493,7 @@
"hideMenu": "Hide the menu",
"forExample": "For example:",
"welcomeBack": "Welcome Back!",
"custom": "Custom",
"id": "ID",
"created": "Created at",
"actions": "Actions"
@ -534,6 +535,60 @@
"multiselect": {
"createPlaceholder": "Create new",
"selectPlaceholder": "Click or press enter to select"
},
"datepickerRange": {
"to": "To",
"from": "From",
"fromto": "{from} to {to}",
"ranges": {
"today": "Today",
"thisWeek": "This Week",
"restOfThisWeek": "The Rest of This Week",
"nextWeek": "Next Week",
"next7Days": "Next 7 Days",
"lastWeek": "Last Week",
"thisMonth": "This Month",
"restOfThisMonth": "The Rest of This Month",
"nextMonth": "Next Month",
"next30Days": "Next 30 Days",
"lastMonth": "Last Month",
"thisYear": "This Year",
"restOfThisYear": "The Rest of This Year"
}
},
"datemathHelp": {
"canuse": "You can use date math to filter for relative dates.",
"learnhow": "Check out how it works",
"title": "Date Math",
"intro": "Date Math allows you to specifiy relative dates which are resolved on the fly by Vikunja when applying the filter.",
"expression": "Each Date Math expression starts with an anchor date, which can either be {0}, or a date string ending with {1}. This anchor date can optionally be followed by one or more maths expressions.",
"similar": "These expressions are similar to the ones provided by {0} and {1}.",
"add1Day": "Add one day",
"minus1Day": "Subtract one day",
"roundDay": "Round down to the nearest day",
"supportedUnits": "Supported time units are:",
"someExamples": "Some examples of time expressions:",
"units": {
"seconds": "Seconds",
"minutes": "Minutes",
"hours": "Hours",
"days": "Days",
"weeks": "Weeks",
"months": "Months",
"years": "Years"
},
"examples": {
"now": "Right now",
"in24h": "In 24h",
"today": "Today at 00:00",
"beginningOfThisWeek": "The beginning of this week at 00:00",
"endOfThisWeek": "The end of this week",
"in30Days": "In 30 days",
"datePlusMonth": "{0} plus one month at 00:00 of that day"
}
}
},
"task": {
@ -551,12 +606,9 @@
"titleCurrent": "Current Tasks",
"titleDates": "Tasks from {from} until {to}",
"noDates": "Show tasks without dates",
"current": "Current tasks",
"from": "Tasks from",
"until": "until",
"today": "Today",
"nextWeek": "Next Week",
"nextMonth": "Next Month",
"overdue": "Show overdue tasks",
"fromuntil": "Tasks from {from} until {until}",
"select": "Select a date range",
"noTasks": "Nothing to do — Have a nice day!"
},
"detail": {
@ -580,22 +632,22 @@
"text2": "This will also remove all attachments, reminders and relations associated with this task and cannot be undone!"
},
"actions": {
"assign": "Assign to a user",
"label": "Add labels",
"assign": "Assign to User",
"label": "Add Labels",
"priority": "Set Priority",
"dueDate": "Set Due Date",
"startDate": "Set a Start Date",
"endDate": "Set an End Date",
"startDate": "Set Start Date",
"endDate": "Set End Date",
"reminders": "Set Reminders",
"repeatAfter": "Set a repeating interval",
"percentDone": "Set Percent Done",
"attachments": "Add attachments",
"relatedTasks": "Add task relations",
"moveList": "Move task",
"color": "Set task color",
"delete": "Delete task",
"favorite": "Save as favorite",
"unfavorite": "Remove from favorites"
"repeatAfter": "Set Repeating Interval",
"percentDone": "Set Progress",
"attachments": "Add Attachments",
"relatedTasks": "Add Relation",
"moveList": "Move",
"color": "Set Color",
"delete": "Delete",
"favorite": "Add to Favorites",
"unfavorite": "Remove from Favorites"
}
},
"attributes": {
@ -608,7 +660,7 @@
"dueDate": "Due Date",
"endDate": "End Date",
"labels": "Labels",
"percentDone": "% Done",
"percentDone": "Progress",
"priority": "Priority",
"relatedTasks": "Related Tasks",
"reminders": "Reminders",
@ -695,6 +747,7 @@
"deleteText1": "Are you sure you want to delete this task relation?",
"deleteText2": "This cannot be undone!",
"select": "Select a relation kind",
"taskRequired": "Please select a task or enter a new task title.",
"kinds": {
"subtask": "Subtask | Subtasks",
"parenttask": "Parent Task | Parent Tasks",
@ -795,17 +848,20 @@
"general": "General",
"allPages": "These shortcuts work on all pages.",
"currentPageOnly": "These shortcuts work only on the current page.",
"somePagesOnly": "These shortcuts work only on some pages.",
"toggleMenu": "Toggle The Menu",
"quickSearch": "Open the search/quick action bar",
"then": "then",
"task": {
"title": "Task Page",
"done": "Done",
"assign": "Assign to a user",
"done": "Mark task done / undone",
"assign": "Assign this task to a user",
"labels": "Add labels to this task",
"dueDate": "Change the due date of this task",
"attachment": "Add an attachment to this task",
"related": "Modify related tasks of this task"
"related": "Modify related tasks of this task",
"color": "Change the color of this task",
"move": "Move this task to another list"
},
"list": {
"title": "List Views",
@ -813,6 +869,14 @@
"switchToGanttView": "Switch to gantt view",
"switchToKanbanView": "Switch to kanban view",
"switchToTableView": "Switch to table view"
},
"navigation": {
"title": "Navigation",
"overview": "Navigato to overview",
"upcoming": "Navigato to upcoming taks",
"namespaces": "Navigate to namepaces & lists",
"labels": "Navigate to labels",
"teams": "Navigate to teams"
}
},
"update": {

View File

@ -385,7 +385,7 @@
"showDoneTasks": "Show Done Tasks",
"sortAlphabetically": "Sort Alphabetically",
"enablePriority": "Enable Filter By Priority",
"enablePercentDone": "Enable Filter By Percent Done",
"enablePercentDone": "Enable Filter By Progress",
"dueDateRange": "Due Date Range",
"startDateRange": "Start Date Range",
"endDateRange": "End Date Range",
@ -485,7 +485,8 @@
"showMenu": "Show the menu",
"hideMenu": "Hide the menu",
"forExample": "For example:",
"welcomeBack": "Welcome Back!"
"welcomeBack": "Welcome Back!",
"custom": "Custom"
},
"input": {
"resetColor": "Reset Color",
@ -524,6 +525,57 @@
"multiselect": {
"createPlaceholder": "Create new",
"selectPlaceholder": "Click or press enter to select"
},
"datepickerRange": {
"to": "To",
"from": "From",
"fromto": "{from} to {to}",
"ranges": {
"today": "Today",
"thisWeek": "This Week",
"restOfThisWeek": "The Rest of This Week",
"nextWeek": "Next Week",
"next7Days": "Next 7 Days",
"lastWeek": "Last Week",
"thisMonth": "This Month",
"restOfThisMonth": "The Rest of This Month",
"nextMonth": "Next Month",
"next30Days": "Next 30 Days",
"lastMonth": "Last Month",
"thisYear": "This Year",
"restOfThisYear": "The Rest of This Year"
}
},
"datemathHelp": {
"canuse": "You can use date math to filter for relative dates.",
"learnhow": "Check out how it works",
"title": "Date Math",
"intro": "Date Math allows you to specifiy relative dates which are resolved on the fly by Vikunja when applying the filter.",
"expression": "Each Date Math expression starts with an anchor date, which can either be {0}, or a date string ending with {1}. This anchor date can optionally be followed by one or more maths expressions.",
"similar": "These expressions are similar to the ones provided by {0} and {1}.",
"add1Day": "Add one day",
"minus1Day": "Subtract one day",
"roundDay": "Round down to the nearest day",
"supportedUnits": "Supported time units are:",
"someExamples": "Some examples of time expressions:",
"units": {
"seconds": "Seconds",
"minutes": "Minutes",
"hours": "Hours",
"days": "Days",
"weeks": "Weeks",
"months": "Months",
"years": "Years"
},
"examples": {
"now": "Right now",
"in24h": "In 24h",
"today": "Today at 00:00",
"beginningOfThisWeek": "The beginning of this week at 00:00",
"endOfThisWeek": "The end of this week",
"in30Days": "In 30 days",
"datePlusMonth": "{0} plus one month at 00:00 of that day"
}
}
},
"task": {
@ -541,12 +593,9 @@
"titleCurrent": "Current Tasks",
"titleDates": "Tasks from {from} until {to}",
"noDates": "Show tasks without dates",
"current": "Current tasks",
"from": "Tasks from",
"until": "until",
"today": "Today",
"nextWeek": "Next Week",
"nextMonth": "Next Month",
"overdue": "Show overdue tasks",
"fromuntil": "Tasks from {from} until {until}",
"select": "Select a date range",
"noTasks": "Nothing to do — Have a nice day!"
},
"detail": {
@ -570,22 +619,22 @@
"text2": "This will also remove all attachments, reminders and relations associated with this task and cannot be undone!"
},
"actions": {
"assign": "Assign to a user",
"label": "Add labels",
"assign": "Assign to User",
"label": "Add Labels",
"priority": "Set Priority",
"dueDate": "Set Due Date",
"startDate": "Set a Start Date",
"endDate": "Set an End Date",
"startDate": "Set Start Date",
"endDate": "Set End Date",
"reminders": "Set Reminders",
"repeatAfter": "Set a repeating interval",
"percentDone": "Set Percent Done",
"attachments": "Add attachments",
"relatedTasks": "Add task relations",
"moveList": "Move task",
"color": "Set task color",
"delete": "Delete task",
"favorite": "Save as favorite",
"unfavorite": "Remove from favorites"
"repeatAfter": "Set Repeating Interval",
"percentDone": "Set Progress",
"attachments": "Add Attachments",
"relatedTasks": "Add Relation",
"moveList": "Move",
"color": "Set Color",
"delete": "Delete",
"favorite": "Add to Favorites",
"unfavorite": "Remove from Favorites"
}
},
"attributes": {
@ -598,7 +647,7 @@
"dueDate": "Due Date",
"endDate": "End Date",
"labels": "Labels",
"percentDone": "% Done",
"percentDone": "Progress",
"priority": "Priority",
"relatedTasks": "Related Tasks",
"reminders": "Reminders",
@ -785,17 +834,20 @@
"general": "General",
"allPages": "These shortcuts work on all pages.",
"currentPageOnly": "These shortcuts work only on the current page.",
"somePagesOnly": "These shortcuts work only on some pages.",
"toggleMenu": "Toggle The Menu",
"quickSearch": "Open the search/quick action bar",
"then": "then",
"task": {
"title": "Task Page",
"done": "Done",
"assign": "Assign to a user",
"done": "Mark task done / undone",
"assign": "Assign this task to a user",
"labels": "Add labels to this task",
"dueDate": "Change the due date of this task",
"attachment": "Add an attachment to this task",
"related": "Modify related tasks of this task"
"related": "Modify related tasks of this task",
"color": "Change the color of this task",
"move": "Move this task to another list"
},
"list": {
"title": "List Views",
@ -803,6 +855,14 @@
"switchToGanttView": "Switch to gantt view",
"switchToKanbanView": "Switch to kanban view",
"switchToTableView": "Switch to table view"
},
"navigation": {
"title": "Navigation",
"overview": "Navigato to overview",
"upcoming": "Navigato to upcoming taks",
"namespaces": "Navigate to namepaces & lists",
"labels": "Navigate to labels",
"teams": "Navigate to teams"
}
},
"update": {

View File

@ -7,7 +7,7 @@
"lastViewed": "Dernière consultation",
"list": {
"newText": "Tu peux créer une nouvelle liste pour tes nouvelles tâches :",
"new": "New list",
"new": "Nouvelle liste",
"importText": "Ou importe tes listes et tâches dautres services dans Vikunja :",
"import": "Importer tes données dans Vikunja"
}
@ -31,11 +31,11 @@
"username": "Nom dutilisateur·rice",
"usernameEmail": "Nom dutilisateur·rice ou adresse courriel",
"usernamePlaceholder": "p. ex. frederick",
"email": "Email address",
"email": "Adresse courriel",
"emailPlaceholder": "p. ex. frederic{'@'}vikunja.io",
"password": "Mot de passe",
"passwordPlaceholder": "p. ex. •••••••••••",
"forgotPassword": "Forgot your password?",
"forgotPassword": "Mot de passe oublié ?",
"resetPassword": "Réinitialiser ton mot de passe",
"resetPasswordAction": "Menvoyer un lien de réinitialisation du mot de passe",
"resetPasswordSuccess": "Vérifie ta boîte de réception ! Tu devrais avoir un courriel contenant les instructions sur la manière de réinitialiser ton mot de passe.",
@ -44,20 +44,20 @@
"totpTitle": "Code dauthentification à deux facteurs",
"totpPlaceholder": "p. ex. 123456",
"login": "Se connecter",
"createAccount": "Create account",
"createAccount": "Créer un compte",
"loginWith": "Se connecter avec {provider}",
"authenticating": "Authentification…",
"openIdStateError": "Létat ne correspond pas, impossible de continuer !",
"openIdGeneralError": "Une erreur s'est produite lors de l'authentification contre un tiers.",
"logout": "Se déconnecter",
"emailInvalid": "Please enter a valid email address.",
"usernameRequired": "Please provide a username.",
"passwordRequired": "Please provide a password.",
"showPassword": "Show the password",
"hidePassword": "Hide the password",
"noAccountYet": "Don't have an account yet?",
"alreadyHaveAnAccount": "Already have an account?",
"remember": "Stay logged in"
"emailInvalid": "Veuillez saisir une adresse courriel valide.",
"usernameRequired": "Veuillez saisir un nom d'utilisateur.",
"passwordRequired": "Veuillez fournir un mot de passe.",
"showPassword": "Afficher le mot de passe",
"hidePassword": "Masquer le mot de passe",
"noAccountYet": "Vous n'avez pas encore de compte?",
"alreadyHaveAnAccount": "Vous avez déjà un compte?",
"remember": "Rester connecté(e)"
},
"settings": {
"title": "Paramètres",
@ -68,7 +68,7 @@
"currentPasswordPlaceholder": "Ton mot de passe actuel",
"passwordsDontMatch": "Le nouveau mot de passe et sa confirmation ne correspondent pas.",
"passwordUpdateSuccess": "Mot de passe mis à jour.",
"updateEmailTitle": "Update Your Email Address",
"updateEmailTitle": "Mettre à jour votre adresse courriel",
"updateEmailNew": "Nouvelle adresse courriel",
"updateEmailSuccess": "Mise à jour de ladresse électronique. Clique sur le lien dans le courriel qui ta été envoyé pour le confirmer.",
"general": {
@ -86,7 +86,7 @@
"weekStartMonday": "lundi",
"language": "Langue",
"defaultList": "Liste par défaut",
"timezone": "Time Zone"
"timezone": "Fuseau horaire"
},
"totp": {
"title": "Authentification à deux facteurs",
@ -111,7 +111,7 @@
"title": "Avatar",
"initials": "Initiales",
"gravatar": "Gravatar",
"marble": "Marble",
"marble": "Bille",
"upload": "Téléverser",
"uploadAvatar": "Téléverser lavatar",
"statusUpdateSuccess": "Statut de lavatar mis à jour.",
@ -165,7 +165,7 @@
"searchSelect": "Clique ou appuie sur la touche Entrée pour sélectionner cette liste",
"shared": "Listes partagées",
"create": {
"header": "New list",
"header": "Nouvelle liste",
"titlePlaceholder": "Entre le nom de la liste…",
"addTitleRequired": "Indique un nom.",
"createdSuccess": "Liste créée.",
@ -323,7 +323,7 @@
"namespaces": "Espaces de noms",
"search": "Écris pour rechercher un espace de noms…",
"create": {
"title": "New namespace",
"title": "Nouvel espace de noms",
"titleRequired": "Indique un nom.",
"explanation": "Des collections de listes pour partager et organiser vos listes. En fait, chaque liste appartient à un espace de noms.",
"tooltip": "Quest-ce quun espace de noms ?",
@ -335,7 +335,7 @@
"archiveText": "Tu ne pourras pas modifier cet espace de noms ou créer de nouvelles listes tant que tu ne lauras pas désarchivé. Ceci archivera également toutes les listes de cet espace de noms.",
"unarchiveText": "Tu pourras créer de nouvelles listes ou les modifier.",
"success": "Espace de noms archivé.",
"unarchiveSuccess": "The namespace was successfully un-archived.",
"unarchiveSuccess": "Espace de noms archivé.",
"description": "Larchivage dun espace de noms signifie quon ne peut pas créer de nouvelles listes dans cet espace, ni le modifier."
},
"delete": {
@ -383,16 +383,16 @@
"includeNulls": "Inclure les tâches sans valeurs",
"requireAll": "Exiger tous les filtres pour quune tâche saffiche",
"showDoneTasks": "Afficher les tâches terminées",
"sortAlphabetically": "Sort Alphabetically",
"sortAlphabetically": "Trier par ordre alphabétique",
"enablePriority": "Activer le filtre par priorité",
"enablePercentDone": "Par % dachèvement",
"enablePercentDone": "Activer le filtre par progression",
"dueDateRange": "Plage de dates déchéance",
"startDateRange": "Plage de dates de début",
"endDateRange": "Plage de dates de fin",
"reminderRange": "Plage de dates de rappel"
},
"create": {
"title": "New Saved Filter",
"title": "Nouveau filtre enregistré",
"description": "Un filtre enregistré est une liste virtuelle qui est calculée à partir dun ensemble de filtres à chaque fois quon y accède. Une fois créé, il apparaît dans un espace de noms spécial.",
"action": "Créer un nouveau filtre enregistré"
},
@ -485,7 +485,8 @@
"showMenu": "Afficher le menu",
"hideMenu": "Masquer le menu",
"forExample": "Par exemple :",
"welcomeBack": "Welcome Back!"
"welcomeBack": "Heureux de vous revoir !",
"custom": "Custom"
},
"input": {
"resetColor": "Réinitialiser la couleur",
@ -524,6 +525,57 @@
"multiselect": {
"createPlaceholder": "Créer un nouveau",
"selectPlaceholder": "Clique ou appuie sur la touche Entrée pour sélectionner"
},
"datepickerRange": {
"to": "To",
"from": "From",
"fromto": "{from} to {to}",
"ranges": {
"today": "Today",
"thisWeek": "This Week",
"restOfThisWeek": "The Rest of This Week",
"nextWeek": "Next Week",
"next7Days": "Next 7 Days",
"lastWeek": "Last Week",
"thisMonth": "This Month",
"restOfThisMonth": "The Rest of This Month",
"nextMonth": "Next Month",
"next30Days": "Next 30 Days",
"lastMonth": "Last Month",
"thisYear": "This Year",
"restOfThisYear": "The Rest of This Year"
}
},
"datemathHelp": {
"canuse": "You can use date math to filter for relative dates.",
"learnhow": "Check out how it works",
"title": "Date Math",
"intro": "Date Math allows you to specifiy relative dates which are resolved on the fly by Vikunja when applying the filter.",
"expression": "Each Date Math expression starts with an anchor date, which can either be {0}, or a date string ending with {1}. This anchor date can optionally be followed by one or more maths expressions.",
"similar": "These expressions are similar to the ones provided by {0} and {1}.",
"add1Day": "Add one day",
"minus1Day": "Subtract one day",
"roundDay": "Round down to the nearest day",
"supportedUnits": "Supported time units are:",
"someExamples": "Some examples of time expressions:",
"units": {
"seconds": "Seconds",
"minutes": "Minutes",
"hours": "Hours",
"days": "Days",
"weeks": "Weeks",
"months": "Months",
"years": "Years"
},
"examples": {
"now": "Right now",
"in24h": "In 24h",
"today": "Today at 00:00",
"beginningOfThisWeek": "The beginning of this week at 00:00",
"endOfThisWeek": "The end of this week",
"in30Days": "In 30 days",
"datePlusMonth": "{0} plus one month at 00:00 of that day"
}
}
},
"task": {
@ -541,12 +593,9 @@
"titleCurrent": "Tâches actuelles",
"titleDates": "Tâches du {from} au {to}",
"noDates": "Afficher les tâches sans date",
"current": "Tâches actuelles",
"from": "Tâches du",
"until": "au",
"today": "Aujourdhui",
"nextWeek": "La semaine prochaine",
"nextMonth": "Le mois prochain",
"overdue": "Show overdue tasks",
"fromuntil": "Tasks from {from} until {until}",
"select": "Select a date range",
"noTasks": "Rien à faire — Passe une bonne journée !"
},
"detail": {
@ -554,7 +603,7 @@
"chooseStartDate": "Clique ici pour fixer une date de début",
"chooseEndDate": "Clique ici pour fixer une date de fin",
"move": "Déplacer une tâche vers une autre liste",
"done": "Mark task done!",
"done": "Marquer la tâche comme terminée !",
"undone": "Marquer comme inachevé",
"created": "Créé {0} par {1}",
"updated": "Mis à jour {0}",
@ -570,21 +619,21 @@
"text2": "Ceci supprimera également toutes les pièces jointes, les rappels et les relations associés à cette tâche et ne pourra pas être annulé !"
},
"actions": {
"assign": "Attribuer à un utilisateur",
"assign": "Assigner à l'utilisateur",
"label": "Ajouter des étiquettes",
"priority": "Définir la priorité",
"dueDate": "Définir léchéance",
"startDate": "Définir une date de début",
"endDate": "Fixer une date de fin",
"startDate": "Définir la date de début",
"endDate": "Définir la date de fin",
"reminders": "Définir des rappels",
"repeatAfter": "Définir un intervalle de répétition",
"percentDone": "Définir le pourcentage dachèvement",
"percentDone": "Définir la progression",
"attachments": "Ajouter des pièces jointes",
"relatedTasks": "Ajouter des relations de tâches",
"moveList": "Déplacer la tâche",
"color": "Définir la couleur de la tâche",
"delete": "Supprimer la tâche",
"favorite": "Enregistrer comme favori",
"relatedTasks": "Ajouter une relation",
"moveList": "Déplacer",
"color": "Définir la couleur",
"delete": "Supprimer",
"favorite": "Ajouter aux favoris",
"unfavorite": "Retirer des favoris"
}
},
@ -598,7 +647,7 @@
"dueDate": "Date déchéance",
"endDate": "Date de fin",
"labels": "Étiquettes",
"percentDone": "% terminé",
"percentDone": "Progression",
"priority": "Priorité",
"relatedTasks": "Tâches connexes",
"reminders": "Rappels",
@ -785,17 +834,20 @@
"general": "Général",
"allPages": "Fonctionne sur toutes les pages.",
"currentPageOnly": "Fonctionnent uniquement sur la page en cours.",
"somePagesOnly": "Ces raccourcis fonctionnent seulement sur certaines pages.",
"toggleMenu": "Basculer le menu",
"quickSearch": "Ouvrir la barre de recherche/action rapide",
"then": "puis",
"task": {
"title": "Page de tâche",
"done": "Done",
"assign": "Attribuer à un utilisateur",
"done": "Mark task done / undone",
"assign": "Assigner cette tâche à un utilisateur",
"labels": "Ajouter des étiquettes à cette tâche",
"dueDate": "Modifier la date déchéance de cette tâche",
"attachment": "Ajouter une pièce jointe à cette tâche",
"related": "Modifier les tâches connexes de cette tâche"
"related": "Modifier les tâches connexes de cette tâche",
"color": "Changer la couleur de cette tâche",
"move": "Déplacer cette tâche dans une autre liste"
},
"list": {
"title": "Vues en liste",
@ -803,6 +855,14 @@
"switchToGanttView": "Passer en vue Gantt",
"switchToKanbanView": "Passer en vue kanban",
"switchToTableView": "Passer en vue tableau"
},
"navigation": {
"title": "Navigation",
"overview": "Accéder à la vue d'ensemble",
"upcoming": "Accéder aux prochaines tâches",
"namespaces": "Accéder aux espaces de noms et listes",
"labels": "Accéder aux étiquettes",
"teams": "Accéder aux équipes"
}
},
"update": {
@ -823,7 +883,7 @@
"url": "URL Vikunja",
"urlPlaceholder": "Par exemple : https://localhost:3456",
"change": "changer",
"use": "Using Vikunja installation at {0}",
"use": "Utiliser linstallation de Vikunja à {0}",
"error": "Impossible de trouver ou d'utiliser l'installation de Vikunja sur « {domain} ». Veuillez essayer une autre URL.",
"success": "Utilisation de linstallation Vikunja à « {domain} ».",
"urlRequired": "Une URL est requise."
@ -908,7 +968,7 @@
"4015": "Le commentaire de la tâche nexiste pas.",
"4016": "Champ de tâche invalide.",
"4017": "Comparateur de filtre de tâche invalide.",
"4018": "Invalid task filter concatenator.",
"4018": "Concaténateur de filtre de tâche invalide.",
"4019": "Valeur de filtre de tâche invalide.",
"5001": "Lespace de noms nexiste pas.",
"5003": "Tu nas pas accès à lespace de noms indiqué.",

View File

@ -103,9 +103,9 @@
"disableSuccess": "L'autenticazione a due fattori è stata disattivata."
},
"caldav": {
"title": "CalDav",
"howTo": "Puoi connettere Vikunja ai client caldav per visualizzare e gestire tutte le attività da diversi client. Inserisci questo URL nel tuo client:",
"more": "Ulteriori informazioni su caldav in Vikunja"
"title": "CalDAV",
"howTo": "Puoi connettere Vikunja ai client CalDAV per visualizzare e gestire tutte le attività da diversi client. Inserisci questo URL nel tuo client:",
"more": "Ulteriori informazioni su CalDAV in Vikunja"
},
"avatar": {
"title": "Avatar",
@ -335,7 +335,7 @@
"archiveText": "Non sarà possibile modificare questo namespace o creare nuove liste fino a quando non verrà disarchiviato. Questo archivierà anche tutte le liste in questo namespace.",
"unarchiveText": "Potrai creare nuove liste o modificarle.",
"success": "Namespace creato.",
"unarchiveSuccess": "The namespace was successfully un-archived.",
"unarchiveSuccess": "Namespace estratto dall'archivio.",
"description": "Se un namespace è archiviato, non è possibile creare nuove liste o modificarlo."
},
"delete": {
@ -385,7 +385,7 @@
"showDoneTasks": "Mostra Attività Fatte",
"sortAlphabetically": "Ordine alfabetico",
"enablePriority": "Abilita Filtro Per Priorità",
"enablePercentDone": "Abilitare Filtro Per Percentuale Fatta",
"enablePercentDone": "Abilita Filtro Per Progresso",
"dueDateRange": "Intervallo Data Di Scadenza",
"startDateRange": "Intervallo Data Iniziale",
"endDateRange": "Intervallo Data Finale",
@ -485,7 +485,8 @@
"showMenu": "Mostra il menu",
"hideMenu": "Nascondi il menù",
"forExample": "Ad esempio:",
"welcomeBack": "Bentornato!"
"welcomeBack": "Bentornato!",
"custom": "Custom"
},
"input": {
"resetColor": "Ripristina Colore",
@ -524,6 +525,57 @@
"multiselect": {
"createPlaceholder": "Crea nuovo",
"selectPlaceholder": "Clicca o premere invio per selezionare"
},
"datepickerRange": {
"to": "To",
"from": "From",
"fromto": "{from} to {to}",
"ranges": {
"today": "Today",
"thisWeek": "This Week",
"restOfThisWeek": "The Rest of This Week",
"nextWeek": "Next Week",
"next7Days": "Next 7 Days",
"lastWeek": "Last Week",
"thisMonth": "This Month",
"restOfThisMonth": "The Rest of This Month",
"nextMonth": "Next Month",
"next30Days": "Next 30 Days",
"lastMonth": "Last Month",
"thisYear": "This Year",
"restOfThisYear": "The Rest of This Year"
}
},
"datemathHelp": {
"canuse": "You can use date math to filter for relative dates.",
"learnhow": "Check out how it works",
"title": "Date Math",
"intro": "Date Math allows you to specifiy relative dates which are resolved on the fly by Vikunja when applying the filter.",
"expression": "Each Date Math expression starts with an anchor date, which can either be {0}, or a date string ending with {1}. This anchor date can optionally be followed by one or more maths expressions.",
"similar": "These expressions are similar to the ones provided by {0} and {1}.",
"add1Day": "Add one day",
"minus1Day": "Subtract one day",
"roundDay": "Round down to the nearest day",
"supportedUnits": "Supported time units are:",
"someExamples": "Some examples of time expressions:",
"units": {
"seconds": "Seconds",
"minutes": "Minutes",
"hours": "Hours",
"days": "Days",
"weeks": "Weeks",
"months": "Months",
"years": "Years"
},
"examples": {
"now": "Right now",
"in24h": "In 24h",
"today": "Today at 00:00",
"beginningOfThisWeek": "The beginning of this week at 00:00",
"endOfThisWeek": "The end of this week",
"in30Days": "In 30 days",
"datePlusMonth": "{0} plus one month at 00:00 of that day"
}
}
},
"task": {
@ -541,12 +593,9 @@
"titleCurrent": "Attività Attuali",
"titleDates": "Attività dal {from} al {to}",
"noDates": "Mostra attività senza date",
"current": "Attività attuali",
"from": "Attività dal",
"until": "fino al",
"today": "Oggi",
"nextWeek": "Settimana Prossima",
"nextMonth": "Prossimo Mese",
"overdue": "Show overdue tasks",
"fromuntil": "Tasks from {from} until {until}",
"select": "Select a date range",
"noTasks": "Nessuna attività — Buona giornata!"
},
"detail": {
@ -570,22 +619,22 @@
"text2": "Questo rimuoverà anche tutti gli allegati, i promemoria e le relazioni associati a questa attività e non può essere ripristinato!"
},
"actions": {
"assign": "Assegna ad un utente",
"label": "Aggiungi etichette",
"assign": "Assegna all'Utente",
"label": "Aggiungi Etichette",
"priority": "Imposta Priorità",
"dueDate": "Imposta data di scadenza",
"startDate": "Imposta una data di inizio",
"endDate": "Imposta una data di fine",
"startDate": "Imposta Data Inizio",
"endDate": "Imposta Data Fine",
"reminders": "Imposta promemoria",
"repeatAfter": "Imposta ricorrenza",
"percentDone": "Imposta Percentuale Completata",
"attachments": "Aggiungi allegati",
"relatedTasks": "Aggiungi attività collegate",
"moveList": "Sposta attività",
"color": "Imposta colore attività",
"delete": "Elimina attività",
"favorite": "Salva come preferito",
"unfavorite": "Rimuovi dai preferiti"
"repeatAfter": "Imposta Intervallo Ripetizione",
"percentDone": "Imposta Progresso",
"attachments": "Aggiungi Allegati",
"relatedTasks": "Aggiungi Relazione",
"moveList": "Sposta",
"color": "Imposta Colore",
"delete": "Elimina",
"favorite": "Aggiungi ai Preferiti",
"unfavorite": "Rimuovi dai Preferiti"
}
},
"attributes": {
@ -598,7 +647,7 @@
"dueDate": "Data di scadenza",
"endDate": "Data di fine",
"labels": "Etichette",
"percentDone": "% Completata",
"percentDone": "Progresso",
"priority": "Priorità",
"relatedTasks": "Attività Collegate",
"reminders": "Promemoria",
@ -785,17 +834,20 @@
"general": "Generali",
"allPages": "Queste scorciatoie funzionano in tutte le pagine.",
"currentPageOnly": "Queste scorciatoie funzionano solo nella pagina attuale.",
"somePagesOnly": "These shortcuts work only on some pages.",
"toggleMenu": "Attiva/Disattiva Menu",
"quickSearch": "Apri la barra di ricerca/azione rapida",
"then": "e dopo",
"task": {
"title": "Pagina Attività",
"done": "Fatto",
"assign": "Assegna a un utente",
"done": "Mark task done / undone",
"assign": "Assign this task to a user",
"labels": "Aggiungi etichette a questa attività",
"dueDate": "Modifica la data di scadenza di questa attività",
"attachment": "Aggiungi un allegato a questa attività",
"related": "Modifica le attività collegate a questa"
"related": "Modifica le attività collegate a questa",
"color": "Change the color of this task",
"move": "Move this task to another list"
},
"list": {
"title": "Viste Liste",
@ -803,6 +855,14 @@
"switchToGanttView": "Passa alla vista Gantt",
"switchToKanbanView": "Passa alla vista Kanban",
"switchToTableView": "Passa alla vista Tabella"
},
"navigation": {
"title": "Navigation",
"overview": "Navigato to overview",
"upcoming": "Navigato to upcoming taks",
"namespaces": "Navigate to namepaces & lists",
"labels": "Navigate to labels",
"teams": "Navigate to teams"
}
},
"update": {

View File

@ -67,7 +67,7 @@
"currentPassword": "Huidig wachtwoord",
"currentPasswordPlaceholder": "Je huidige wachtwoord",
"passwordsDontMatch": "Het nieuwe wachtwoord en de bevestiging ervan komen niet overeen.",
"passwordUpdateSuccess": "Het wachtwoord is succesvol gewijzigd.",
"passwordUpdateSuccess": "Het wachtwoord is succesvol bijgewerkt.",
"updateEmailTitle": "Update Your Email Address",
"updateEmailNew": "Nieuw e-mailadres",
"updateEmailSuccess": "Je e-mailadres is succesvol bijgewerkt. We hebben je een link gestuurd om het te bevestigen.",
@ -91,15 +91,15 @@
"totp": {
"title": "Twee-factor-authenticatie",
"enroll": "Activeren",
"finishSetupPart1": "To finish your setup, use this secret in your totp app (Google Authenticator or similar):",
"finishSetupPart2": "After that, enter a code from your app below.",
"finishSetupPart1": "Gebruik dit geheim in je TOTP app (Google Authenticator of vergelijkbaar), om de installatie te voltooien:",
"finishSetupPart2": "Daarna voert u hieronder een code van je app in.",
"scanQR": "Als alternatief kan je ook deze QR code scannen:",
"passcode": "Je toegangscode",
"passcodePlaceholder": "A code generated by your totp application",
"passcodePlaceholder": "Een code gegenereerd door uw TOTP app",
"setupSuccess": "Je hebt met succes tweestapsverificatie ingesteld!",
"enterPassword": "Voer alsjeblieft je wachtwoord in",
"disable": "Tweestapsverificatie uitschakelen",
"confirmSuccess": "You've successfully confirmed your totp setup and can use it from now on!",
"confirmSuccess": "Je hebt met succes je TOTP setup bevestigd en kan het van nu af aan gebruiken!",
"disableSuccess": "Authenticatie in twee stappen is succesvol uitgeschakeld."
},
"caldav": {
@ -118,7 +118,7 @@
"setSuccess": "De avatar is succesvol ingesteld!"
},
"quickAddMagic": {
"title": "Quick Add Magic Mode",
"title": "Magische Modus Snel Toevoegen",
"disabled": "Uitgeschakeld",
"todoist": "Todoist",
"vikunja": "Vikunja"
@ -136,7 +136,7 @@
"deletion": {
"title": "Verwijder je Vikunja account",
"text1": "Het verwijderen van je account is permanent en kan niet ongedaan worden gemaakt. We zullen al je namespaces, lijsten, taken en alles wat ermee verbonden is verwijderen.",
"text2": "To proceed, please enter your password. You will receive an email with further instructions.",
"text2": "Graag je wachtwoord invullen om verder te gaan. Je zult een e-mail ontvangen met verdere instructies.",
"confirm": "Verwijder mijn account",
"requestSuccess": "Het verzoek was succesvol. Je ontvangt een e-mail met verdere instructies.",
"passwordRequired": "Voer alsjeblieft je wachtwoord in.",
@ -335,6 +335,7 @@
"archiveText": "You won't be able to edit this namespace or create new lists until you un-archive it. This will also archive all lists in this namespace.",
"unarchiveText": "Je kan nieuwe lijsten maken of deze bewerken.",
"success": "The namespace was successfully archived.",
"unarchiveSuccess": "The namespace was successfully un-archived.",
"description": "If a namespace is archived, you cannot create new lists or edit it."
},
"delete": {
@ -384,7 +385,7 @@
"showDoneTasks": "Show Done Tasks",
"sortAlphabetically": "Alfabetisch sorteren",
"enablePriority": "Enable Filter By Priority",
"enablePercentDone": "Enable Filter By Percent Done",
"enablePercentDone": "Enable Filter By Progress",
"dueDateRange": "Due Date Range",
"startDateRange": "Start Date Range",
"endDateRange": "End Date Range",
@ -484,7 +485,8 @@
"showMenu": "Menu weergeven",
"hideMenu": "Menu verbergen",
"forExample": "Bijvoorbeeld:",
"welcomeBack": "Welkom terug!"
"welcomeBack": "Welkom terug!",
"custom": "Custom"
},
"input": {
"resetColor": "Kleur resetten",
@ -499,7 +501,7 @@
},
"editor": {
"edit": "Bewerken",
"done": "Gereed",
"done": "Voltooid",
"heading1": "Kop 1",
"heading2": "Kop 2",
"heading3": "Kop 3",
@ -523,6 +525,57 @@
"multiselect": {
"createPlaceholder": "Nieuwe aanmaken",
"selectPlaceholder": "Klik of druk op enter om te selecteren"
},
"datepickerRange": {
"to": "To",
"from": "From",
"fromto": "{from} to {to}",
"ranges": {
"today": "Today",
"thisWeek": "This Week",
"restOfThisWeek": "The Rest of This Week",
"nextWeek": "Next Week",
"next7Days": "Next 7 Days",
"lastWeek": "Last Week",
"thisMonth": "This Month",
"restOfThisMonth": "The Rest of This Month",
"nextMonth": "Next Month",
"next30Days": "Next 30 Days",
"lastMonth": "Last Month",
"thisYear": "This Year",
"restOfThisYear": "The Rest of This Year"
}
},
"datemathHelp": {
"canuse": "You can use date math to filter for relative dates.",
"learnhow": "Check out how it works",
"title": "Date Math",
"intro": "Date Math allows you to specifiy relative dates which are resolved on the fly by Vikunja when applying the filter.",
"expression": "Each Date Math expression starts with an anchor date, which can either be {0}, or a date string ending with {1}. This anchor date can optionally be followed by one or more maths expressions.",
"similar": "These expressions are similar to the ones provided by {0} and {1}.",
"add1Day": "Add one day",
"minus1Day": "Subtract one day",
"roundDay": "Round down to the nearest day",
"supportedUnits": "Supported time units are:",
"someExamples": "Some examples of time expressions:",
"units": {
"seconds": "Seconds",
"minutes": "Minutes",
"hours": "Hours",
"days": "Days",
"weeks": "Weeks",
"months": "Months",
"years": "Years"
},
"examples": {
"now": "Right now",
"in24h": "In 24h",
"today": "Today at 00:00",
"beginningOfThisWeek": "The beginning of this week at 00:00",
"endOfThisWeek": "The end of this week",
"in30Days": "In 30 days",
"datePlusMonth": "{0} plus one month at 00:00 of that day"
}
}
},
"task": {
@ -540,12 +593,9 @@
"titleCurrent": "Huidige taken",
"titleDates": "Tasks from {from} until {to}",
"noDates": "Taken zonder datums tonen",
"current": "Huidige taken",
"from": "Taken van",
"until": "tot",
"today": "Vandaag",
"nextWeek": "Volgende week",
"nextMonth": "Volgende maand",
"overdue": "Show overdue tasks",
"fromuntil": "Tasks from {from} until {until}",
"select": "Select a date range",
"noTasks": "Nothing to do — Have a nice day!"
},
"detail": {
@ -554,7 +604,7 @@
"chooseEndDate": "Klik hier om een einddatum in te stellen",
"move": "Verplaats taak naar een andere lijst",
"done": "Mark task done!",
"undone": "Markeer als niet gereed",
"undone": "Markeer als niet voltooid",
"created": "Created {0} by {1}",
"updated": "Updated {0}",
"doneAt": "Done {0}",
@ -569,22 +619,22 @@
"text2": "This will also remove all attachments, reminders and relations associated with this task and cannot be undone!"
},
"actions": {
"assign": "Toewijzen aan een gebruiker",
"label": "Labels toevoegen",
"assign": "Assign to User",
"label": "Add Labels",
"priority": "Prioriteit instellen",
"dueDate": "Vervaldatum instellen",
"startDate": "Startdatum instellen",
"endDate": "Einddatum instellen",
"startDate": "Set Start Date",
"endDate": "Set End Date",
"reminders": "Herinneringen instellen",
"repeatAfter": "Herhalingsinterval instellen",
"percentDone": "Percentage gereed instellen",
"attachments": "Bijlage toevoegen",
"relatedTasks": "Taakrelaties toevoegen",
"moveList": "Taak verplaatsen",
"color": "Taakkleur instellen",
"delete": "Taak verwijderen",
"favorite": "Opslaan als favoriet",
"unfavorite": "Verwijderen uit favorieten"
"repeatAfter": "Set Repeating Interval",
"percentDone": "Set Progress",
"attachments": "Add Attachments",
"relatedTasks": "Add Relation",
"moveList": "Move",
"color": "Set Color",
"delete": "Verwijder",
"favorite": "Toevoegen aan favorieten",
"unfavorite": "Verwijder uit favorieten"
}
},
"attributes": {
@ -593,11 +643,11 @@
"created": "Aangemaakt op",
"createdBy": "Aangemaakt door",
"description": "Beschrijving",
"done": "Gereed",
"done": "Voltooid",
"dueDate": "Due Date",
"endDate": "End Date",
"labels": "Labels",
"percentDone": "% Gereed",
"percentDone": "Progress",
"priority": "Prioriteit",
"relatedTasks": "Verwante Taken",
"reminders": "Herinneringen",
@ -784,17 +834,20 @@
"general": "General",
"allPages": "These shortcuts work on all pages.",
"currentPageOnly": "These shortcuts work only on the current page.",
"somePagesOnly": "These shortcuts work only on some pages.",
"toggleMenu": "Toggle The Menu",
"quickSearch": "Open the search/quick action bar",
"then": "then",
"task": {
"title": "Task Page",
"done": "Done",
"assign": "Assign to a user",
"done": "Mark task done / undone",
"assign": "Assign this task to a user",
"labels": "Add labels to this task",
"dueDate": "Change the due date of this task",
"attachment": "Add an attachment to this task",
"related": "Modify related tasks of this task"
"related": "Modify related tasks of this task",
"color": "Change the color of this task",
"move": "Move this task to another list"
},
"list": {
"title": "List Views",
@ -802,6 +855,14 @@
"switchToGanttView": "Switch to gantt view",
"switchToKanbanView": "Switch to kanban view",
"switchToTableView": "Switch to table view"
},
"navigation": {
"title": "Navigation",
"overview": "Navigato to overview",
"upcoming": "Navigato to upcoming taks",
"namespaces": "Navigate to namepaces & lists",
"labels": "Navigate to labels",
"teams": "Navigate to teams"
}
},
"update": {

View File

@ -105,7 +105,7 @@
"caldav": {
"title": "Caldav",
"howTo": "Możesz połączyć Vikunja z klientami caldav, aby przeglądać i zarządzać wszystkimi zadaniami z różnych klientów. Wprowadź ten adres URL do swojego klienta:",
"more": "Więcej informacji o caldav w Vikunji"
"more": "Więcej informacji o CalDAV w Vikunji"
},
"avatar": {
"title": "Awatar",
@ -335,7 +335,7 @@
"archiveText": "Nie będziesz mógł tworzyć nowych list ani edytować tej sekcji, dopóki nie cofniesz archiwizacji. Ta operacja zarchiwizuje również wszystkie listy należące do tej sekcji.",
"unarchiveText": "Będziesz mógł tworzyć nowe listy i je edytować.",
"success": "Sekcja została pomyślnie zarchiwizowana.",
"unarchiveSuccess": "The namespace was successfully un-archived.",
"unarchiveSuccess": "Archiwizacja sekcji została pomyślnie cofnięta.",
"description": "Jeśli sekcja jest zarchiwizowana, nie można edytować ani tworzyć nowych list."
},
"delete": {
@ -357,7 +357,7 @@
"description": "Opis",
"descriptionPlaceholder": "Tu wpisz opis sekcji…",
"color": "Kolor",
"archived": "Zarchiwizowany",
"archived": "Archiwizacja",
"isArchived": "Ta sekcja jest zarchiwizowana"
},
"pseudo": {
@ -385,7 +385,7 @@
"showDoneTasks": "Pokaż ukończone zadania",
"sortAlphabetically": "Sortuj alfabetycznie",
"enablePriority": "Włącz filtrowanie według priorytetu",
"enablePercentDone": "Włącz filtrowanie według procentu ukończenia",
"enablePercentDone": "Włącz filtrowanie według postępu",
"dueDateRange": "Zakres daty terminu",
"startDateRange": "Zakres daty rozpoczęcia",
"endDateRange": "Zakres daty zakończenia",
@ -485,7 +485,8 @@
"showMenu": "Pokaż menu",
"hideMenu": "Ukryj menu",
"forExample": "Na przykład:",
"welcomeBack": "Witaj ponownie!"
"welcomeBack": "Witaj ponownie!",
"custom": "Custom"
},
"input": {
"resetColor": "Resetuj kolor",
@ -524,6 +525,57 @@
"multiselect": {
"createPlaceholder": "Utwórz nowy",
"selectPlaceholder": "Kliknij lub naciśnij Enter, aby wybrać"
},
"datepickerRange": {
"to": "To",
"from": "From",
"fromto": "{from} to {to}",
"ranges": {
"today": "Today",
"thisWeek": "This Week",
"restOfThisWeek": "The Rest of This Week",
"nextWeek": "Next Week",
"next7Days": "Next 7 Days",
"lastWeek": "Last Week",
"thisMonth": "This Month",
"restOfThisMonth": "The Rest of This Month",
"nextMonth": "Next Month",
"next30Days": "Next 30 Days",
"lastMonth": "Last Month",
"thisYear": "This Year",
"restOfThisYear": "The Rest of This Year"
}
},
"datemathHelp": {
"canuse": "You can use date math to filter for relative dates.",
"learnhow": "Check out how it works",
"title": "Date Math",
"intro": "Date Math allows you to specifiy relative dates which are resolved on the fly by Vikunja when applying the filter.",
"expression": "Each Date Math expression starts with an anchor date, which can either be {0}, or a date string ending with {1}. This anchor date can optionally be followed by one or more maths expressions.",
"similar": "These expressions are similar to the ones provided by {0} and {1}.",
"add1Day": "Add one day",
"minus1Day": "Subtract one day",
"roundDay": "Round down to the nearest day",
"supportedUnits": "Supported time units are:",
"someExamples": "Some examples of time expressions:",
"units": {
"seconds": "Seconds",
"minutes": "Minutes",
"hours": "Hours",
"days": "Days",
"weeks": "Weeks",
"months": "Months",
"years": "Years"
},
"examples": {
"now": "Right now",
"in24h": "In 24h",
"today": "Today at 00:00",
"beginningOfThisWeek": "The beginning of this week at 00:00",
"endOfThisWeek": "The end of this week",
"in30Days": "In 30 days",
"datePlusMonth": "{0} plus one month at 00:00 of that day"
}
}
},
"task": {
@ -541,12 +593,9 @@
"titleCurrent": "Bieżące zadania",
"titleDates": "Zadania od {from} do {to}",
"noDates": "Pokaż zadania bez dat",
"current": "Bieżące zadania",
"from": "Zadania od",
"until": "do",
"today": "Dziś",
"nextWeek": "Następny tydzień",
"nextMonth": "Następny miesiąc",
"overdue": "Show overdue tasks",
"fromuntil": "Tasks from {from} until {until}",
"select": "Select a date range",
"noTasks": "Brak zadań do wykonania miłego dnia!"
},
"detail": {
@ -578,13 +627,13 @@
"endDate": "Ustaw datę zakończenia",
"reminders": "Ustaw przypomnienia",
"repeatAfter": "Ustaw interwał powtarzania",
"percentDone": "Ustaw procent ukończenia",
"percentDone": "Ustaw postęp",
"attachments": "Dodaj załączniki",
"relatedTasks": "Dodaj powiązane zadania",
"moveList": "Przenieś zadanie",
"color": "Ustaw kolor zadania",
"delete": "Usuń zadanie",
"favorite": "Zapisz jako ulubione",
"relatedTasks": "Dodaj powiązanie",
"moveList": "Przenieś",
"color": "Ustaw kolor",
"delete": "Usuń",
"favorite": "Dodaj do ulubionych",
"unfavorite": "Usuń z ulubionych"
}
},
@ -598,7 +647,7 @@
"dueDate": "Termin",
"endDate": "Data zakończenia",
"labels": "Etykiety",
"percentDone": "% ukończenia",
"percentDone": "Postęp",
"priority": "Priorytet",
"relatedTasks": "Powiązane zadania",
"reminders": "Przypomnienia",
@ -785,17 +834,20 @@
"general": "Ogólne",
"allPages": "Te skróty działają na wszystkich stronach.",
"currentPageOnly": "Te skróty działają tylko na bieżącej stronie.",
"somePagesOnly": "Te skróty działają tylko na niektórych stronach.",
"toggleMenu": "Przełącz menu",
"quickSearch": "Otwórz pasek wyszukiwania/szybkiej akcji",
"then": "następnie",
"task": {
"title": "Widok zadań",
"done": "Ukończone",
"assign": "Przypisz do użytkownika",
"done": "Oznacz zadanie jako wykonane / niewykonane",
"assign": "Przypisz to zadanie do użytkownika",
"labels": "Dodaj etykiety do tego zadania",
"dueDate": "Zmień termin wykonania tego zadania",
"attachment": "Dodaj załącznik do tego zadania",
"related": "Zmodyfikuj zadania powiązane z tym zadaniem"
"related": "Zmodyfikuj zadania powiązane z tym zadaniem",
"color": "Zmień kolor tego zadania",
"move": "Przenieś to zadanie do innej listy"
},
"list": {
"title": "Widoki listy",
@ -803,6 +855,14 @@
"switchToGanttView": "Przełącz na widok Gantta",
"switchToKanbanView": "Przełącz na widok Kanban",
"switchToTableView": "Przełącz na widok tabeli"
},
"navigation": {
"title": "Nawigacja",
"overview": "Przejdź do przeglądu",
"upcoming": "Przejdź do nadchodzących zadań",
"namespaces": "Przejdź do sekcji i list",
"labels": "Przejdź do etykiet",
"teams": "Przejdź do zespołów"
}
},
"update": {

View File

@ -385,7 +385,7 @@
"showDoneTasks": "Show Done Tasks",
"sortAlphabetically": "Sort Alphabetically",
"enablePriority": "Enable Filter By Priority",
"enablePercentDone": "Enable Filter By Percent Done",
"enablePercentDone": "Enable Filter By Progress",
"dueDateRange": "Due Date Range",
"startDateRange": "Start Date Range",
"endDateRange": "End Date Range",
@ -485,7 +485,8 @@
"showMenu": "Show the menu",
"hideMenu": "Hide the menu",
"forExample": "For example:",
"welcomeBack": "Welcome Back!"
"welcomeBack": "Welcome Back!",
"custom": "Custom"
},
"input": {
"resetColor": "Reset Color",
@ -524,6 +525,57 @@
"multiselect": {
"createPlaceholder": "Create new",
"selectPlaceholder": "Click or press enter to select"
},
"datepickerRange": {
"to": "To",
"from": "From",
"fromto": "{from} to {to}",
"ranges": {
"today": "Today",
"thisWeek": "This Week",
"restOfThisWeek": "The Rest of This Week",
"nextWeek": "Next Week",
"next7Days": "Next 7 Days",
"lastWeek": "Last Week",
"thisMonth": "This Month",
"restOfThisMonth": "The Rest of This Month",
"nextMonth": "Next Month",
"next30Days": "Next 30 Days",
"lastMonth": "Last Month",
"thisYear": "This Year",
"restOfThisYear": "The Rest of This Year"
}
},
"datemathHelp": {
"canuse": "You can use date math to filter for relative dates.",
"learnhow": "Check out how it works",
"title": "Date Math",
"intro": "Date Math allows you to specifiy relative dates which are resolved on the fly by Vikunja when applying the filter.",
"expression": "Each Date Math expression starts with an anchor date, which can either be {0}, or a date string ending with {1}. This anchor date can optionally be followed by one or more maths expressions.",
"similar": "These expressions are similar to the ones provided by {0} and {1}.",
"add1Day": "Add one day",
"minus1Day": "Subtract one day",
"roundDay": "Round down to the nearest day",
"supportedUnits": "Supported time units are:",
"someExamples": "Some examples of time expressions:",
"units": {
"seconds": "Seconds",
"minutes": "Minutes",
"hours": "Hours",
"days": "Days",
"weeks": "Weeks",
"months": "Months",
"years": "Years"
},
"examples": {
"now": "Right now",
"in24h": "In 24h",
"today": "Today at 00:00",
"beginningOfThisWeek": "The beginning of this week at 00:00",
"endOfThisWeek": "The end of this week",
"in30Days": "In 30 days",
"datePlusMonth": "{0} plus one month at 00:00 of that day"
}
}
},
"task": {
@ -541,12 +593,9 @@
"titleCurrent": "Current Tasks",
"titleDates": "Tasks from {from} until {to}",
"noDates": "Show tasks without dates",
"current": "Current tasks",
"from": "Tasks from",
"until": "until",
"today": "Today",
"nextWeek": "Next Week",
"nextMonth": "Next Month",
"overdue": "Show overdue tasks",
"fromuntil": "Tasks from {from} until {until}",
"select": "Select a date range",
"noTasks": "Nothing to do — Have a nice day!"
},
"detail": {
@ -570,22 +619,22 @@
"text2": "This will also remove all attachments, reminders and relations associated with this task and cannot be undone!"
},
"actions": {
"assign": "Assign to a user",
"label": "Add labels",
"assign": "Assign to User",
"label": "Add Labels",
"priority": "Set Priority",
"dueDate": "Set Due Date",
"startDate": "Set a Start Date",
"endDate": "Set an End Date",
"startDate": "Set Start Date",
"endDate": "Set End Date",
"reminders": "Set Reminders",
"repeatAfter": "Set a repeating interval",
"percentDone": "Set Percent Done",
"attachments": "Add attachments",
"relatedTasks": "Add task relations",
"moveList": "Move task",
"color": "Set task color",
"delete": "Delete task",
"favorite": "Save as favorite",
"unfavorite": "Remove from favorites"
"repeatAfter": "Set Repeating Interval",
"percentDone": "Set Progress",
"attachments": "Add Attachments",
"relatedTasks": "Add Relation",
"moveList": "Move",
"color": "Set Color",
"delete": "Delete",
"favorite": "Add to Favorites",
"unfavorite": "Remove from Favorites"
}
},
"attributes": {
@ -598,7 +647,7 @@
"dueDate": "Due Date",
"endDate": "End Date",
"labels": "Labels",
"percentDone": "% Done",
"percentDone": "Progress",
"priority": "Priority",
"relatedTasks": "Related Tasks",
"reminders": "Reminders",
@ -785,17 +834,20 @@
"general": "General",
"allPages": "These shortcuts work on all pages.",
"currentPageOnly": "These shortcuts work only on the current page.",
"somePagesOnly": "These shortcuts work only on some pages.",
"toggleMenu": "Toggle The Menu",
"quickSearch": "Open the search/quick action bar",
"then": "then",
"task": {
"title": "Task Page",
"done": "Done",
"assign": "Assign to a user",
"done": "Mark task done / undone",
"assign": "Assign this task to a user",
"labels": "Add labels to this task",
"dueDate": "Change the due date of this task",
"attachment": "Add an attachment to this task",
"related": "Modify related tasks of this task"
"related": "Modify related tasks of this task",
"color": "Change the color of this task",
"move": "Move this task to another list"
},
"list": {
"title": "List Views",
@ -803,6 +855,14 @@
"switchToGanttView": "Switch to gantt view",
"switchToKanbanView": "Switch to kanban view",
"switchToTableView": "Switch to table view"
},
"navigation": {
"title": "Navigation",
"overview": "Navigato to overview",
"upcoming": "Navigato to upcoming taks",
"namespaces": "Navigate to namepaces & lists",
"labels": "Navigate to labels",
"teams": "Navigate to teams"
}
},
"update": {

File diff suppressed because it is too large Load Diff

View File

@ -385,7 +385,7 @@
"showDoneTasks": "Show Done Tasks",
"sortAlphabetically": "Sort Alphabetically",
"enablePriority": "Enable Filter By Priority",
"enablePercentDone": "Enable Filter By Percent Done",
"enablePercentDone": "Enable Filter By Progress",
"dueDateRange": "Due Date Range",
"startDateRange": "Start Date Range",
"endDateRange": "End Date Range",
@ -485,7 +485,8 @@
"showMenu": "Show the menu",
"hideMenu": "Hide the menu",
"forExample": "For example:",
"welcomeBack": "Welcome Back!"
"welcomeBack": "Welcome Back!",
"custom": "Custom"
},
"input": {
"resetColor": "Reset Color",
@ -524,6 +525,57 @@
"multiselect": {
"createPlaceholder": "Create new",
"selectPlaceholder": "Click or press enter to select"
},
"datepickerRange": {
"to": "To",
"from": "From",
"fromto": "{from} to {to}",
"ranges": {
"today": "Today",
"thisWeek": "This Week",
"restOfThisWeek": "The Rest of This Week",
"nextWeek": "Next Week",
"next7Days": "Next 7 Days",
"lastWeek": "Last Week",
"thisMonth": "This Month",
"restOfThisMonth": "The Rest of This Month",
"nextMonth": "Next Month",
"next30Days": "Next 30 Days",
"lastMonth": "Last Month",
"thisYear": "This Year",
"restOfThisYear": "The Rest of This Year"
}
},
"datemathHelp": {
"canuse": "You can use date math to filter for relative dates.",
"learnhow": "Check out how it works",
"title": "Date Math",
"intro": "Date Math allows you to specifiy relative dates which are resolved on the fly by Vikunja when applying the filter.",
"expression": "Each Date Math expression starts with an anchor date, which can either be {0}, or a date string ending with {1}. This anchor date can optionally be followed by one or more maths expressions.",
"similar": "These expressions are similar to the ones provided by {0} and {1}.",
"add1Day": "Add one day",
"minus1Day": "Subtract one day",
"roundDay": "Round down to the nearest day",
"supportedUnits": "Supported time units are:",
"someExamples": "Some examples of time expressions:",
"units": {
"seconds": "Seconds",
"minutes": "Minutes",
"hours": "Hours",
"days": "Days",
"weeks": "Weeks",
"months": "Months",
"years": "Years"
},
"examples": {
"now": "Right now",
"in24h": "In 24h",
"today": "Today at 00:00",
"beginningOfThisWeek": "The beginning of this week at 00:00",
"endOfThisWeek": "The end of this week",
"in30Days": "In 30 days",
"datePlusMonth": "{0} plus one month at 00:00 of that day"
}
}
},
"task": {
@ -541,12 +593,9 @@
"titleCurrent": "Current Tasks",
"titleDates": "Tasks from {from} until {to}",
"noDates": "Show tasks without dates",
"current": "Current tasks",
"from": "Tasks from",
"until": "until",
"today": "Today",
"nextWeek": "Next Week",
"nextMonth": "Next Month",
"overdue": "Show overdue tasks",
"fromuntil": "Tasks from {from} until {until}",
"select": "Select a date range",
"noTasks": "Nothing to do — Have a nice day!"
},
"detail": {
@ -570,22 +619,22 @@
"text2": "This will also remove all attachments, reminders and relations associated with this task and cannot be undone!"
},
"actions": {
"assign": "Assign to a user",
"label": "Add labels",
"assign": "Assign to User",
"label": "Add Labels",
"priority": "Set Priority",
"dueDate": "Set Due Date",
"startDate": "Set a Start Date",
"endDate": "Set an End Date",
"startDate": "Set Start Date",
"endDate": "Set End Date",
"reminders": "Set Reminders",
"repeatAfter": "Set a repeating interval",
"percentDone": "Set Percent Done",
"attachments": "Add attachments",
"relatedTasks": "Add task relations",
"moveList": "Move task",
"color": "Set task color",
"delete": "Delete task",
"favorite": "Save as favorite",
"unfavorite": "Remove from favorites"
"repeatAfter": "Set Repeating Interval",
"percentDone": "Set Progress",
"attachments": "Add Attachments",
"relatedTasks": "Add Relation",
"moveList": "Move",
"color": "Set Color",
"delete": "Delete",
"favorite": "Add to Favorites",
"unfavorite": "Remove from Favorites"
}
},
"attributes": {
@ -598,7 +647,7 @@
"dueDate": "Due Date",
"endDate": "End Date",
"labels": "Labels",
"percentDone": "% Done",
"percentDone": "Progress",
"priority": "Priority",
"relatedTasks": "Related Tasks",
"reminders": "Reminders",
@ -785,17 +834,20 @@
"general": "General",
"allPages": "These shortcuts work on all pages.",
"currentPageOnly": "These shortcuts work only on the current page.",
"somePagesOnly": "These shortcuts work only on some pages.",
"toggleMenu": "Toggle The Menu",
"quickSearch": "Open the search/quick action bar",
"then": "then",
"task": {
"title": "Task Page",
"done": "Done",
"assign": "Assign to a user",
"done": "Mark task done / undone",
"assign": "Assign this task to a user",
"labels": "Add labels to this task",
"dueDate": "Change the due date of this task",
"attachment": "Add an attachment to this task",
"related": "Modify related tasks of this task"
"related": "Modify related tasks of this task",
"color": "Change the color of this task",
"move": "Move this task to another list"
},
"list": {
"title": "List Views",
@ -803,6 +855,14 @@
"switchToGanttView": "Switch to gantt view",
"switchToKanbanView": "Switch to kanban view",
"switchToTableView": "Switch to table view"
},
"navigation": {
"title": "Navigation",
"overview": "Navigato to overview",
"upcoming": "Navigato to upcoming taks",
"namespaces": "Navigate to namepaces & lists",
"labels": "Navigate to labels",
"teams": "Navigate to teams"
}
},
"update": {

View File

@ -105,7 +105,7 @@
"caldav": {
"title": "CalDAV",
"howTo": "Ты можешь подключить Vikunja к клиентам CalDAV, чтобы просматривать и управлять всеми задачами из разных клиентов. Введи этот URL в свой клиент:",
"more": "Подробнее о caldav в Vikunja"
"more": "Подробнее о CalDAV в Vikunja"
},
"avatar": {
"title": "Аватар",
@ -385,7 +385,7 @@
"showDoneTasks": "Показывать завершённые задачи",
"sortAlphabetically": "Sort Alphabetically",
"enablePriority": "Вкл. фильтр по приоритету",
"enablePercentDone": "По % завершения",
"enablePercentDone": "Enable Filter By Progress",
"dueDateRange": "Диапазон срока",
"startDateRange": "Диапазон даты начала",
"endDateRange": "Диапазон даты завершения",
@ -485,7 +485,8 @@
"showMenu": "Show the menu",
"hideMenu": "Hide the menu",
"forExample": "For example:",
"welcomeBack": "Welcome Back!"
"welcomeBack": "Welcome Back!",
"custom": "Custom"
},
"input": {
"resetColor": "Сбросить цвет",
@ -524,6 +525,57 @@
"multiselect": {
"createPlaceholder": "Создать",
"selectPlaceholder": "Кликните или нажмите Enter для выбора"
},
"datepickerRange": {
"to": "To",
"from": "From",
"fromto": "{from} to {to}",
"ranges": {
"today": "Today",
"thisWeek": "This Week",
"restOfThisWeek": "The Rest of This Week",
"nextWeek": "Next Week",
"next7Days": "Next 7 Days",
"lastWeek": "Last Week",
"thisMonth": "This Month",
"restOfThisMonth": "The Rest of This Month",
"nextMonth": "Next Month",
"next30Days": "Next 30 Days",
"lastMonth": "Last Month",
"thisYear": "This Year",
"restOfThisYear": "The Rest of This Year"
}
},
"datemathHelp": {
"canuse": "You can use date math to filter for relative dates.",
"learnhow": "Check out how it works",
"title": "Date Math",
"intro": "Date Math allows you to specifiy relative dates which are resolved on the fly by Vikunja when applying the filter.",
"expression": "Each Date Math expression starts with an anchor date, which can either be {0}, or a date string ending with {1}. This anchor date can optionally be followed by one or more maths expressions.",
"similar": "These expressions are similar to the ones provided by {0} and {1}.",
"add1Day": "Add one day",
"minus1Day": "Subtract one day",
"roundDay": "Round down to the nearest day",
"supportedUnits": "Supported time units are:",
"someExamples": "Some examples of time expressions:",
"units": {
"seconds": "Seconds",
"minutes": "Minutes",
"hours": "Hours",
"days": "Days",
"weeks": "Weeks",
"months": "Months",
"years": "Years"
},
"examples": {
"now": "Right now",
"in24h": "In 24h",
"today": "Today at 00:00",
"beginningOfThisWeek": "The beginning of this week at 00:00",
"endOfThisWeek": "The end of this week",
"in30Days": "In 30 days",
"datePlusMonth": "{0} plus one month at 00:00 of that day"
}
}
},
"task": {
@ -541,12 +593,9 @@
"titleCurrent": "Текущие задачи",
"titleDates": "Задачи с {from} по {to}",
"noDates": "Показать задачи без даты",
"current": "Текущие задачи",
"from": "Задачи с",
"until": "по",
"today": "Сегодня",
"nextWeek": "Неделя",
"nextMonth": "Месяц",
"overdue": "Show overdue tasks",
"fromuntil": "Tasks from {from} until {until}",
"select": "Select a date range",
"noTasks": "Nothing to do — Have a nice day!"
},
"detail": {
@ -570,22 +619,22 @@
"text2": "Будут удалены все вложения, напоминания и отношения, связанные с этой задачей, и отменить это будет нельзя!"
},
"actions": {
"assign": "Assign to a user",
"label": "Добавить метки",
"assign": "Assign to User",
"label": "Add Labels",
"priority": "Установить приоритет",
"dueDate": "Установить срок",
"startDate": "Установить дату начала",
"endDate": "Установить дату завершения",
"startDate": "Set Start Date",
"endDate": "Set End Date",
"reminders": "Установить напоминания",
"repeatAfter": "Установить интервал повтора",
"percentDone": "Установить процент завершения",
"attachments": "Добавить вложения",
"relatedTasks": "Добавить связанные задачи",
"moveList": "Переместить задачу",
"color": "Установить цвет задачи",
"delete": "Удалить задачу",
"favorite": "Сохранить как ибзранное",
"unfavorite": "Убрать из избранного"
"repeatAfter": "Set Repeating Interval",
"percentDone": "Set Progress",
"attachments": "Add Attachments",
"relatedTasks": "Add Relation",
"moveList": "Move",
"color": "Set Color",
"delete": "Delete",
"favorite": "Add to Favorites",
"unfavorite": "Remove from Favorites"
}
},
"attributes": {
@ -598,7 +647,7 @@
"dueDate": "Срок",
"endDate": "Дата завершения",
"labels": "Метки",
"percentDone": "% Завершено",
"percentDone": "Progress",
"priority": "Приоритет",
"relatedTasks": "Связанные задачи",
"reminders": "Напоминания",
@ -785,17 +834,20 @@
"general": "General",
"allPages": "Работают на всех страницах.",
"currentPageOnly": "Работают только на текущей странице.",
"somePagesOnly": "These shortcuts work only on some pages.",
"toggleMenu": "Переключить меню",
"quickSearch": "Открыть панель поиска/быстрых действий",
"then": "then",
"task": {
"title": "Страница задачи",
"done": "Done",
"assign": "Assign to a user",
"done": "Mark task done / undone",
"assign": "Assign this task to a user",
"labels": "Добавить метки этой задаче",
"dueDate": "Изменить срок этой задачи",
"attachment": "Добавить вложение к задаче",
"related": "Изменить связанные задачи"
"related": "Изменить связанные задачи",
"color": "Change the color of this task",
"move": "Move this task to another list"
},
"list": {
"title": "List Views",
@ -803,6 +855,14 @@
"switchToGanttView": "Switch to gantt view",
"switchToKanbanView": "Switch to kanban view",
"switchToTableView": "Switch to table view"
},
"navigation": {
"title": "Navigation",
"overview": "Navigato to overview",
"upcoming": "Navigato to upcoming taks",
"namespaces": "Navigate to namepaces & lists",
"labels": "Navigate to labels",
"teams": "Navigate to teams"
}
},
"update": {

View File

@ -385,7 +385,7 @@
"showDoneTasks": "Show Done Tasks",
"sortAlphabetically": "Sort Alphabetically",
"enablePriority": "Enable Filter By Priority",
"enablePercentDone": "Enable Filter By Percent Done",
"enablePercentDone": "Enable Filter By Progress",
"dueDateRange": "Due Date Range",
"startDateRange": "Start Date Range",
"endDateRange": "End Date Range",
@ -485,7 +485,8 @@
"showMenu": "Show the menu",
"hideMenu": "Hide the menu",
"forExample": "For example:",
"welcomeBack": "Welcome Back!"
"welcomeBack": "Welcome Back!",
"custom": "Custom"
},
"input": {
"resetColor": "Reset Color",
@ -524,6 +525,57 @@
"multiselect": {
"createPlaceholder": "Create new",
"selectPlaceholder": "Click or press enter to select"
},
"datepickerRange": {
"to": "To",
"from": "From",
"fromto": "{from} to {to}",
"ranges": {
"today": "Today",
"thisWeek": "This Week",
"restOfThisWeek": "The Rest of This Week",
"nextWeek": "Next Week",
"next7Days": "Next 7 Days",
"lastWeek": "Last Week",
"thisMonth": "This Month",
"restOfThisMonth": "The Rest of This Month",
"nextMonth": "Next Month",
"next30Days": "Next 30 Days",
"lastMonth": "Last Month",
"thisYear": "This Year",
"restOfThisYear": "The Rest of This Year"
}
},
"datemathHelp": {
"canuse": "You can use date math to filter for relative dates.",
"learnhow": "Check out how it works",
"title": "Date Math",
"intro": "Date Math allows you to specifiy relative dates which are resolved on the fly by Vikunja when applying the filter.",
"expression": "Each Date Math expression starts with an anchor date, which can either be {0}, or a date string ending with {1}. This anchor date can optionally be followed by one or more maths expressions.",
"similar": "These expressions are similar to the ones provided by {0} and {1}.",
"add1Day": "Add one day",
"minus1Day": "Subtract one day",
"roundDay": "Round down to the nearest day",
"supportedUnits": "Supported time units are:",
"someExamples": "Some examples of time expressions:",
"units": {
"seconds": "Seconds",
"minutes": "Minutes",
"hours": "Hours",
"days": "Days",
"weeks": "Weeks",
"months": "Months",
"years": "Years"
},
"examples": {
"now": "Right now",
"in24h": "In 24h",
"today": "Today at 00:00",
"beginningOfThisWeek": "The beginning of this week at 00:00",
"endOfThisWeek": "The end of this week",
"in30Days": "In 30 days",
"datePlusMonth": "{0} plus one month at 00:00 of that day"
}
}
},
"task": {
@ -541,12 +593,9 @@
"titleCurrent": "Current Tasks",
"titleDates": "Tasks from {from} until {to}",
"noDates": "Show tasks without dates",
"current": "Current tasks",
"from": "Tasks from",
"until": "until",
"today": "Today",
"nextWeek": "Next Week",
"nextMonth": "Next Month",
"overdue": "Show overdue tasks",
"fromuntil": "Tasks from {from} until {until}",
"select": "Select a date range",
"noTasks": "Nothing to do — Have a nice day!"
},
"detail": {
@ -570,22 +619,22 @@
"text2": "This will also remove all attachments, reminders and relations associated with this task and cannot be undone!"
},
"actions": {
"assign": "Assign to a user",
"label": "Add labels",
"assign": "Assign to User",
"label": "Add Labels",
"priority": "Set Priority",
"dueDate": "Set Due Date",
"startDate": "Set a Start Date",
"endDate": "Set an End Date",
"startDate": "Set Start Date",
"endDate": "Set End Date",
"reminders": "Set Reminders",
"repeatAfter": "Set a repeating interval",
"percentDone": "Set Percent Done",
"attachments": "Add attachments",
"relatedTasks": "Add task relations",
"moveList": "Move task",
"color": "Set task color",
"delete": "Delete task",
"favorite": "Save as favorite",
"unfavorite": "Remove from favorites"
"repeatAfter": "Set Repeating Interval",
"percentDone": "Set Progress",
"attachments": "Add Attachments",
"relatedTasks": "Add Relation",
"moveList": "Move",
"color": "Set Color",
"delete": "Delete",
"favorite": "Add to Favorites",
"unfavorite": "Remove from Favorites"
}
},
"attributes": {
@ -598,7 +647,7 @@
"dueDate": "Due Date",
"endDate": "End Date",
"labels": "Labels",
"percentDone": "% Done",
"percentDone": "Progress",
"priority": "Priority",
"relatedTasks": "Related Tasks",
"reminders": "Reminders",
@ -785,17 +834,20 @@
"general": "General",
"allPages": "These shortcuts work on all pages.",
"currentPageOnly": "These shortcuts work only on the current page.",
"somePagesOnly": "These shortcuts work only on some pages.",
"toggleMenu": "Toggle The Menu",
"quickSearch": "Open the search/quick action bar",
"then": "then",
"task": {
"title": "Task Page",
"done": "Done",
"assign": "Assign to a user",
"done": "Mark task done / undone",
"assign": "Assign this task to a user",
"labels": "Add labels to this task",
"dueDate": "Change the due date of this task",
"attachment": "Add an attachment to this task",
"related": "Modify related tasks of this task"
"related": "Modify related tasks of this task",
"color": "Change the color of this task",
"move": "Move this task to another list"
},
"list": {
"title": "List Views",
@ -803,6 +855,14 @@
"switchToGanttView": "Switch to gantt view",
"switchToKanbanView": "Switch to kanban view",
"switchToTableView": "Switch to table view"
},
"navigation": {
"title": "Navigation",
"overview": "Navigato to overview",
"upcoming": "Navigato to upcoming taks",
"namespaces": "Navigate to namepaces & lists",
"labels": "Navigate to labels",
"teams": "Navigate to teams"
}
},
"update": {

View File

@ -385,7 +385,7 @@
"showDoneTasks": "Show Done Tasks",
"sortAlphabetically": "Sort Alphabetically",
"enablePriority": "Enable Filter By Priority",
"enablePercentDone": "Enable Filter By Percent Done",
"enablePercentDone": "Enable Filter By Progress",
"dueDateRange": "Due Date Range",
"startDateRange": "Start Date Range",
"endDateRange": "End Date Range",
@ -485,7 +485,8 @@
"showMenu": "Show the menu",
"hideMenu": "Hide the menu",
"forExample": "For example:",
"welcomeBack": "Welcome Back!"
"welcomeBack": "Welcome Back!",
"custom": "Custom"
},
"input": {
"resetColor": "Reset Color",
@ -524,6 +525,57 @@
"multiselect": {
"createPlaceholder": "Create new",
"selectPlaceholder": "Click or press enter to select"
},
"datepickerRange": {
"to": "To",
"from": "From",
"fromto": "{from} to {to}",
"ranges": {
"today": "Today",
"thisWeek": "This Week",
"restOfThisWeek": "The Rest of This Week",
"nextWeek": "Next Week",
"next7Days": "Next 7 Days",
"lastWeek": "Last Week",
"thisMonth": "This Month",
"restOfThisMonth": "The Rest of This Month",
"nextMonth": "Next Month",
"next30Days": "Next 30 Days",
"lastMonth": "Last Month",
"thisYear": "This Year",
"restOfThisYear": "The Rest of This Year"
}
},
"datemathHelp": {
"canuse": "You can use date math to filter for relative dates.",
"learnhow": "Check out how it works",
"title": "Date Math",
"intro": "Date Math allows you to specifiy relative dates which are resolved on the fly by Vikunja when applying the filter.",
"expression": "Each Date Math expression starts with an anchor date, which can either be {0}, or a date string ending with {1}. This anchor date can optionally be followed by one or more maths expressions.",
"similar": "These expressions are similar to the ones provided by {0} and {1}.",
"add1Day": "Add one day",
"minus1Day": "Subtract one day",
"roundDay": "Round down to the nearest day",
"supportedUnits": "Supported time units are:",
"someExamples": "Some examples of time expressions:",
"units": {
"seconds": "Seconds",
"minutes": "Minutes",
"hours": "Hours",
"days": "Days",
"weeks": "Weeks",
"months": "Months",
"years": "Years"
},
"examples": {
"now": "Right now",
"in24h": "In 24h",
"today": "Today at 00:00",
"beginningOfThisWeek": "The beginning of this week at 00:00",
"endOfThisWeek": "The end of this week",
"in30Days": "In 30 days",
"datePlusMonth": "{0} plus one month at 00:00 of that day"
}
}
},
"task": {
@ -541,12 +593,9 @@
"titleCurrent": "Current Tasks",
"titleDates": "Tasks from {from} until {to}",
"noDates": "Show tasks without dates",
"current": "Current tasks",
"from": "Tasks from",
"until": "until",
"today": "Today",
"nextWeek": "Next Week",
"nextMonth": "Next Month",
"overdue": "Show overdue tasks",
"fromuntil": "Tasks from {from} until {until}",
"select": "Select a date range",
"noTasks": "Nothing to do — Have a nice day!"
},
"detail": {
@ -570,22 +619,22 @@
"text2": "This will also remove all attachments, reminders and relations associated with this task and cannot be undone!"
},
"actions": {
"assign": "Assign to a user",
"label": "Add labels",
"assign": "Assign to User",
"label": "Add Labels",
"priority": "Set Priority",
"dueDate": "Set Due Date",
"startDate": "Set a Start Date",
"endDate": "Set an End Date",
"startDate": "Set Start Date",
"endDate": "Set End Date",
"reminders": "Set Reminders",
"repeatAfter": "Set a repeating interval",
"percentDone": "Set Percent Done",
"attachments": "Add attachments",
"relatedTasks": "Add task relations",
"moveList": "Move task",
"color": "Set task color",
"delete": "Delete task",
"favorite": "Save as favorite",
"unfavorite": "Remove from favorites"
"repeatAfter": "Set Repeating Interval",
"percentDone": "Set Progress",
"attachments": "Add Attachments",
"relatedTasks": "Add Relation",
"moveList": "Move",
"color": "Set Color",
"delete": "Delete",
"favorite": "Add to Favorites",
"unfavorite": "Remove from Favorites"
}
},
"attributes": {
@ -598,7 +647,7 @@
"dueDate": "Due Date",
"endDate": "End Date",
"labels": "Labels",
"percentDone": "% Done",
"percentDone": "Progress",
"priority": "Priority",
"relatedTasks": "Related Tasks",
"reminders": "Reminders",
@ -785,17 +834,20 @@
"general": "General",
"allPages": "These shortcuts work on all pages.",
"currentPageOnly": "These shortcuts work only on the current page.",
"somePagesOnly": "These shortcuts work only on some pages.",
"toggleMenu": "Toggle The Menu",
"quickSearch": "Open the search/quick action bar",
"then": "then",
"task": {
"title": "Task Page",
"done": "Done",
"assign": "Assign to a user",
"done": "Mark task done / undone",
"assign": "Assign this task to a user",
"labels": "Add labels to this task",
"dueDate": "Change the due date of this task",
"attachment": "Add an attachment to this task",
"related": "Modify related tasks of this task"
"related": "Modify related tasks of this task",
"color": "Change the color of this task",
"move": "Move this task to another list"
},
"list": {
"title": "List Views",
@ -803,6 +855,14 @@
"switchToGanttView": "Switch to gantt view",
"switchToKanbanView": "Switch to kanban view",
"switchToTableView": "Switch to table view"
},
"navigation": {
"title": "Navigation",
"overview": "Navigato to overview",
"upcoming": "Navigato to upcoming taks",
"namespaces": "Navigate to namepaces & lists",
"labels": "Navigate to labels",
"teams": "Navigate to teams"
}
},
"update": {

View File

@ -7,7 +7,7 @@
"lastViewed": "Xem gần đây",
"list": {
"newText": "Bạn có thể tạo một danh sách công việc mới cho mình:",
"new": "New list",
"new": "Danh sách mới",
"importText": "Hoặc nhập danh sách và nhiệm vụ của bạn từ các dịch vụ khác vào Vikunja:",
"import": "Nhập dữ liệu của bạn vào Vikunja"
}
@ -31,7 +31,7 @@
"username": "Tên người dùng",
"usernameEmail": "Tên người dùng hoặc Email",
"usernamePlaceholder": "ví dụ: frederick",
"email": "Email address",
"email": "Địa chỉ Email",
"emailPlaceholder": "ví dụ: frederic{'@'}vikunja.io",
"password": "Mật khẩu",
"passwordPlaceholder": "ví dụ: •••••••••••",
@ -44,20 +44,20 @@
"totpTitle": "Mã xác thực hai lớp",
"totpPlaceholder": "ví dụ: 123456",
"login": "Đăng nhập",
"createAccount": "Create account",
"createAccount": "Tạo tài khoản",
"loginWith": "Đăng nhập với {provider}",
"authenticating": "Đang xác thực…",
"openIdStateError": "Trạng thái không khớp, từ chối tiếp tục!",
"openIdGeneralError": "Đã xảy ra lỗi khi xác thực với bên thứ ba.",
"logout": "Đăng xuất",
"emailInvalid": "Please enter a valid email address.",
"usernameRequired": "Please provide a username.",
"passwordRequired": "Please provide a password.",
"showPassword": "Show the password",
"hidePassword": "Hide the password",
"noAccountYet": "Don't have an account yet?",
"alreadyHaveAnAccount": "Already have an account?",
"remember": "Stay logged in"
"emailInvalid": "Vui lòng nhập một địa chỉ email hợp lệ.",
"usernameRequired": "Vui lòng cung cấp tên người dùng.",
"passwordRequired": "Vui lòng cung cấp một mật khẩu.",
"showPassword": "Hiển thị mật khẩu",
"hidePassword": "Ẩn mật khẩu",
"noAccountYet": "Bạn chưa có tài khoản?",
"alreadyHaveAnAccount": "Đã có tài khoản?",
"remember": "Duy trì đăng nhập"
},
"settings": {
"title": "Cài đặt",
@ -68,7 +68,7 @@
"currentPasswordPlaceholder": "Nhập mật khẩu hiện tại của bạn",
"passwordsDontMatch": "Mật khẩu mới và xác nhận của nó không khớp.",
"passwordUpdateSuccess": "Mật khẩu đã được cập nhật thành công.",
"updateEmailTitle": "Update Your Email Address",
"updateEmailTitle": "Cập nhật địa chỉ e-mail của bạn",
"updateEmailNew": "Địa chỉ email mới",
"updateEmailSuccess": "Địa chỉ email của bạn đã được cập nhật thành công. Chúng tôi đã gửi cho bạn một liên kết để xác nhận nó.",
"general": {
@ -86,7 +86,7 @@
"weekStartMonday": "Thứ hai",
"language": "Ngôn ngữ",
"defaultList": "Danh sách mặc định",
"timezone": "Time Zone"
"timezone": "Múi giờ"
},
"totp": {
"title": "Xác thực hai lớp",
@ -103,7 +103,7 @@
"disableSuccess": "Xác thực hai lớp đã bị vô hiệu hóa thành công."
},
"caldav": {
"title": "Giao thức Caldav",
"title": "Giao thức CalDAV",
"howTo": "Bạn có thể kết nối Vikunja tới các máy khách CalDAV để xem và quản lý tất cả các công việc từ nhiều máy khách khác nhau. Nhập URL này vào ứng dụng khách của bạn:",
"more": "Tìm hiểu thêm về CalDAV"
},
@ -165,7 +165,7 @@
"searchSelect": "Nhấp hoặc nhấn enter để chọn danh sách này",
"shared": "Đang tham gia",
"create": {
"header": "New list",
"header": "Danh sách mới",
"titlePlaceholder": "Tên danh sách ở đây…",
"addTitleRequired": "Hãy xác định một tên.",
"createdSuccess": "Danh sách đã được tạo thành công.",
@ -323,7 +323,7 @@
"namespaces": "Góc làm việc",
"search": "Gõ để tìm kiếm một góc làm việc…",
"create": {
"title": "New namespace",
"title": "Góc làm việc mới",
"titleRequired": "Hãy đặt một tiêu đề.",
"explanation": "Góc làm việc là một tập hợp các danh sách mà bạn có thể chia sẻ và sử dụng để sắp xếp các danh sách của mình. Trên thực tế, mọi danh sách đều thuộc về một góc làm việc.",
"tooltip": "Góc làm việc là gì?",
@ -335,7 +335,7 @@
"archiveText": "Bạn sẽ không thể chỉnh sửa góc làm việc này hoặc tạo danh sách mới cho đến khi bạn bỏ lưu trữ nó. Điều này cũng sẽ lưu trữ tất cả các danh sách trong góc làm việc này.",
"unarchiveText": "Bạn có thể tạo danh sách mới hoặc chỉnh sửa nó.",
"success": "Góc làm việc đã lưu trữ thành công.",
"unarchiveSuccess": "The namespace was successfully un-archived.",
"unarchiveSuccess": "Góc làm việc đã được bỏ lưu trữ thành công.",
"description": "Nếu một góc làm việc được lưu trữ, bạn không thể tạo thêm danh sách hoặc chỉnh sửa nó."
},
"delete": {
@ -385,14 +385,14 @@
"showDoneTasks": "Hiển thị các công việc đã hoàn thành",
"sortAlphabetically": "Xếp theo bảng chữ cái",
"enablePriority": "Bật Bộ lọc theo mức độ ưu tiên",
"enablePercentDone": "Bật Bộ lọc theo tỉ lệ % hoàn thành",
"enablePercentDone": "Bật Bộ lọc theo Tiến độ",
"dueDateRange": "Phạm vi ngày đến hạn",
"startDateRange": "Phạm vi Ngày bắt đầu",
"endDateRange": "Phạm vi Ngày Kết thúc",
"reminderRange": "Phạm vi Ngày nhắc nhở"
},
"create": {
"title": "New Saved Filter",
"title": "Bộ lọc đã lưu mới",
"description": "Bộ lọc sẵn là một danh sách ảo được chọn từ một tập hợp các bộ lọc. Sau khi được tạo, nó sẽ xuất hiện trong một không gian làm việc đặc biệt.",
"action": "Tạo thêm bộ lọc sẵn"
},
@ -485,7 +485,8 @@
"showMenu": "Hiển thị menu",
"hideMenu": "Ẩn menu",
"forExample": "Ví dụ:",
"welcomeBack": "Mừng quá! Bạn trở lại rồi."
"welcomeBack": "Mừng quá! Bạn trở lại rồi.",
"custom": "Tuỳ chỉnh"
},
"input": {
"resetColor": "Đặt lại màu",
@ -524,6 +525,57 @@
"multiselect": {
"createPlaceholder": "Tạo mới",
"selectPlaceholder": "Nhấp hoặc nhấn enter để chọn"
},
"datepickerRange": {
"to": "Đến",
"from": "Từ",
"fromto": "{from} đến {to}",
"ranges": {
"today": "Hôm nay",
"thisWeek": "Tuần này",
"restOfThisWeek": "Toàn bộ ngày còn lại trong tuần này",
"nextWeek": "Tuần tới",
"next7Days": "7 ngày tới",
"lastWeek": "Tuần trước",
"thisMonth": "Tháng này",
"restOfThisMonth": "Toàn bộ ngày còn lại trong tháng này",
"nextMonth": "Tháng tới",
"next30Days": "30 ngày tới",
"lastMonth": "Tháng trước",
"thisYear": "Năm nay",
"restOfThisYear": "Toàn bộ ngày còn lại trong năm"
}
},
"datemathHelp": {
"canuse": "Bạn có thể sử dụng biểu thức tính ngày để lọc những ngày liên quan.",
"learnhow": "Xem cách hoạt động",
"title": "Tính Ngày",
"intro": "Tính Ngày cho phép bạn xác định những ngày liên quan được xử lý bởi Vikunja khi áp dụng bộ lọc.",
"expression": "Mỗi Biểu thức tính ngày bắt đầu bằng một ngày cố định, có thể là {0}, hoặc kết thúc bằng {1}. Ngày cố định này có thể được theo sau bởi một hoặc nhiều biểu thức toán học.",
"similar": "Những biểu thức này tương tự như những biểu thức được cung cấp bởi {0} và {1}.",
"add1Day": "Thêm một ngày",
"minus1Day": "Bớt đi một ngày",
"roundDay": "Làm tròn đến ngày gần nhất",
"supportedUnits": "Các đơn vị thời gian hỗ trợ là:",
"someExamples": "Một vài ví dụ về cách hiển thị thời gian:",
"units": {
"seconds": "Giây",
"minutes": "Phút",
"hours": "Giờ",
"days": "Ngày",
"weeks": "Tuần",
"months": "Tháng",
"years": "Năm"
},
"examples": {
"now": "Ngay bây giờ",
"in24h": "Trong vòng 24h",
"today": "Hôm nay lúc 00:00",
"beginningOfThisWeek": "Bắt đầu tuần này lúc 00:00",
"endOfThisWeek": "Cuối tuần này",
"in30Days": "Trong 30 ngày",
"datePlusMonth": "{0} thêm một tháng kể từ lúc 00:00 ngày hôm đó"
}
}
},
"task": {
@ -541,12 +593,9 @@
"titleCurrent": "Công việc hiện tại",
"titleDates": "Công việc từ {from} cho đến {to}",
"noDates": "Hiển thị công việc không có ngày tháng",
"current": "Công việc hiện tại",
"from": "Công việc từ",
"until": "cho đến",
"today": "Hôm nay",
"nextWeek": "Tuần tới",
"nextMonth": "Tháng tới",
"overdue": "Hiển thị công việc quá hạn",
"fromuntil": "Công việc từ {from} cho đến {until}",
"select": "Chọn khoảng ngày",
"noTasks": "Hôm nay thảnh thơi — Hãy tận hưởng ngày tuyệt vời!"
},
"detail": {
@ -554,7 +603,7 @@
"chooseStartDate": "Bấm vào đây để đặt ngày bắt đầu",
"chooseEndDate": "Bấm vào đây để đặt ngày kết thúc",
"move": "Di chuyển công việc sang một danh sách khác",
"done": "Mark task done!",
"done": "Đánh dấu đã xong!",
"undone": "Đánh dấu Chưa xong",
"created": "Đã tạo được {0} bởi {1}",
"updated": "Đã cập nhật {0}",
@ -570,22 +619,22 @@
"text2": "Thao tác này cũng sẽ xóa tất cả tệp đính kèm, lời nhắc và liên kết đến công việc này. Nó không thể hoàn tác!"
},
"actions": {
"assign": "Chỉ định một người",
"assign": "Chỉ định người",
"label": "Thêm nhãn",
"priority": "Mức độ ưu tiên",
"dueDate": "Đặt ngày đến hạn",
"startDate": "Chọn ngày bắt đầu",
"endDate": "Chọn ngày kết thúc",
"reminders": "Thiết lập nhắc nhở",
"repeatAfter": "Đặt khoảng lặp lại",
"percentDone": "Chọn tỉ lệ hoàn thành",
"attachments": "Đính kèm tệp",
"relatedTasks": "Thêm liên kết công việc",
"moveList": "Di chuyển công việc",
"color": "Chọn màu",
"delete": "Loại bỏ công việc",
"favorite": "Lưu thành ưa thích",
"unfavorite": "Gỡ khỏi ưa thích"
"repeatAfter": "Chọn chu kì lặp",
"percentDone": "Đặt tiến trình",
"attachments": "Thêm Tệp đính kèm",
"relatedTasks": "Thêm Quan hệ",
"moveList": "Di chuyển",
"color": "Đặt màu",
"delete": "Xóa",
"favorite": "Thêm vào mục yêu thích",
"unfavorite": "Xóa khỏi mục yêu thích"
}
},
"attributes": {
@ -598,7 +647,7 @@
"dueDate": "Ngày hết hạn",
"endDate": "Ngày kết thúc",
"labels": "Nhãn",
"percentDone": "Tiến độ hoàn thành",
"percentDone": "Tiến độ",
"priority": "Mức độ ưu tiên",
"relatedTasks": "Công việc liên quan",
"reminders": "Nhắc nhở",
@ -785,17 +834,20 @@
"general": "Tổng quan",
"allPages": "Các phím tắt này hoạt động ở mọi nơi.",
"currentPageOnly": "Các phím tắt này chỉ hoạt động ở trang hiện tại.",
"somePagesOnly": "Các phím tắt này chỉ hoạt động trên một số trang.",
"toggleMenu": "Bật/tắt Menu",
"quickSearch": "Mở thanh tìm kiếm/thao tác nhanh",
"then": "sau đó",
"task": {
"title": "Trang công việc",
"done": "Done",
"assign": "Chỉ định một người",
"done": "Đánh dấu công việc hoàn thành / chưa xong",
"assign": "Chỉ định công việc cho một người",
"labels": "Thêm nhãn cho công việc này",
"dueDate": "Thay đổi ngày hết hạn của công việc này",
"attachment": "Thêm tệp đính kèm cho công việc này",
"related": "Sửa đổi các công việc liên kết"
"related": "Sửa đổi các công việc liên kết",
"color": "Thay đổi màu công việc này",
"move": "Dời công việc này sang danh sách khác"
},
"list": {
"title": "Xem danh sách",
@ -803,6 +855,14 @@
"switchToGanttView": "Chuyển sang biểu đồ Gantt",
"switchToKanbanView": "Chuyển sang Kanban",
"switchToTableView": "Chuyển qua xem Bảng"
},
"navigation": {
"title": "Điều hướng",
"overview": "Điều hướng đến trang tổng quan",
"upcoming": "Điều hướng đến công việc sắp tới",
"namespaces": "Điều hướng đến Không gian làm việc & danh sách",
"labels": "Điều hướng đến nhãn",
"teams": "Điều hướng đến Team"
}
},
"update": {
@ -908,7 +968,7 @@
"4015": "Bình luận không tồn tại.",
"4016": "Trường công việc không hợp lệ.",
"4017": "Bộ so sánh bộ lọc công việc không hợp lệ.",
"4018": "Invalid task filter concatenator.",
"4018": "Bộ lọc kết hợp không hợp lệ.",
"4019": "Giá trị bộ lọc công việc không hợp lệ.",
"5001": "Góc làm việc không có nữa.",
"5003": "Bạn chưa được phép bước vào vào góc làm việc được chỉ định.",

View File

@ -35,7 +35,6 @@ export function error(e, actions = []) {
text: getErrorText(e),
actions: actions,
})
console.error(e, actions)
}
export function success(e, actions = []) {

View File

@ -7,6 +7,7 @@ export default class BackgroundImageModel extends AbstractModel {
url: '',
thumb: '',
info: {},
blurHash: '',
}
}
}

View File

@ -4,7 +4,7 @@ export default class EmailUpdateModel extends AbstractModel {
defaults() {
return {
newEmail: '',
passwort: '',
password: '',
}
}
}

View File

@ -20,7 +20,7 @@ export default class ListModel extends AbstractModel {
this.owner = new UserModel(this.owner)
if(typeof this.subscription !== 'undefined' && this.subscription !== null) {
if (typeof this.subscription !== 'undefined' && this.subscription !== null) {
this.subscription = new SubscriptionModel(this.subscription)
}
@ -44,6 +44,7 @@ export default class ListModel extends AbstractModel {
isFavorite: false,
subscription: null,
position: 0,
backgroundBlurHash: '',
created: null,
updated: null,

View File

@ -3,6 +3,8 @@ import {saveLastVisited} from '@/helpers/saveLastVisited'
import {store} from '@/store'
import {saveListView, getListView} from '@/helpers/saveListView'
import {parseDateOrString} from '@/helpers/time/parseDateOrString'
import {getNextWeekDate} from '@/helpers/time/getNextWeekDate'
import HomeComponent from '../views/Home.vue'
import NotFoundComponent from '../views/404.vue'
@ -13,7 +15,7 @@ import RegisterComponent from '../views/user/Register.vue'
import OpenIdAuth from '../views/user/OpenIdAuth.vue'
import DataExportDownload from '../views/user/DataExportDownload.vue'
// Tasks
import ShowTasksInRangeComponent from '../views/tasks/ShowTasksInRange.vue'
import UpcomingTasksComponent from '../views/tasks/ShowTasks.vue'
import LinkShareAuthComponent from '../views/sharing/LinkSharingAuth.vue'
import ListNamespaces from '../views/namespaces/ListNamespaces.vue'
import TaskDetailView from '../views/tasks/TaskDetailView.vue'
@ -248,7 +250,13 @@ const router = createRouter({
{
path: '/tasks/by/upcoming',
name: 'tasks.range',
component: ShowTasksInRangeComponent,
component: UpcomingTasksComponent,
props: route => ({
dateFrom: parseDateOrString(route.query.from as string, new Date()),
dateTo: parseDateOrString(route.query.to as string, getNextWeekDate()),
showNulls: route.query.showNulls === 'true',
showOverdue: route.query.showOverdue === 'true',
}),
},
{
path: '/lists/new/:namespaceId/',

View File

@ -2,6 +2,31 @@ import axios from 'axios'
import {objectToSnakeCase} from '@/helpers/case'
import {getToken} from '@/helpers/auth'
function convertObject(o) {
if (o instanceof Date) {
return o.toISOString()
}
return o
}
function prepareParams(params) {
if (typeof params !== 'object') {
return params
}
for (const p in params) {
if (Array.isArray(params[p])) {
params[p] = params[p].map(convertObject)
continue
}
params[p] = convertObject(params[p])
}
return objectToSnakeCase(params)
}
export default class AbstractService {
/////////////////////////////
@ -292,7 +317,7 @@ export default class AbstractService {
const finalUrl = this.getReplacedRoute(url, model)
try {
const response = await this.http.get(finalUrl, {params})
const response = await this.http.get(finalUrl, {params: prepareParams(params)})
const result = this.modelGetFactory(response.data)
result.maxRight = Number(response.headers['x-max-right'])
return result
@ -331,7 +356,7 @@ export default class AbstractService {
const finalUrl = this.getReplacedRoute(this.paths.getAll, model)
try {
const response = await this.http.get(finalUrl, {params: params})
const response = await this.http.get(finalUrl, {params: prepareParams(params)})
this.resultCount = Number(response.headers['x-pagination-result-count'])
this.totalPages = Number(response.headers['x-pagination-total-pages'])

View File

@ -1,6 +1,8 @@
import {createStore} from 'vuex'
import {getBlobFromBlurHash} from '../helpers/getBlobFromBlurHash'
import {
BACKGROUND,
BLUR_HASH,
CURRENT_LIST,
HAS_TASKS,
KEYBOARD_SHORTCUTS_ACTIVE,
@ -44,10 +46,12 @@ export const store = createStore({
isArchived: false,
}),
background: '',
blurHash: '',
hasTasks: false,
menuActive: true,
keyboardShortcutsActive: false,
quickActionsActive: false,
modalActive: false,
},
mutations: {
[LOADING](state, loading) {
@ -83,6 +87,12 @@ export const store = createStore({
[BACKGROUND](state, background) {
state.background = background
},
[BLUR_HASH](state, blurHash) {
state.blurHash = blurHash
},
modalActive(state, active) {
state.modalActive = active
},
},
actions: {
async [CURRENT_LIST]({state, commit}, currentList) {
@ -90,6 +100,7 @@ export const store = createStore({
if (currentList === null) {
commit(CURRENT_LIST, {})
commit(BACKGROUND, null)
commit(BLUR_HASH, null)
return
}
@ -122,10 +133,15 @@ export const store = createStore({
) {
if (currentList.backgroundInformation) {
try {
const blurHash = await getBlobFromBlurHash(currentList.backgroundBlurHash)
if (blurHash) {
commit(BLUR_HASH, window.URL.createObjectURL(blurHash))
}
const listService = new ListService()
const background = await listService.background(currentList)
commit(BACKGROUND, background)
} catch(e) {
} catch (e) {
console.error('Error getting background image for list', currentList.id, e)
}
}
@ -133,6 +149,7 @@ export const store = createStore({
if (typeof currentList.backgroundInformation === 'undefined' || currentList.backgroundInformation === null) {
commit(BACKGROUND, null)
commit(BLUR_HASH, null)
}
commit(CURRENT_LIST, currentList)

View File

@ -133,9 +133,19 @@ export default {
console.debug('Could not add assignee to task in kanban, task not found', t)
return r
}
// FIXME: direct store manipulation (task)
t.task.assignees.push(user)
ctx.commit('kanban/setTaskInBucketByIndex', t, { root: true })
const assignees = [
...t.task.assignees,
user,
]
ctx.commit('kanban/setTaskInBucketByIndex', {
...t,
task: {
...t.task,
assignees,
},
}, {root: true})
return r
},
@ -153,15 +163,15 @@ export default {
return response
}
for (const a in t.task.assignees) {
if (t.task.assignees[a].id === user.id) {
// FIXME: direct store manipulation (task)
t.task.assignees.splice(a, 1)
break
}
}
const assignees = t.task.assignees.filter(({ id }) => id !== user.id)
ctx.commit('kanban/setTaskInBucketByIndex', t, {root: true})
ctx.commit('kanban/setTaskInBucketByIndex', {
...t,
task: {
...t.task,
assignees,
},
}, {root: true})
return response
},
@ -179,17 +189,19 @@ export default {
console.debug('Could not add label to task in kanban, task not found', t)
return r
}
const labels = [...t.task.labels]
labels.push(label)
const labels = [
...t.task.labels,
label,
]
ctx.commit('kanban/setTaskInBucketByIndex', {
task: {
labels,
...t.task,
},
...t,
}, { root: true })
task: {
...t.task,
labels,
},
}, {root: true})
return r
},
@ -209,20 +221,14 @@ export default {
}
// Remove the label from the list
const labels = [...t.task.labels]
for (const l in labels) {
if (labels[l].id === label.id) {
labels.splice(l, 1)
break
}
}
const labels = t.task.labels.filter(({ id }) => id !== label.id)
ctx.commit('kanban/setTaskInBucketByIndex', {
task: {
labels,
...t.task,
},
...t,
task: {
...t.task,
labels,
},
}, {root: true})
return response

View File

@ -6,6 +6,6 @@ export const MENU_ACTIVE = 'menuActive'
export const KEYBOARD_SHORTCUTS_ACTIVE = 'keyboardShortcutsActive'
export const QUICK_ACTIONS_ACTIVE = 'quickActionsActive'
export const BACKGROUND = 'background'
export const BLUR_HASH = 'blurHash'
export const CONFIG = 'config'
export const AUTH = 'auth'

View File

@ -23,7 +23,7 @@ $filter-container-top-link-share-list: -47px;
display: flex;
justify-content: flex-end;
.button:not(:last-child) {
.button:not(:last-of-type) {
margin-right: .5rem;
}
}

View File

@ -1,9 +1,182 @@
// Vikunja colors as CSS custom properties
:root {
// Core Bulma color variables
// Added (from bulma-css-variables/css/bulma.css) to fix issues with undefined variables
// This section should be removed once bulma/sass scoping issues are fixed
// see https://kolaente.dev/vikunja/frontend/issues/1064
// Variables overriden in Vikunja specific rules below are commented out
//--scheme-main: white;
--scheme-main-bis: #fafafa;
--scheme-main-ter: whitesmoke;
--scheme-invert: #0a0a0a;
--scheme-invert-rgb: 10.2, 10.2, 10.2;
--scheme-invert-bis: #121212;
--scheme-invert-ter: #242424;
--background: whitesmoke;
//--border: #dbdbdb;
--border-rgb: 219.3, 219.3, 219.3;
--border-hover: #b5b5b5;
--border-light: #ededed;
--border-light-hover: #b5b5b5;
--text: #4a4a4a;
--text-invert: #fff;
--text-light: #7a7a7a;
--text-strong: #363636;
--code: #da1039;
--code-background: var(--background, whitesmoke);
--pre: var(--text, #4a4a4a);
--pre-background: var(--background, whitesmoke);
--link-visited: #b86bff;
//--link-hover: #363636;
--link-hover-border: #b5b5b5;
--link-focus: #363636;
--link-focus-border: var(--link, #485fc7);
--link-active: #363636;
--link-active-border: #4a4a4a;
//--white-h: 0deg;
//--white-s: 0%;
//--white-l: 100%;
//--white-a: 1;
//--white: hsla(var(--white-h), var(--white-s), var(--white-l), var(--white-a));
--white-invert-l: 4%;
--white-invert: #0a0a0a;
--white-light-l: 100%;
--white-light: hsla(var(--white-h), var(--white-s), var(--white-light-l), var(--white-a));
--white-dark-l: 29%;
--white-dark: hsla(var(--white-h), var(--white-s), var(--white-dark-l), var(--white-a));
//--black-h: 0deg;
//--black-s: 0%;
//--black-l: 4%;
//--black-a: 1;
//--black: hsla(var(--black-h), var(--black-s), var(--black-l), var(--black-a));
--black-invert-l: 100%;
--black-invert: white;
--black-light-l: 96%;
--black-light: hsla(var(--black-h), var(--black-s), var(--black-light-l), var(--black-a));
--black-dark-l: 57%;
--black-dark: hsla(var(--black-h), var(--black-s), var(--black-dark-l), var(--black-a));
--light-h: 0deg;
--light-s: 0%;
--light-l: 96%;
--light-a: 1;
--light: hsla(var(--light-h), var(--light-s), var(--light-l), var(--light-a));
--light-invert-l: 0%;
--light-invert: rgba(0, 0, 0, 0.7);
--light-light-l: 96%;
--light-light: hsla(var(--light-h), var(--light-s), var(--light-light-l), var(--light-a));
--light-dark-l: 29%;
--light-dark: hsla(var(--light-h), var(--light-s), var(--light-dark-l), var(--light-a));
--dark-h: 0deg;
--dark-s: 0%;
--dark-l: 21%;
--dark-a: 1;
--dark: hsla(var(--dark-h), var(--dark-s), var(--dark-l), var(--dark-a));
--dark-invert-l: 100%;
--dark-invert: #fff;
--dark-light-l: 96%;
--dark-light: hsla(var(--dark-h), var(--dark-s), var(--dark-light-l), var(--dark-a));
--dark-dark-l: 54%;
--dark-dark: hsla(var(--dark-h), var(--dark-s), var(--dark-dark-l), var(--dark-a));
//--primary-h: 171deg;
//--primary-s: 100%;
//--primary-l: 41%;
//--primary-a: 1;
//--primary: hsla(var(--primary-h), var(--primary-s), var(--primary-l), var(--primary-a));
--primary-invert-l: 100%;
--primary-invert: #fff;
--primary-light-l: 96%;
--primary-light: hsla(var(--primary-h), var(--primary-s), var(--primary-light-l), var(--primary-a));
--primary-dark-l: 29%;
--primary-dark: hsla(var(--primary-h), var(--primary-s), var(--primary-dark-l), var(--primary-a));
--link-h: 229deg;
--link-s: 53%;
--link-l: 53%;
--link-a: 1;
//--link: hsla(var(--link-h), var(--link-s), var(--link-l), var(--link-a));
--link-invert-l: 100%;
--link-invert: #fff;
--link-light-l: 96%;
--link-light: hsla(var(--link-h), var(--link-s), var(--link-light-l), var(--link-a));
--link-dark-l: 47%;
--link-dark: hsla(var(--link-h), var(--link-s), var(--link-dark-l), var(--link-a));
--info-h: 207deg;
--info-s: 61%;
--info-l: 53%;
--info-a: 1;
--info: hsla(var(--info-h), var(--info-s), var(--info-l), var(--info-a));
--info-invert-l: 100%;
--info-invert: #fff;
--info-light-l: 96%;
--info-light: hsla(var(--info-h), var(--info-s), var(--info-light-l), var(--info-a));
--info-dark-l: 41%;
--info-dark: hsla(var(--info-h), var(--info-s), var(--info-dark-l), var(--info-a));
//--success-h: 153deg;
//--success-s: 53%;
//--success-l: 53%;
//--success-a: 1;
//--success: hsla(var(--success-h), var(--success-s), var(--success-l), var(--success-a));
--success-invert-l: 100%;
--success-invert: #fff;
--success-light-l: 96%;
--success-light: hsla(var(--success-h), var(--success-s), var(--success-light-l), var(--success-a));
--success-dark-l: 31%;
--success-dark: hsla(var(--success-h), var(--success-s), var(--success-dark-l), var(--success-a));
//--warning-h: 44deg;
//--warning-s: 100%;
//--warning-l: 77%;
//--warning-a: 1;
//--warning: hsla(var(--warning-h), var(--warning-s), var(--warning-l), var(--warning-a));
--warning-invert-l: 0%;
--warning-invert: rgba(0, 0, 0, 0.7);
--warning-light-l: 96%;
--warning-light: hsla(var(--warning-h), var(--warning-s), var(--warning-light-l), var(--warning-a));
--warning-dark-l: 29%;
--warning-dark: hsla(var(--warning-h), var(--warning-s), var(--warning-dark-l), var(--warning-a));
//--danger-h: 348deg;
//--danger-s: 86%;
//--danger-l: 61%;
//--danger-a: 1;
//--danger: hsla(var(--danger-h), var(--danger-s), var(--danger-l), var(--danger-a));
--danger-invert-l: 100%;
--danger-invert: #fff;
--danger-light-l: 96%;
--danger-light: hsla(var(--danger-h), var(--danger-s), var(--danger-light-l), var(--danger-a));
--danger-dark-l: 43%;
--danger-dark: hsla(var(--danger-h), var(--danger-s), var(--danger-dark-l), var(--danger-a));
--input-color: var(--text-strong, #363636);
--input-background-color: var(--scheme-main, white);
//--input-border-color: var(--border, #dbdbdb);
--input-shadow: inset 0 0.0625em 0.125em rgba(var(--scheme-invert-rgb, 10.2, 10.2, 10.2), 0.05);
--input-placeholder-color: rgba(54, 54, 54, 0.3);
--input-hover-color: var(--text-strong, #363636);
--input-hover-border-color: var(--border-hover, #b5b5b5);
--input-focus-color: var(--text-strong, #363636);
--input-focus-border-color: var(--link, #485fc7);
--input-focus-box-shadow-color: var(--input-focus-box-shadow-color-hsla, rgba(72, 95, 199, 0.25));
--input-disabled-color: var(--text-light, #7a7a7a);
//--input-disabled-background-color: var(--background, whitesmoke);
//--input-disabled-border-color: var(--background, whitesmoke);
--input-disabled-placeholder-color: rgba(122, 122, 122, 0.3);
--input-arrow: var(--link, #485fc7);
--input-icon-color: var(--border, #dbdbdb);
--input-icon-active-color: var(--text, #4a4a4a);
--black-bis: #121212;
--black-ter: #242424;
//--grey-darker: #363636;
//--grey-dark: #4a4a4a;
//--grey: #7a7a7a;
//--grey-light: #b5b5b5;
//--grey-lighter: #dbdbdb;
--white-ter: whitesmoke;
--white-bis: #fafafa;
// END core Bulma color variables
// Vikunja specific variables
--grey-50: hsl(210, 20%, 98%);
--grey-100: hsl(220, 14.3%, 95.9%);
--grey-100-hsl: 220, 14.3%, 95.9%;
--grey-100: hsl(var(--grey-100-hsl));
--grey-200: hsl(220, 13%, 91%);
--grey-300: hsl(216, 12.2%, 83.9%);
--grey-400: hsl(217.9, 10.6%, 64.9%);
@ -14,9 +187,9 @@
--grey-800: hsl(215, 27.9%, 16.9%);
--grey-900: hsl(220.9, 39.3%, 11%);
--site-background: var(--grey-100);
--scheme-main: var(--white);
// Overrides of Bulma defaults
--scheme-main: var(--white);
--grey-darker: var(--grey-700);
--grey-dark: var(--grey-800);
--grey: var(--grey-500);
@ -66,6 +239,12 @@
--primary-a: 1;
--primary-hsl: var(--primary-h), var(--primary-s), var(--primary-l);
--primary: hsla(var(--primary-h), var(--primary-s), var(--primary-l), var(--primary-a));
--link: var(--primary);
--link-hover: hsla(var(--primary-h), var(--primary-s), var(--primary-l), .75);
--border: var(--grey-200);
--input-disabled-background-color: var(--grey-100);
--input-disabled-border-color: var(--grey-300);
// END Overrides of Bulma defaults
@ -76,12 +255,6 @@
--card-border-color: var(--grey-200);
--logo-text-color: hsl(180, 1%, 15%);
--link: var(--primary);
--link-hover: hsla(var(--primary-h), var(--primary-s), var(--primary-l), .75);
--border: var(--grey-200);
--input-disabled-background-color: var(--grey-100);
--input-disabled-border-color: var(--grey-300);
&.dark {
// Light mode colours reversed for dark mode
--grey-900-hsl: 210, 20%, 98%;

View File

@ -1,12 +1,16 @@
.app-container.has-background,
.link-share-container.has-background {
background-position: center;
background-size: cover;
background-repeat: no-repeat;
background-attachment: fixed;
min-height: 100vh;
position: relative;
// FIXME: move to pagination component
&, .app-container-background {
background-position: center;
background-size: cover;
background-repeat: no-repeat;
background-attachment: fixed;
min-height: 100vh;
}
// FIXME: move to pagination component
.pagination-link:not(.is-current) {
background: var(--grey-100);
}
@ -32,4 +36,21 @@
border-radius: $radius !important;
}
}
}
}
.app-container-background {
width: 100vw;
height: 100vh;
position: fixed;
z-index: 0;
}
.background-fade-in {
opacity: 0;
transition: opacity $transition;
transition-delay: $transition-duration * 2; // To fake an appearing background
&.is-visible {
opacity: 1;
}
}

View File

@ -18,6 +18,11 @@
box-shadow: 0 0 0 2px hsla(var(--primary-hsl), 0.5);
}
:root {
// Bulma sets this to "scroll" which gives us a scrollbar even if there's no content to scroll
--body-overflow-y: auto;
}
body {
background: var(--site-background);
min-height: 100vh;
@ -65,7 +70,7 @@ h6 {
}
.has-overflow {
overflow: visible;
overflow: visible !important;
}
.has-horizontal-overflow {

View File

@ -1,7 +1,7 @@
/* eslint-disable no-console */
/* eslint-disable no-undef */
const workboxVersion = 'v6.4.2'
const workboxVersion = 'v6.5.2'
importScripts( `/workbox-${workboxVersion}/workbox-sw.js`)
workbox.setConfig({
modulePathPrefix: `/workbox-${workboxVersion}`,

View File

@ -50,7 +50,11 @@
/>
</div>
</div>
<ShowTasks class="mt-4" :show-all="true" v-if="hasLists" :key="showTasksKey"/>
<ShowTasks
v-if="hasLists"
class="mt-4"
:key="showTasksKey"
/>
</div>
</template>
@ -83,13 +87,14 @@ const userInfo = computed(() => store.state.auth.info)
const hasTasks = computed(() => store.state.hasTasks)
const defaultListId = computed(() => store.state.auth.defaultListId)
const defaultNamespaceId = computed(() => store.state.namespaces.namespaces?.[0]?.id || 0)
const hasLists = computed (() => store.state.namespaces.namespaces?.[0]?.lists.length > 0)
const hasLists = computed(() => store.state.namespaces.namespaces?.[0]?.lists.length > 0)
const loading = computed(() => store.state.loading && store.state.loadingModule === 'tasks')
const deletionScheduledAt = computed(() => parseDateOrNull(store.state.auth.info?.deletionScheduledAt))
// This is to reload the tasks list after adding a new task through the global task add.
// FIXME: Should use vuex (somehow?)
const showTasksKey = ref(0)
function updateTaskList() {
showTasksKey.value++
}

View File

@ -616,7 +616,7 @@ $crazy-height-calculation-tasks: '#{$crazy-height-calculation} - 1rem - 2.5rem -
$filter-container-height: '1rem - #{$switch-view-height}';
// FIXME:
.app-content.list\.kanban {
.app-content.list\.kanban, .app-content.task\.detail {
padding-bottom: 0 !important;
}
@ -659,11 +659,12 @@ $filter-container-height: '1rem - #{$switch-view-height}';
position: relative;
margin: 0 $bucket-right-margin 0 0;
max-height: 100%;
max-height: calc(100% - 1rem); // 1rem spacing to the bottom
min-height: 20px;
width: $bucket-width;
display: flex;
flex-direction: column;
overflow: hidden; // Make sure the edges are always rounded
.tasks {
overflow: hidden auto;
@ -764,6 +765,7 @@ $filter-container-height: '1rem - #{$switch-view-height}';
background-color: var(--grey-100);
border-bottom-left-radius: $radius;
border-bottom-right-radius: $radius;
transform: none;
.button {
background-color: transparent;
@ -775,6 +777,7 @@ $filter-container-height: '1rem - #{$switch-view-height}';
}
}
// FIXME: This does not seem to work
.task-dragging {
transform: rotateZ(3deg);
transition: transform 0.18s ease;

View File

@ -299,6 +299,7 @@ export default defineComponent({
break
}
}
// FIXME: Use computed
sortTasks(this.tasks)
},

View File

@ -42,12 +42,12 @@
</Message>
</transition>
<slot />
<slot v-if="loadedListId"/>
</div>
</template>
<script setup lang="ts">
import {ref, shallowRef, computed, watchEffect} from 'vue'
import {ref, computed, watch, watchEffect} from 'vue'
import {useRoute} from 'vue-router'
import Message from '@/components/misc/message.vue'
@ -55,12 +55,12 @@ import Message from '@/components/misc/message.vue'
import ListModel from '@/models/list'
import ListService from '@/services/list'
import {store} from '@/store'
import {CURRENT_LIST} from '@/store/mutation-types'
import {BACKGROUND, BLUR_HASH, CURRENT_LIST} from '@/store/mutation-types'
import {getListTitle} from '@/helpers/getListTitle'
import {saveListToHistory} from '@/modules/listHistory'
import { useTitle } from '@/composables/useTitle'
import {useTitle} from '@/composables/useTitle'
import {useStore} from 'vuex'
const props = defineProps({
listId: {
@ -74,8 +74,9 @@ const props = defineProps({
})
const route = useRoute()
const store = useStore()
const listService = shallowRef(new ListService())
const listService = ref(new ListService())
const loadedListId = ref(0)
const currentList = computed(() => {
@ -87,7 +88,22 @@ const currentList = computed(() => {
} : store.state.currentList
})
// call again the method if the listId changes
// watchEffect would be called every time the prop would get a value assigned, even if that value was the same as before.
// This resulted in loading and setting the list multiple times, even when navigating away from it.
// This caused wired bugs where the list background would be set on the home page but only right after setting a new
// list background and then navigating to home. It also highlighted the list in the menu and didn't allow changing any
// of it, most likely due to the rights not being properly populated.
watch(
() => props.listId,
(listId) => {
loadList(listId)
},
{
immediate: true,
},
)
// call the method again if the listId changes
watchEffect(() => loadList(props.listId))
useTitle(() => currentList.value.id ? getListTitle(currentList.value) : '')
@ -118,11 +134,21 @@ async function loadList(listIdToLoad: number) {
)
&& typeof currentList.value !== 'undefined' && currentList.value.maxRight !== null
) {
loadedListId.value = props.listId
return
}
console.debug(`Loading list, props.viewName = ${props.viewName}, $route.params =`, route.params, `, loadedListId = ${loadedListId.value}, currentList = `, currentList.value)
// Set the current list to the one we're about to load so that the title is already shown at the top
loadedListId.value = 0
const listFromStore = store.getters['lists/getListById'](listData.id)
if (listFromStore !== null) {
store.commit(BACKGROUND, null)
store.commit(BLUR_HASH, null)
store.commit(CURRENT_LIST, listFromStore)
}
// We create an extra list object instead of creating it in list.value because that would trigger a ui update which would result in bad ux.
const list = new ListModel(listData)
try {
@ -139,6 +165,7 @@ async function loadList(listIdToLoad: number) {
@media screen and (max-width: $tablet) {
display: flex;
justify-content: center;
flex-direction: column;
}
}
@ -149,7 +176,7 @@ async function loadList(listIdToLoad: number) {
font-size: .75rem;
box-shadow: var(--shadow-sm);
height: $switch-view-height;
margin-bottom: 1rem;
margin: 0 auto 1rem;
padding: .5rem;
a {

View File

@ -35,16 +35,25 @@
v-model="backgroundSearchTerm"
/>
<p class="unsplash-link">
<a href="https://unsplash.com" rel="noreferrer noopener nofollow" target="_blank">{{ $t('list.background.poweredByUnsplash') }}</a>
<a href="https://unsplash.com" rel="noreferrer noopener nofollow" target="_blank">
{{ $t('list.background.poweredByUnsplash') }}
</a>
</p>
<div class="image-search-result">
<a
:key="im.id"
:style="{'background-image': `url(${backgroundThumbs[im.id]})`}"
:style="{'background-image': `url(${backgroundBlurHashes[im.id]})`}"
@click="() => setBackground(im.id)"
class="image"
v-for="im in backgroundSearchResult">
<a :href="`https://unsplash.com/@${im.info.author}`" rel="noreferrer noopener nofollow" target="_blank" class="info">
<transition name="fade">
<img :src="backgroundThumbs[im.id]" alt="" v-if="backgroundThumbs[im.id]"/>
</transition>
<a
:href="`https://unsplash.com/@${im.info.author}`"
rel="noreferrer noopener nofollow"
target="_blank"
class="info">
{{ im.info.authorName }}
</a>
</a>
@ -65,6 +74,8 @@
<script>
import {mapState} from 'vuex'
import {getBlobFromBlurHash} from '../../../helpers/getBlobFromBlurHash'
import BackgroundUnsplashService from '../../../services/backgroundUnsplash'
import BackgroundUploadService from '../../../services/backgroundUpload'
import ListService from '@/services/list'
@ -83,6 +94,7 @@ export default {
backgroundSearchTerm: '',
backgroundSearchResult: [],
backgroundThumbs: {},
backgroundBlurHashes: {},
currentPage: 1,
// We're using debounce to not search on every keypress but with a delay.
@ -120,8 +132,16 @@ export default {
this.currentPage = page
const result = await this.backgroundService.getAll({}, {s: this.backgroundSearchTerm, p: page})
this.backgroundSearchResult = this.backgroundSearchResult.concat(result)
result.forEach(async background => {
this.backgroundThumbs[background.id] = await this.backgroundService.thumb(background)
result.forEach(background => {
getBlobFromBlurHash(background.blurHash)
.then(b => {
this.backgroundBlurHashes[background.id] = window.URL.createObjectURL(b)
})
this.backgroundService.thumb(background)
.then(b => {
this.backgroundThumbs[background.id] = b
})
})
},
@ -134,6 +154,7 @@ export default {
const list = await this.backgroundService.update({id: backgroundId, listId: this.$route.params.listId})
await this.$store.dispatch(CURRENT_LIST, list)
this.$store.commit('namespaces/setListInNamespaceById', list)
this.$store.commit('lists/setList', list)
this.$message.success({message: this.$t('list.background.success')})
},
@ -145,6 +166,7 @@ export default {
const list = await this.backgroundUploadService.create(this.$route.params.listId, this.$refs.backgroundUploadInput.files[0])
await this.$store.dispatch(CURRENT_LIST, list)
this.$store.commit('namespaces/setListInNamespaceById', list)
this.$store.commit('lists/setList', list)
this.$message.success({message: this.$t('list.background.success')})
},
@ -152,6 +174,7 @@ export default {
const list = await this.listService.removeBackground(this.currentList)
await this.$store.dispatch(CURRENT_LIST, list)
this.$store.commit('namespaces/setListInNamespaceById', list)
this.$store.commit('lists/setList', list)
this.$message.success({message: this.$t('list.background.removeSuccess')})
this.$router.back()
},
@ -162,82 +185,88 @@ export default {
<style lang="scss" scoped>
.list-background-setting {
.unsplash-link {
text-align: right;
font-size: .8rem;
.unsplash-link {
text-align: right;
font-size: .8rem;
a {
color: var(--grey-800);
}
}
a {
color: var(--grey-800);
}
}
.image-search-result {
margin-top: 1rem;
display: flex;
flex-flow: row wrap;
.image-search-result {
margin-top: 1rem;
display: flex;
flex-flow: row wrap;
.image {
width: calc(100% / 5 - 1rem);
height: 120px;
margin: .5rem;
background-size: cover;
background-position: center;
display: flex;
.image {
width: calc(100% / 5 - 1rem);
height: 120px;
margin: .5rem;
background-size: cover;
background-position: center;
display: flex;
position: relative;
@media screen and (min-width: $desktop) {
&:nth-child(5n) {
break-after: always;
}
}
@media screen and (min-width: $desktop) {
&:nth-child(5n) {
break-after: always;
}
}
@media screen and (max-width: $desktop) {
width: calc(100% / 4 - 1rem);
@media screen and (max-width: $desktop) {
width: calc(100% / 4 - 1rem);
&:nth-child(4n) {
break-after: always;
}
}
&:nth-child(4n) {
break-after: always;
}
}
@media screen and (max-width: $tablet) {
width: calc(100% / 2 - 1rem);
@media screen and (max-width: $tablet) {
width: calc(100% / 2 - 1rem);
&:nth-child(2n) {
break-after: always;
}
}
&:nth-child(2n) {
break-after: always;
}
}
@media screen and (max-width: ($mobile)) {
width: calc(100% - 1rem);
@media screen and (max-width: ($mobile)) {
width: calc(100% - 1rem);
&:nth-child(1n) {
break-after: always;
}
}
&:nth-child(1n) {
break-after: always;
}
}
.info {
align-self: flex-end;
display: block;
opacity: 0;
width: 100%;
padding: .25rem 0;
text-align: center;
background: rgba(0, 0, 0, 0.5);
font-size: .75rem;
font-weight: bold;
color: var(--white);
transition: opacity $transition;
}
.info {
align-self: flex-end;
display: block;
opacity: 0;
width: 100%;
padding: .25rem 0;
text-align: center;
background: rgba(0, 0, 0, 0.5);
font-size: .75rem;
font-weight: bold;
color: var(--white);
transition: opacity $transition;
position: absolute;
}
&:hover .info {
opacity: 1;
}
}
}
img {
object-fit: cover;
}
.is-load-more-button {
margin: 1rem auto 0 !important;
display: block;
width: 200px;
}
&:hover .info {
opacity: 1;
}
}
}
.is-load-more-button {
margin: 1rem auto 0 !important;
display: block;
width: 200px;
}
}
</style>

View File

@ -1,283 +1,236 @@
<template>
<div class="is-max-width-desktop show-tasks">
<fancycheckbox
@change="setDate"
class="is-pulled-right"
v-if="!showAll"
v-model="showNulls"
>
{{ $t('task.show.noDates') }}
</fancycheckbox>
<h3 v-if="showAll && tasks.length > 0">
{{ $t('task.show.current') }}
<div class="is-max-width-desktop has-text-left ">
<h3 class="mb-2 title">
{{ pageTitle }}
</h3>
<h3 v-else-if="!showAll" class="mb-2">
{{ $t('task.show.from') }}
<flat-pickr
:class="{ 'disabled': loading}"
:config="flatPickerConfig"
:disabled="loading"
@on-close="setDate"
class="input"
v-model="cStartDate"
/>
{{ $t('task.show.until') }}
<flat-pickr
:class="{ 'disabled': loading}"
:config="flatPickerConfig"
:disabled="loading"
@on-close="setDate"
class="input"
v-model="cEndDate"
/>
</h3>
<div v-if="!showAll" class="mb-4">
<x-button variant="secondary" @click="showTodaysTasks()" class="mr-2">{{ $t('task.show.today') }}</x-button>
<x-button variant="secondary" @click="setDatesToNextWeek()" class="mr-2">{{ $t('task.show.nextWeek') }}</x-button>
<x-button variant="secondary" @click="setDatesToNextMonth()">{{ $t('task.show.nextMonth') }}</x-button>
</div>
<p v-if="!showAll" class="show-tasks-options">
<datepicker-with-range @dateChanged="setDate">
<template #trigger="{toggle}">
<x-button @click.prevent.stop="toggle()" variant="primary" :shadow="false" class="mb-2">
{{ $t('task.show.select') }}
</x-button>
</template>
</datepicker-with-range>
<fancycheckbox @change="setShowNulls" class="mr-2">
{{ $t('task.show.noDates') }}
</fancycheckbox>
<fancycheckbox @change="setShowOverdue">
{{ $t('task.show.overdue') }}
</fancycheckbox>
</p>
<template v-if="!loading && (!tasks || tasks.length === 0) && showNothingToDo">
<h3 class="nothing">{{ $t('task.show.noTasks') }}</h3>
<LlamaCool class="llama-cool" />
<h3 class="has-text-centered mt-6">{{ $t('task.show.noTasks') }}</h3>
<LlamaCool class="llama-cool"/>
</template>
<div :class="{ 'is-loading': loading}" class="spinner"></div>
<card :padding="false" class="has-overflow" :has-content="false" v-if="tasks && tasks.length > 0">
<div class="tasks">
<card
v-if="hasTasks"
:padding="false"
class="has-overflow"
:has-content="false"
:loading="loading"
>
<div class="p-2">
<single-task-in-list
v-for="t in tasksSorted"
:key="t.id"
class="task"
v-for="t in tasks"
:show-list="true"
:the-task="t"
@taskUpdated="updateTasks"/>
</div>
</card>
<div v-else :class="{ 'is-loading': loading}" class="spinner"></div>
</div>
</template>
<script>
import SingleTaskInList from '../../components/tasks/partials/singleTaskInList'
import {mapState} from 'vuex'
import flatPickr from 'vue-flatpickr-component'
import 'flatpickr/dist/flatpickr.css'
import Fancycheckbox from '../../components/input/fancycheckbox'
import {LOADING, LOADING_MODULE} from '../../store/mutation-types'
<script setup lang="ts">
import {computed, ref, watchEffect} from 'vue'
import {useStore} from 'vuex'
import {useRoute, useRouter} from 'vue-router'
import {useI18n} from 'vue-i18n'
import TaskModel from '@/models/task'
import {formatDate} from '@/helpers/time/formatDate'
import {setTitle} from '@/helpers/setTitle'
import Fancycheckbox from '@/components/input/fancycheckbox.vue'
import SingleTaskInList from '@/components/tasks/partials/singleTaskInList.vue'
import DatepickerWithRange from '@/components/date/datepickerWithRange.vue'
import {DATE_RANGES} from '@/components/date/dateRanges'
import {LOADING, LOADING_MODULE} from '@/store/mutation-types'
import LlamaCool from '@/assets/llama-cool.svg?component'
export default {
name: 'ShowTasks',
components: {
Fancycheckbox,
SingleTaskInList,
flatPickr,
LlamaCool,
},
data() {
return {
tasks: [],
showNulls: true,
showOverdue: false,
const store = useStore()
const route = useRoute()
const router = useRouter()
const {t} = useI18n()
cStartDate: null,
cEndDate: null,
const tasks = ref<TaskModel[]>([])
const showNothingToDo = ref<boolean>(false)
showNothingToDo: false,
}
},
props: {
startDate: Date,
endDate: Date,
showAll: Boolean,
},
created() {
this.cStartDate = this.startDate
this.cEndDate = this.endDate
this.loadPendingTasks()
},
mounted() {
setTimeout(() => this.showNothingToDo = true, 100)
},
watch: {
'$route': {
handler: 'loadPendingTasks',
deep: true,
},
startDate(newVal) {
this.cStartDate = newVal
},
endDate(newVal) {
this.cEndDate = newVal
},
},
computed: {
flatPickerConfig() {
return {
altFormat: this.$t('date.altFormatLong'),
altInput: true,
dateFormat: 'Y-m-d H:i',
enableTime: true,
time_24hr: true,
locale: {
firstDayOfWeek: this.$store.state.auth.settings.weekStart,
},
}
},
...mapState({
userAuthenticated: state => state.auth.authenticated,
loading: state => state[LOADING] && state[LOADING_MODULE] === 'tasks',
}),
},
methods: {
setDate() {
this.$router.push({
name: this.$route.name,
query: {
from: +new Date(this.cStartDate),
to: +new Date(this.cEndDate),
showOverdue: this.showOverdue,
showNulls: this.showNulls,
},
})
},
async loadPendingTasks() {
// Since this route is authentication only, users would get an error message if they access the page unauthenticated.
// Since this component is mounted as the home page before unauthenticated users get redirected
// to the login page, they will almost always see the error message.
if (!this.userAuthenticated) {
return
}
setTimeout(() => showNothingToDo.value = true, 100)
// Make sure all dates are date objects
if (typeof this.$route.query.from !== 'undefined' && typeof this.$route.query.to !== 'undefined') {
this.cStartDate = new Date(Number(this.$route.query.from))
this.cEndDate = new Date(Number(this.$route.query.to))
} else {
this.cStartDate = new Date(this.cStartDate)
this.cEndDate = new Date(this.cEndDate)
}
this.showOverdue = this.$route.query.showOverdue
this.showNulls = this.$route.query.showNulls
// Linting disabled because we explicitely enabled destructuring in vite's config, this will work.
// eslint-disable-next-line vue/no-setup-props-destructure
const {
dateFrom,
dateTo,
showNulls = false,
showOverdue = false,
} = defineProps<{
dateFrom?: Date | string,
dateTo?: Date | string,
showNulls?: Boolean,
showOverdue?: Boolean,
}>()
if (this.showAll) {
this.setTitle(this.$t('task.show.titleCurrent'))
} else {
this.setTitle(this.$t('task.show.titleDates', {
from: this.cStartDate.toLocaleDateString(),
to: this.cEndDate.toLocaleDateString(),
}))
}
const showAll = computed(() => typeof dateFrom === 'undefined' || typeof dateTo === 'undefined')
const params = {
sort_by: ['due_date', 'id'],
order_by: ['desc', 'desc'],
filter_by: ['done'],
filter_value: [false],
filter_comparator: ['equals'],
filter_concat: 'and',
filter_include_nulls: this.showNulls,
}
if (!this.showAll) {
if (this.showNulls) {
params.filter_by.push('start_date')
params.filter_value.push(this.cStartDate)
params.filter_comparator.push('greater')
const pageTitle = computed(() => {
// We need to define "key" because it is the first parameter in the array and we need the second
const predefinedRange = Object.entries(DATE_RANGES)
// eslint-disable-next-line no-unused-vars
.find(([key, value]) => dateFrom === value[0] && dateTo === value[1])
?.[0]
if (typeof predefinedRange !== 'undefined') {
return t(`input.datepickerRange.ranges.${predefinedRange}`)
}
params.filter_by.push('end_date')
params.filter_value.push(this.cEndDate)
params.filter_comparator.push('less')
}
return showAll.value
? t('task.show.titleCurrent')
: t('task.show.fromuntil', {
from: formatDate(dateFrom, 'PPP'),
until: formatDate(dateTo, 'PPP'),
})
})
const tasksSorted = computed(() => {
// Sort all tasks to put those with a due date before the ones without a due date, the
// soonest before the later ones.
// We can't use the api sorting here because that sorts tasks with a due date after
// ones without a due date.
params.filter_by.push('due_date')
params.filter_value.push(this.cEndDate)
params.filter_comparator.push('less')
const tasksWithDueDate = [...tasks.value]
.filter(t => t.dueDate !== null)
.sort((a, b) => {
const sortByDueDate = a.dueDate - b.dueDate
return sortByDueDate === 0
? b.id - a.id
: sortByDueDate
})
const tasksWithoutDueDate = [...tasks.value]
.filter(t => t.dueDate === null)
if (!this.showOverdue) {
params.filter_by.push('due_date')
params.filter_value.push(this.cStartDate)
params.filter_comparator.push('greater')
}
}
return [
...tasksWithDueDate,
...tasksWithoutDueDate,
]
})
const hasTasks = computed(() => tasks.value && tasks.value.length > 0)
const userAuthenticated = computed(() => store.state.auth.authenticated)
const loading = computed(() => store.state[LOADING] && store.state[LOADING_MODULE] === 'tasks')
const tasks = await this.$store.dispatch('tasks/loadTasks', params)
// FIXME: sort tasks in computed
// Sort all tasks to put those with a due date before the ones without a due date, the
// soonest before the later ones.
// We can't use the api sorting here because that sorts tasks with a due date after
// ones without a due date.
this.tasks = tasks.sort((a, b) => {
const sortByDueDate = b.dueDate - a.dueDate
return sortByDueDate === 0
? b.id - a.id
: sortByDueDate
})
},
// FIXME: this modification should happen in the store
updateTasks(updatedTask) {
for (const t in this.tasks) {
if (this.tasks[t].id === updatedTask.id) {
this.tasks[t] = updatedTask
// Move the task to the end of the done tasks if it is now done
if (updatedTask.done) {
this.tasks.splice(t, 1)
this.tasks.push(updatedTask)
}
break
}
}
},
setDatesToNextWeek() {
const now = new Date()
this.cStartDate = now
this.cEndDate = new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000)
this.showOverdue = false
this.setDate()
},
setDatesToNextMonth() {
const now = new Date()
this.cStartDate = now
this.cEndDate = new Date((new Date()).setMonth(now.getMonth() + 1))
this.showOverdue = false
this.setDate()
},
showTodaysTasks() {
const now = new Date()
this.cStartDate = now
this.cEndDate = new Date((new Date()).setDate(now.getDate() + 1))
this.showOverdue = true
this.setDate()
},
},
interface dateStrings {
dateFrom: string,
dateTo: string,
}
function setDate(dates: dateStrings) {
router.push({
name: route.name as string,
query: {
from: dates.dateFrom ?? dateFrom,
to: dates.dateTo ?? dateTo,
showOverdue: showOverdue ? 'true' : 'false',
showNulls: showNulls ? 'true' : 'false',
},
})
}
function setShowOverdue(show: boolean) {
router.push({
name: route.name as string,
query: {
...route.query,
showOverdue: show ? 'true' : 'false',
},
})
}
function setShowNulls(show: boolean) {
router.push({
name: route.name as string,
query: {
...route.query,
showNulls: show ? 'true' : 'false',
},
})
}
async function loadPendingTasks(from: string, to: string) {
// FIXME: HACK! This should never happen.
// Since this route is authentication only, users would get an error message if they access the page unauthenticated.
// Since this component is mounted as the home page before unauthenticated users get redirected
// to the login page, they will almost always see the error message.
if (!userAuthenticated.value) {
return
}
const params = {
sortBy: ['due_date', 'id'],
orderBy: ['desc', 'desc'],
filterBy: ['done'],
filterValue: ['false'],
filterComparator: ['equals'],
filterConcat: 'and',
filterIncludeNulls: showNulls,
}
if (!showAll.value) {
params.filterBy.push('due_date')
params.filterValue.push(to)
params.filterComparator.push('less')
// NOTE: Ideally we could also show tasks with a start or end date in the specified range, but the api
// is not capable (yet) of combining multiple filters with 'and' and 'or'.
if (!showOverdue) {
params.filterBy.push('due_date')
params.filterValue.push(from)
params.filterComparator.push('greater')
}
}
tasks.value = await store.dispatch('tasks/loadTasks', params)
}
// FIXME: this modification should happen in the store
function updateTasks(updatedTask: TaskModel) {
for (const t in tasks.value) {
if (tasks.value[t].id === updatedTask.id) {
tasks.value[t] = updatedTask
// Move the task to the end of the done tasks if it is now done
if (updatedTask.done) {
tasks.value.splice(t, 1)
tasks.value.push(updatedTask)
}
break
}
}
}
watchEffect(() => loadPendingTasks(dateFrom as string, dateTo as string))
watchEffect(() => setTitle(pageTitle.value))
</script>
<style lang="scss" scoped>
h3 {
text-align: left;
&.nothing {
text-align: center;
margin-top: 3rem;
}
:deep(.input) {
width: 190px;
vertical-align: middle;
margin: .5rem 0;
}
}
.tasks {
padding: .5rem;
.show-tasks-options {
display: flex;
flex-direction: column;
}
.llama-cool {
margin-top: 2rem;
margin: 3rem auto 0;
display: block;
}
</style>

View File

@ -1,20 +0,0 @@
<template>
<div class="content has-text-centered">
<ShowTasks
:end-date="endDate"
:start-date="startDate"
/>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import ShowTasks from './ShowTasks.vue'
function getNextWeekDate() {
return new Date((new Date()).getTime() + 7 * 24 * 60 * 60 * 1000)
}
const startDate = ref(new Date())
const endDate = ref(getNextWeekDate())
</script>

View File

@ -72,7 +72,7 @@
</transition>
<transition name="flash-background" appear>
<div class="column" v-if="activeFields.percentDone">
<!-- Percent Done -->
<!-- Progress -->
<div class="detail-title">
<icon icon="percent"/>
{{ $t('task.attributes.percentDone') }}
@ -259,6 +259,7 @@
class="is-outlined has-no-border"
icon="check-double"
variant="secondary"
v-shortcut="'t'"
>
{{ task.done ? $t('task.detail.undone') : $t('task.detail.done') }}
</x-button>
@ -356,6 +357,7 @@
@click="setFieldActive('moveList')"
variant="secondary"
icon="list"
v-shortcut="'m'"
>
{{ $t('task.detail.actions.moveList') }}
</x-button>
@ -363,6 +365,7 @@
@click="setFieldActive('color')"
variant="secondary"
icon="fill-drip"
v-shortcut="'c'"
>
{{ $t('task.detail.actions.color') }}
</x-button>
@ -520,6 +523,13 @@ export default {
},
immediate: true,
},
// Using a watcher here because the header component handles saving the task with the api but we want to decouple
// it from the page title.
'task.title': {
handler(title) {
this.setTitle(title)
},
},
},
computed: {
currentList() {

View File

@ -181,7 +181,7 @@ export default {
validateField() {
// using computed so that debounced function definition stays
return useDebounceFn((field) => {
this[`${field}Valid`] = this.$refs[field].value !== ''
this[`${field}Valid`] = this.$refs[field]?.value !== ''
}, 100)
},
},

View File

@ -135,7 +135,7 @@
import {computed, watch, ref} from 'vue'
import {useI18n} from 'vue-i18n'
import {playSoundWhenDoneKey, playPop} from '@/helpers/playPop'
import {playSoundWhenDoneKey, playPopSound} from '@/helpers/playPop'
import {availableLanguages} from '@/i18n'
import {getQuickAddMagicMode, setQuickAddMagicMode} from '@/helpers/quickAddMagicMode'
import {PrefixMode} from '@/modules/parseTaskText'
@ -230,13 +230,13 @@ export default {
watch: {
playSoundWhenDone(play) {
if (play) {
playPop()
playPopSound()
}
},
},
methods: {
async updateSettings() {
localStorage.setItem(playSoundWhenDoneKey, this.playSoundWhenDone)
localStorage.setItem(playSoundWhenDoneKey, this.playSoundWhenDone ? 'true' : 'false')
setQuickAddMagicMode(this.quickAddMagicMode)
await this.$store.dispatch('auth/saveUserSettings', {

View File

@ -13,6 +13,7 @@
"resolveJsonModule": true,
"sourceMap": true,
"baseUrl": ".",
"strictNullChecks": true,
"isolatedModules": true,
"types": [
"vite/client"

View File

@ -1,7 +1,8 @@
/// <reference types="vitest" />
import { defineConfig } from 'vite'
import {defineConfig} from 'vite'
import vue from '@vitejs/plugin-vue'
import legacyFn from '@vitejs/plugin-legacy'
const {VitePWA} = require('vite-plugin-pwa')
const path = require('path')
const {visualizer} = require('rollup-plugin-visualizer')
@ -49,6 +50,7 @@ export default defineConfig({
},
},
},
reactivityTransform: true,
}),
legacy,
svgLoader({
@ -130,7 +132,7 @@ export default defineConfig({
extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'],
},
server: {
port: 5000,
port: 4173,
strictPort: true,
},
build: {

3203
yarn.lock

File diff suppressed because it is too large Load Diff