Compare commits

...

309 Commits

Author SHA1 Message Date
a94198f2eb Fixed accidental change - restoring original 2022-01-08 15:52:33 -05:00
a6e7e6efa6 Changed button test to look for "Mark task done!" - to match button change 2022-01-08 15:49:50 -05:00
6f5f7b190a Changed "Done!" to "Mark task done" on green button 2022-01-08 15:48:47 -05:00
0473c385d6
fix: editor cursor color 2022-01-08 17:34:13 +01:00
68a76faacc
fix: don't reset active fields when saving
Resolves #590
2022-01-08 15:13:49 +01:00
4579dd3ce7
fix: button size on task detail view 2022-01-08 15:11:55 +01:00
f4fee26fe4 chore(deps): update dependency sass to v1.47.0 (#1333)
Reviewed-on: vikunja/frontend#1333
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-01-08 11:03:51 +00:00
00398085fd chore(deps): update dependency caniuse-lite to v1.0.30001298 (#1334)
Reviewed-on: vikunja/frontend#1334
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-01-08 10:54:58 +00:00
13c8e6dbcd fix(deps): update dependency v-tooltip to v4.0.0-beta.13 (#1332)
Reviewed-on: vikunja/frontend#1332
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-01-07 16:21:41 +00:00
1b5f8a069b chore(deps): update dependency netlify-cli to v8.6.15 (#1331)
Reviewed-on: vikunja/frontend#1331
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-01-07 16:21:27 +00:00
21fec9461d chore(deps): update dependency vitest to v0.0.139 (#1330)
Reviewed-on: vikunja/frontend#1330
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-01-07 16:21:11 +00:00
df3af739f8 chore(deps): update dependency autoprefixer to v10.4.2 (#1329)
Reviewed-on: vikunja/frontend#1329
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-01-07 16:20:45 +00:00
b08d34bc96 fix(deps): update dependency v-tooltip to v4.0.0-beta.11 (#1326)
Reviewed-on: vikunja/frontend#1326
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-01-07 08:26:54 +00:00
be03efd015 chore(deps): update dependency caniuse-lite to v1.0.30001297 (#1327)
Reviewed-on: vikunja/frontend#1327
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-01-07 08:26:35 +00:00
c353fd151d chore(deps): update dependency vitest to v0.0.136 (#1325)
Reviewed-on: vikunja/frontend#1325
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-01-06 21:23:31 +00:00
c32e9badf0 chore(deps): update dependency netlify-cli to v8.6.12 (#1322)
Reviewed-on: vikunja/frontend#1322
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-01-06 19:39:31 +00:00
8f64ab5dce chore(deps): update dependency vitest to v0.0.135 (#1323)
Reviewed-on: vikunja/frontend#1323
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-01-06 19:39:11 +00:00
63ca8ffc7c fix(deps): update dependency v-tooltip to v4.0.0-beta.10 (#1324)
Reviewed-on: vikunja/frontend#1324
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-01-06 19:38:46 +00:00
fe9ddf33ca fix(deps): update dependency marked to v4.0.9 (#1321)
Reviewed-on: vikunja/frontend#1321
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-01-06 16:26:02 +00:00
74777d6bed chore(deps): update dependency netlify-cli to v8.6.9 (#1320)
Reviewed-on: vikunja/frontend#1320
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-01-06 16:25:44 +00:00
76d1c56fab chore(deps): update dependency netlify-cli to v8.6.8 (#1318)
Reviewed-on: vikunja/frontend#1318
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-01-06 15:23:22 +00:00
f75e9135c2 fix(deps): update dependency highlight.js to v11.4.0 (#1319)
Reviewed-on: vikunja/frontend#1319
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-01-06 15:23:08 +00:00
480f0f8da9 fix(deps): update dependency v-tooltip to v4.0.0-beta.8 (#1317)
Reviewed-on: vikunja/frontend#1317
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-01-06 14:05:02 +00:00
ac832186d6 chore(deps): update dependency netlify-cli to v8.6.6 (#1316)
Reviewed-on: vikunja/frontend#1316
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-01-06 11:38:23 +00:00
738e1e8370 chore(deps): update dependency sass to v1.46.0 (#1315)
Reviewed-on: vikunja/frontend#1315
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-01-06 11:10:06 +00:00
Dominik Pschenitschni
9b85817ddb feat: run vue-tsc in ci (#1295)
We had this in for a while already, but never cared for the result.
Might make sense to integrate in the pipeline.

To make things easy from the start we could add [`failure: ignore`](https://docs.drone.io/pipeline/macstadium/syntax/steps/#failure) to the step

Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: vikunja/frontend#1295
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-01-06 10:37:51 +00:00
Dominik Pschenitschni
49a6569db0 fix: remove obsolet code (#1312)
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: vikunja/frontend#1312
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-01-06 10:34:14 +00:00
e762f7f073 chore(deps): update dependency vitest to v0.0.134 (#1314)
Reviewed-on: vikunja/frontend#1314
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-01-06 10:33:07 +00:00
e5d2b23cb3 chore(deps): update dependency netlify-cli to v8.6.5 2022-01-05 21:05:56 +00:00
6eddf23c0d fix(deps): update dependency vue-advanced-cropper to v2.7.1 2022-01-05 17:03:11 +00:00
70934c6a0b fix(deps): pin dependency @types/is-touch-device to 1.0.0 (#1308)
Reviewed-on: vikunja/frontend#1308
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-01-05 16:45:48 +00:00
49955eb03a
fix: remove some of the typescript warnings 2022-01-05 16:17:14 +01:00
2b302974cc chore(deps): update dependency vitest to v0.0.133 2022-01-05 14:52:22 +00:00
Dominik Pschenitschni
64d632b0a5 [skip ci] Updated translations via Crowdin 2022-01-05 14:36:24 +00:00
Dominik Pschenitschni
e28f0f5be4 chore(addTask) improve order (#1297)
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: vikunja/frontend#1297
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-01-05 13:14:50 +00:00
c618b7e0b6 fix: namespace new buttons on mobile (#1262)
Before:

![image](/attachments/7626e28d-8a13-4f92-b162-697676f765c7)

After:

![image](/attachments/5331af47-4887-4ba5-98d7-ee70311e20d7)

Co-authored-by: kolaente <k@knt.li>
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: vikunja/frontend#1262
Reviewed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-authored-by: konrad <k@knt.li>
Co-committed-by: konrad <k@knt.li>
2022-01-05 12:46:33 +00:00
380af7fbf2 fix(deps): update dependency @vueuse/router to v7.5.3 (#1303)
Reviewed-on: vikunja/frontend#1303
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2022-01-05 11:44:12 +00:00
9d3ef30be6 fix(deps): update dependency @vueuse/core to v7.5.2 2022-01-05 10:03:09 +00:00
fc00169863 chore(deps): update dependency vitest to v0.0.132 2022-01-05 09:21:26 +00:00
b652225a12 fix(deps): update dependency @vueuse/router to v7.5.2 2022-01-05 08:02:58 +00:00
29d8422e94
fix(ready): remove class form fragment 2022-01-04 21:15:02 +01:00
Dominik Pschenitschni
cdbd1c2ac4 feat: create BaseButton component (#1123)
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: vikunja/frontend#1123
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-01-04 18:58:06 +00:00
cb37fd773d feat: convert to composable useDateTimeSalutation 2022-01-04 18:44:07 +00:00
d2577f1df6 feat: use useNow to provide auto updates 2022-01-04 18:44:07 +00:00
27534a98e9 feat: return full translation key 2022-01-04 18:44:07 +00:00
de77393905 feat: move the calculation of the current salutation to a different function 2022-01-04 18:44:07 +00:00
dd450263fb chore(deps): pin dependency happy-dom to 2.25.1 2022-01-04 18:03:16 +00:00
d8106dcb73 chore(deps): update dependency vitest to v0.0.131 2022-01-04 14:03:26 +00:00
8114012997
feat: replace jest with vitest 2022-01-04 14:16:47 +01:00
bc4ea82639 chore(deps): update dependency netlify-cli to v8.6.4 2022-01-04 13:03:16 +00:00
cd97cfe612 chore(deps): update dependency netlify-cli to v8.6.3 2022-01-04 12:03:19 +00:00
e6136fdee4 chore(deps): update dependency caniuse-lite to v1.0.30001296 2022-01-04 11:48:22 +00:00
2c395c720a chore(deps): update dependency vue-tsc to v0.30.2 2022-01-04 11:48:01 +00:00
8b639fd4af chore(deps): update dependency rollup to v2.63.0 2022-01-04 08:03:11 +00:00
f7bd5f13ac fix(deps): update dependency v-tooltip to v4.0.0-beta.6 2022-01-03 20:03:15 +00:00
0ae774b95c chore(deps): update typescript-eslint monorepo to v5.9.0 2022-01-03 19:04:33 +00:00
be899c3eb0 chore(deps): update dependency eslint to v8.6.0 2022-01-03 15:40:28 +00:00
dc02827a33 chore(deps): update dependency slugify to v1.6.5 2022-01-03 15:39:59 +00:00
951e511bf9
chore(deps): update dependency postcss-preset-env to v7.2.0 2022-01-03 16:21:43 +01:00
5f1d936ca4 fix(deps): update dependency v-tooltip to v4.0.0-beta.5 2022-01-03 15:15:05 +00:00
c3845e5690 chore(deps): update dependency netlify-cli to v8.6.1 2022-01-03 14:03:10 +00:00
f4db2df37b chore(deps): update dependency caniuse-lite to v1.0.30001295 2022-01-02 00:02:54 +00:00
5668fc7a2c chore(deps): update dependency esbuild to v0.14.10 2021-12-31 17:02:57 +00:00
12a0099fbf chore(deps): update dependency sass to v1.45.2 (#1271)
Reviewed-on: vikunja/frontend#1271
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-31 15:31:03 +00:00
7f4027cbe8 fix(deps): update dependency @vueuse/core to v7.5.1 (#1272)
Reviewed-on: vikunja/frontend#1272
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-31 15:30:46 +00:00
b57aa33cae fix(deps): update dependency @vueuse/router to v7.5.1 (#1273)
Reviewed-on: vikunja/frontend#1273
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-31 13:06:00 +00:00
b80de79594 fix(deps): update dependency @vueuse/router to v7.4.3 2021-12-31 00:02:51 +00:00
ead3e45a59 chore(deps): update dependency @types/jest to v27.4.0 2021-12-30 21:02:53 +00:00
4a7d2d8414 feat: save and restore the user language on the server (#1181)
Co-authored-by: kolaente <k@knt.li>
Reviewed-on: vikunja/frontend#1181
Reviewed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-authored-by: konrad <k@knt.li>
Co-committed-by: konrad <k@knt.li>
2021-12-30 20:20:45 +00:00
0befa58908 fix: blockquote styling in dark mode 2021-12-30 15:59:59 +00:00
8ae84eaf42 fix: padding and centering of the kanban limit and dropdown 2021-12-30 15:59:59 +00:00
cd10bc9d7a fix(gantt): use function to create default date 2021-12-30 13:05:29 +00:00
f4545fbe2f fix(deps): update dependency @vueuse/core to v7.4.3 (#1266)
Reviewed-on: vikunja/frontend#1266
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-30 12:04:16 +00:00
c6ffe8acab chore(deps): update dependency vite to v2.7.10 (#1265)
Reviewed-on: vikunja/frontend#1265
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-30 08:52:41 +00:00
2fb16f9a77 fix(deps): update dependency vue-i18n to v9.2.0-beta.26 (#1263)
Reviewed-on: vikunja/frontend#1263
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-29 23:13:35 +00:00
be427449e4 chore(deps): update dependency netlify-cli to v8.6.0 (#1259)
Reviewed-on: vikunja/frontend#1259
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-29 20:56:08 +00:00
5e889ebe36 chore(deps): update dependency autoprefixer to v10.4.1 (#1260)
Reviewed-on: vikunja/frontend#1260
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-29 20:06:07 +00:00
8c62c96109 chore(deps): update dependency esbuild to v0.14.9 (#1258)
Reviewed-on: vikunja/frontend#1258
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-29 13:34:16 +00:00
7908a1e657 chore(deps): update dependency caniuse-lite to v1.0.30001294 (#1257)
Reviewed-on: vikunja/frontend#1257
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-28 22:03:48 +00:00
09b62da2ae fix(deps): update dependency date-fns to v2.28.0 (#1256)
Reviewed-on: vikunja/frontend#1256
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-28 17:30:07 +00:00
076494afa5 chore(deps): update dependency netlify-cli to v8.5.0 (#1255)
Reviewed-on: vikunja/frontend#1255
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-28 17:12:35 +00:00
b604d5da75 chore(deps): update dependency vite to v2.7.9 (#1254)
Reviewed-on: vikunja/frontend#1254
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-28 17:11:48 +00:00
59889cccf3 chore(deps): update typescript-eslint monorepo to v5.8.1 (#1253)
Reviewed-on: vikunja/frontend#1253
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-27 19:19:38 +00:00
f8ffb428d3 chore(deps): update dependency rollup to v2.62.0 (#1246)
Reviewed-on: vikunja/frontend#1246
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-27 11:00:46 +00:00
c2ea932c09 [skip ci] Updated translations via Crowdin 2021-12-26 19:09:18 +00:00
033d97e919 chore(deps): update dependency @vue/eslint-config-typescript to v10 (#1243)
Reviewed-on: vikunja/frontend#1243
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-26 17:45:55 +00:00
4694c14760 chore(deps): update dependency vue-tsc to v0.30.1 (#1248)
Reviewed-on: vikunja/frontend#1248
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-26 17:45:33 +00:00
7e8e26679c chore(deps): update dependency vite to v2.7.7 (#1247)
Reviewed-on: vikunja/frontend#1247
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-26 09:33:35 +00:00
838db379ff fix(deps): update dependency @vueuse/core to v7.4.1 (#1244)
Reviewed-on: vikunja/frontend#1244
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-26 09:33:12 +00:00
77da84d21a fix(deps): update dependency @vueuse/router to v7.4.1 (#1245)
Reviewed-on: vikunja/frontend#1245
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-25 20:23:47 +00:00
91b80cba67 chore(deps): update dependency esbuild to v0.14.8 (#1242)
Reviewed-on: vikunja/frontend#1242
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-23 08:50:34 +00:00
ac57c8572a fix(deps): update dependency vue-i18n to v9.2.0-beta.25 (#1240)
Reviewed-on: vikunja/frontend#1240
Reviewed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-23 08:49:52 +00:00
858448b877 chore(deps): update dependency esbuild to v0.14.7 2021-12-22 11:03:15 +00:00
8409db98f6 fix(deps): update dependency vue-i18n to v9.2.0-beta.24 (#1238)
Reviewed-on: vikunja/frontend#1238
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-22 10:12:07 +00:00
04cc01daaf chore(deps): update dependency postcss-preset-env to v7.1.0 (#1237)
Reviewed-on: vikunja/frontend#1237
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-22 10:11:51 +00:00
70f8d46b6c chore(deps): update dependency cypress to v9.2.0 (#1232)
Reviewed-on: vikunja/frontend#1232
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-22 10:11:15 +00:00
15114e487b chore(deps): update dependency caniuse-lite to v1.0.30001292 (#1234)
Reviewed-on: vikunja/frontend#1234
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-22 08:25:19 +00:00
7f79f2a7b3 chore(deps): update dependency netlify-cli to v8.4.2 (#1235)
Reviewed-on: vikunja/frontend#1235
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-22 08:24:56 +00:00
7387112172 chore(deps): update dependency vite to v2.7.6 (#1236)
Reviewed-on: vikunja/frontend#1236
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-22 08:24:08 +00:00
Dominik Pschenitschni
3743cdc058 [skip ci] Updated translations via Crowdin 2021-12-22 02:09:16 +00:00
Dominik Pschenitschni
ce02462cfe [skip ci] Updated translations via Crowdin 2021-12-21 22:09:27 +00:00
Dominik Pschenitschni
7af21c48d5 [skip ci] Updated translations via Crowdin 2021-12-21 18:07:40 +00:00
Dominik Pschenitschni
943e554a58 feat: improve playPop helper (#1229)
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: vikunja/frontend#1229
Reviewed-by: konrad <k@knt.li>
Co-authored-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-committed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
2021-12-21 17:56:48 +00:00
e885d8ae70 chore(deps): update dependency vue-tsc to v0.30.0 2021-12-21 17:04:57 +00:00
2cef6cb343 chore(deps): update dependency netlify-cli to v8.4.1 2021-12-21 16:33:57 +00:00
7ebca9afc5 feat/alphabetical-sort (#1162)
Alphabetical sorting.
Disables re-ordering when applied.
Does not work with the search button as expected, but neither do the filters tbh... Works fine with the search in the filters menu.

I know we talked about having a dropdown but since this is pretty much finished I thought I'd submit a PR. I am a bit short on time these days but may submit a new PR to add the dropdown ( should be simple enough )

Co-authored-by: Stefan Genov <stefantigro@gmail.com>
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: vikunja/frontend#1162
Reviewed-by: konrad <k@knt.li>
Reviewed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-authored-by: Michaelpalacce <stefantigro@gmail.com>
Co-committed-by: Michaelpalacce <stefantigro@gmail.com>
2021-12-21 16:29:49 +00:00
d86eb9ea0b chore(deps): update dependency netlify-cli to v8.3.0 (#1228)
Reviewed-on: vikunja/frontend#1228
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-21 14:29:51 +00:00
Dominik Pschenitschni
063592ca3d fix: auth and move logic to router (#1201)
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Co-authored-by: kolaente <k@knt.li>
Reviewed-on: vikunja/frontend#1201
Reviewed-by: konrad <k@knt.li>
Co-authored-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-committed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
2021-12-21 08:02:03 +00:00
d9fa0dd2bc chore(deps): update dependency sass to v1.45.1 (#1227)
Reviewed-on: vikunja/frontend#1227
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-21 07:36:28 +00:00
4cbacafbbb chore(deps): update dependency netlify-cli to v8.2.4 (#1226)
Reviewed-on: vikunja/frontend#1226
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-20 22:23:49 +00:00
2ce260bcf1 chore(deps): update typescript-eslint monorepo to v5.8.0 (#1225)
Reviewed-on: vikunja/frontend#1225
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-20 20:30:51 +00:00
d606be3459 chore(deps): update dependency netlify-cli to v8.2.3 (#1224)
Reviewed-on: vikunja/frontend#1224
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-20 19:11:12 +00:00
d79b14221d chore(deps): update dependency netlify-cli to v8.2.1 (#1223)
Reviewed-on: vikunja/frontend#1223
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-20 18:38:14 +00:00
fdbacc2084 chore(deps): update dependency netlify-cli to v8.2.0 (#1222)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [netlify-cli](https://github.com/netlify/cli) | devDependencies | minor | [`8.1.9` -> `8.2.0`](https://renovatebot.com/diffs/npm/netlify-cli/8.1.9/8.2.0) |

---

### Release Notes

<details>
<summary>netlify/cli</summary>

### [`v8.2.0`](https://github.com/netlify/cli/blob/master/CHANGELOG.md#&#8203;820-httpswwwgithubcomnetlifyclicomparev819v820-2021-12-20)

[Compare Source](https://github.com/netlify/cli/compare/v8.1.9...v8.2.0)

##### Features

-   remove unused `--name` flag ([#&#8203;3766](https://www.github.com/netlify/cli/issues/3766)) ([07c4bcc](07c4bcc950))

##### [8.1.9](https://www.github.com/netlify/cli/compare/v8.1.8...v8.1.9) (2021-12-20)

##### Bug Fixes

-   **deps:** update dependency [@&#8203;types/node](https://github.com/types/node) to v14.18.1 ([#&#8203;3855](https://www.github.com/netlify/cli/issues/3855)) ([9145946](9145946ff1))
-   **deps:** update rust crate simple_logger to 1.16.0 ([#&#8203;3857](https://www.github.com/netlify/cli/issues/3857)) ([2c12cb4](2c12cb4e20))
-   **deps:** update rust crate tokio to 1.15.0 ([#&#8203;3859](https://www.github.com/netlify/cli/issues/3859)) ([a48643f](a48643fc00))
-   **switch:** fix switch command error when no user logged in ([#&#8203;3851](https://www.github.com/netlify/cli/issues/3851)) ([74cc879](74cc879291))

##### [8.1.8](https://www.github.com/netlify/cli/compare/v8.1.7...v8.1.8) (2021-12-17)

##### Bug Fixes

-   fixes an issue with yarn pnp on installing ([#&#8203;3841](https://www.github.com/netlify/cli/issues/3841)) ([aa14231](aa14231094))

##### [8.1.7](https://www.github.com/netlify/cli/compare/v8.1.6...v8.1.7) (2021-12-16)

##### Bug Fixes

-   **deps:** update dependency [@&#8203;netlify/plugin-edge-handlers](https://github.com/netlify/plugin-edge-handlers) to v3 ([#&#8203;3754](https://www.github.com/netlify/cli/issues/3754)) ([475c9e6](475c9e6606))

##### [8.1.6](https://www.github.com/netlify/cli/compare/v8.1.5...v8.1.6) (2021-12-16)

##### Bug Fixes

-   **deps:** update dependency [@&#8203;netlify/config](https://github.com/netlify/config) to v17 ([#&#8203;3838](https://www.github.com/netlify/cli/issues/3838)) ([ede3514](ede351485b))

##### [8.1.5](https://www.github.com/netlify/cli/compare/v8.1.4...v8.1.5) (2021-12-16)

##### Bug Fixes

-   **deps:** update dependency stripe to v8.194.0 ([#&#8203;3806](https://www.github.com/netlify/cli/issues/3806)) ([ed1ae44](ed1ae448e6))

##### [8.1.4](https://www.github.com/netlify/cli/compare/v8.1.3...v8.1.4) (2021-12-15)

##### Bug Fixes

-   remove oclif framework and fixes an issue with sites:create ([#&#8203;3717](https://www.github.com/netlify/cli/issues/3717)) ([a920292](a920292165))

##### [8.1.3](https://www.github.com/netlify/cli/compare/v8.1.2...v8.1.3) (2021-12-14)

##### Bug Fixes

-   **deps:** update dependency [@&#8203;netlify/build](https://github.com/netlify/build) to ^20.3.1 ([#&#8203;3823](https://www.github.com/netlify/cli/issues/3823)) ([79ca026](79ca026c8d))

##### [8.1.2](https://www.github.com/netlify/cli/compare/v8.1.1...v8.1.2) (2021-12-14)

##### Bug Fixes

-   **deps:** update dependency [@&#8203;netlify/framework-info](https://github.com/netlify/framework-info) to v7 ([#&#8203;3821](https://www.github.com/netlify/cli/issues/3821)) ([7866fa9](7866fa9c7e))
-   **deps:** update dependency [@&#8203;netlify/plugins-list](https://github.com/netlify/plugins-list) to ^6.2.0 ([#&#8203;3819](https://www.github.com/netlify/cli/issues/3819)) ([0ce075f](0ce075f0f2))

##### [8.1.1](https://www.github.com/netlify/cli/compare/v8.1.0...v8.1.1) (2021-12-13)

##### Bug Fixes

-   **deps:** update dependency [@&#8203;netlify/plugins-list](https://github.com/netlify/plugins-list) to ^6.1.0 ([#&#8203;3813](https://www.github.com/netlify/cli/issues/3813)) ([74c2020](74c2020e1a))
-   **deps:** update dependency typescript to v4.5.3 ([#&#8203;3802](https://www.github.com/netlify/cli/issues/3802)) ([b018b3f](b018b3f006))
-   **deps:** update rust crate simple_logger to 1.15.1 ([#&#8203;3804](https://www.github.com/netlify/cli/issues/3804)) ([0481ab6](0481ab610b))

</details>

---

### Configuration

📅 **Schedule**: At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box.

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).

Reviewed-on: vikunja/frontend#1222
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-20 15:43:24 +00:00
dd123dadd2 chore(deps): update dependency netlify-cli to v8.1.9 (#1221)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [netlify-cli](https://github.com/netlify/cli) | devDependencies | patch | [`8.1.8` -> `8.1.9`](https://renovatebot.com/diffs/npm/netlify-cli/8.1.8/8.1.9) |

---

### Release Notes

<details>
<summary>netlify/cli</summary>

### [`v8.1.9`](https://github.com/netlify/cli/blob/master/CHANGELOG.md#&#8203;819-httpswwwgithubcomnetlifyclicomparev818v819-2021-12-20)

[Compare Source](https://github.com/netlify/cli/compare/v8.1.8...v8.1.9)

</details>

---

### Configuration

📅 **Schedule**: At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box.

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).

Reviewed-on: vikunja/frontend#1221
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-20 14:46:13 +00:00
b088a5e864 chore(deps): update dependency vite to v2.7.4 2021-12-20 12:49:37 +00:00
63008e59a3 fix(deps): update dependency codemirror to v5.65.0 2021-12-20 11:02:53 +00:00
3a1da44c94 chore(deps): update dependency eslint to v8.5.0 (#1213)
Reviewed-on: vikunja/frontend#1213
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-20 08:37:38 +00:00
fccb0dcc61 chore(deps): update dependency esbuild to v0.14.6 (#1218)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [esbuild](https://github.com/evanw/esbuild) | devDependencies | patch | [`0.14.5` -> `0.14.6`](https://renovatebot.com/diffs/npm/esbuild/0.14.5/0.14.6) |

---

### Release Notes

<details>
<summary>evanw/esbuild</summary>

### [`v0.14.6`](https://github.com/evanw/esbuild/blob/master/CHANGELOG.md#&#8203;0146)

[Compare Source](https://github.com/evanw/esbuild/compare/v0.14.5...v0.14.6)

-   Fix a minifier bug with BigInt literals

    Previously expression simplification optimizations in the minifier incorrectly assumed that numeric operators always return numbers. This used to be true but has no longer been true since the introduction of BigInt literals in ES2020. Now numeric operators can return either a number or a BigInt depending on the arguments. This oversight could potentially have resulted in behavior changes. For example, this code printed `false` before being minified and `true` after being minified because esbuild shortened `===` to `==` under the false assumption that both operands were numbers:

    ```js
    var x = 0;
    console.log((x ? 2 : -1n) === -1);
    ```

    The type checking logic has been rewritten to take into account BigInt literals in this release, so this incorrect simplification is no longer applied.

-   Enable removal of certain unused template literals ([#&#8203;1853](https://github.com/evanw/esbuild/issues/1853))

    This release contains improvements to the minification of unused template literals containing primitive values:

    ```js
    // Original code
    `${1}${2}${3}`;
    `${x ? 1 : 2}${y}`;

    // Old output (with --minify)
    ""+1+2+3,""+(x?1:2)+y;

    // New output (with --minify)
    x,`${y}`;
    ```

    This can arise when the template literals are nested inside of another function call that was determined to be unnecessary such as an unused call to a function marked with the `/* @&#8203;__PURE__ */` pragma.

    This release also fixes a bug with this transformation where minifying the unused expression `` `foo ${bar}` `` into `"" + bar` changed the meaning of the expression. Template string interpolation always calls `toString` while string addition may call `valueOf` instead. This unused expression is now minified to `` `${bar}` ``, which is slightly longer but which avoids the behavior change.

-   Allow `keyof`/`readonly`/`infer` in TypeScript index signatures ([#&#8203;1859](https://github.com/evanw/esbuild/pull/1859))

    This release fixes a bug that prevented these keywords from being used as names in index signatures. The following TypeScript code was previously rejected, but is now accepted:

    ```ts
    interface Foo {
      [keyof: string]: number
    }
    ```

    This fix was contributed by [@&#8203;magic-akari](https://github.com/magic-akari).

-   Avoid warning about `import.meta` if it's replaced ([#&#8203;1868](https://github.com/evanw/esbuild/issues/1868))

    It's possible to replace the `import.meta` expression using the `--define:` feature. Previously doing that still warned that the `import.meta` syntax was not supported when targeting ES5. With this release, there will no longer be a warning in this case.

</details>

---

### Configuration

📅 **Schedule**: At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box.

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).

Reviewed-on: vikunja/frontend#1218
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-20 07:14:24 +00:00
Dominik Pschenitschni
b3b7669983 fix: llama color (#1212)
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: vikunja/frontend#1212
Reviewed-by: konrad <k@knt.li>
Co-authored-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-committed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
2021-12-19 20:08:59 +00:00
d114c673d8 fix(deps): update dependency @vueuse/core to v7.4.0 2021-12-19 18:02:38 +00:00
a6771b8d37 chore(deps): update dependency slugify to v1.6.4 (#1209)
Reviewed-on: vikunja/frontend#1209
Reviewed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-19 17:29:14 +00:00
91b06a9af6 chore(deps): update dependency caniuse-lite to v1.0.30001291 (#1214)
Reviewed-on: vikunja/frontend#1214
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-19 17:28:22 +00:00
08502619c4 fix(deps): update dependency @vueuse/router to v7.4.0 (#1216)
Reviewed-on: vikunja/frontend#1216
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-19 17:27:47 +00:00
26de8e66fa fix(deps): update dependency marked to v4.0.8 (#1217)
Reviewed-on: vikunja/frontend#1217
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-19 17:27:31 +00:00
f944c35e99 chore: simplify focus directive 2021-12-17 16:34:27 +00:00
36fb250d1f chore: directly use redirectToProvider function 2021-12-17 15:41:11 +00:00
b7aa7891e9 feat: redirect to calculated url everywhere 2021-12-17 15:41:11 +00:00
ccaed029f2 feat: build openid redirect url dynamically 2021-12-17 15:41:11 +00:00
770578240a chore(deps): update dependency ts-jest to v27.1.2 2021-12-17 14:27:34 +00:00
791678720b chore(deps): update dependency netlify-cli to v8.1.8 2021-12-17 11:02:46 +00:00
21e44e15bd [skip ci] Updated translations via Crowdin 2021-12-17 07:11:12 +00:00
9a612849a3 chore(deps): update dependency express to v4.17.2 (#1211)
Reviewed-on: vikunja/frontend#1211
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-17 06:49:18 +00:00
c4173c3c35 chore(deps): update dependency vite to v2.7.3 (#1207)
Reviewed-on: vikunja/frontend#1207
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-16 15:01:35 +00:00
46afeb159a chore(deps): update dependency caniuse-lite to v1.0.30001287 (#1205)
Reviewed-on: vikunja/frontend#1205
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-16 12:29:54 +00:00
940494a02d chore(deps): update dependency postcss-preset-env to v7.0.2 (#1206)
Reviewed-on: vikunja/frontend#1206
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-16 12:28:24 +00:00
1a55d04c97 chore(deps): update dependency vite-plugin-pwa to v0.11.12 (#1204)
Reviewed-on: vikunja/frontend#1204
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-15 22:30:04 +00:00
8ccfe716f6 chore(deps): update dependency netlify-cli to v8.1.4 (#1199)
Reviewed-on: vikunja/frontend#1199
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-15 12:13:05 +00:00
e3243f012d fix(deps): update dependency @github/hotkey to v1.6.1 (#1197)
Reviewed-on: vikunja/frontend#1197
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-14 19:31:49 +00:00
eef37c4f70 chore(deps): update dependency @vitejs/plugin-vue to v2.0.1 (#1196)
Reviewed-on: vikunja/frontend#1196
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-14 19:31:30 +00:00
e7e1cc0e55 chore(deps): update dependency browserslist to v4.19.1 (#1198)
Reviewed-on: vikunja/frontend#1198
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-14 19:31:17 +00:00
f8031b5aef chore(deps): update dependency esbuild to v0.14.5 (#1200)
Reviewed-on: vikunja/frontend#1200
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-14 19:30:52 +00:00
ac61e8d449 chore(deps): update typescript-eslint monorepo to v5.7.0 (#1192)
Reviewed-on: vikunja/frontend#1192
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-14 08:31:19 +00:00
2c671c6a13 chore(deps): update dependency jest to v27.4.5 (#1193)
Reviewed-on: vikunja/frontend#1193
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-14 08:31:04 +00:00
d01c3eabb9 chore(deps): update dependency browserslist to v4.19.0 (#1195)
Reviewed-on: vikunja/frontend#1195
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-14 07:42:55 +00:00
d85d86eaa7 chore(deps): update dependency typescript to v4.5.4 (#1194)
Reviewed-on: vikunja/frontend#1194
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-14 07:42:41 +00:00
e1b04eed72 chore(deps): update dependency netlify-cli to v8.1.1 (#1190)
Reviewed-on: vikunja/frontend#1190
Reviewed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-14 07:42:15 +00:00
543dae2f30 fix: saving default list (#1143)
Co-authored-by: kolaente <k@knt.li>
Reviewed-on: vikunja/frontend#1143
Reviewed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-authored-by: konrad <k@knt.li>
Co-committed-by: konrad <k@knt.li>
2021-12-13 22:20:45 +00:00
40479d0c6e chore(deps): update dependency vite to v2.7.2 (#1191)
Reviewed-on: vikunja/frontend#1191
Reviewed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-13 22:19:24 +00:00
f5fba7880f chore(deps): update dependency postcss to v8.4.5 (#1189)
Reviewed-on: vikunja/frontend#1189
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-13 07:34:48 +00:00
ed332f5dd3 chore(deps): update dependency esbuild to v0.14.3 (#1187)
Reviewed-on: vikunja/frontend#1187
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-12 18:47:58 +00:00
9ecd18a5ee [skip ci] Updated translations via Crowdin 2021-12-12 18:34:43 +00:00
63070e63bd chore(deps): pin dependency caniuse-lite to 1.0.30001286 (#1185)
Reviewed-on: vikunja/frontend#1185
Reviewed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-12 17:40:28 +00:00
32353e3b76 feat: restyle unauthenticated screens (#1103)
I wanted to give the no-auth screens a new look. Here's what I ended up with:

![image](/attachments/d272f36b-03c1-40ca-91f6-30f34e03e5fd)

The image is something we could change with every release.

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: vikunja/frontend#1103
Reviewed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-authored-by: konrad <k@knt.li>
Co-committed-by: konrad <k@knt.li>
2021-12-12 16:40:13 +00:00
14f1ee1885 fix(deps): pin dependency @vueuse/router to 7.3.0 (#1182)
Reviewed-on: vikunja/frontend#1182
Reviewed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-12 15:38:17 +00:00
8440869bcd
chore: explicitly add caniuse-lite to dependencies 2021-12-12 16:29:24 +01:00
14397ffb31
revert: "feat: always use latest browserlist (#1021)"
This reverts commit ed6dc94873.
2021-12-12 16:26:43 +01:00
c3c4d2a0a5 feat: use script setup and ts in app auth components 2021-12-12 14:37:20 +00:00
b03d5d80cd chore(deps): update dependency cypress to v9 2021-12-12 13:28:29 +00:00
2bf9be3676 fix(deps): update dependency @vueuse/core to v7.3.0 (#1178)
Reviewed-on: vikunja/frontend#1178
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-12 11:29:30 +00:00
807fb6a9fe
fix: use watcher to check for user query tokens 2021-12-12 12:20:33 +01:00
a106511646
fix: spacing for deletion message 2021-12-12 12:00:24 +01:00
7ed71f66ea chore(deps): update dependency sass to v1.45.0 (#1177)
Reviewed-on: vikunja/frontend#1177
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-12 10:02:56 +00:00
4463b83b78 chore(deps): update dependency @vitejs/plugin-vue to v2 (#1180)
Reviewed-on: vikunja/frontend#1180
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-12 10:02:28 +00:00
14f14f6d3e fix(deps): update vue monorepo to v3.2.26 (#1179)
Reviewed-on: vikunja/frontend#1179
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-12 10:02:11 +00:00
e1449642bd fix(deps): update sentry-javascript monorepo to v6.16.1 (#1175)
Reviewed-on: vikunja/frontend#1175
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-11 20:21:01 +00:00
5dfaeb39ca chore(deps): update dependency rollup to v2.61.1 (#1174)
Reviewed-on: vikunja/frontend#1174
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-11 20:20:52 +00:00
9584ef127a chore(deps): update dependency netlify-cli to v8.0.20 (#1168)
Reviewed-on: vikunja/frontend#1168
Reviewed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-11 16:34:18 +00:00
Dominik Pschenitschni
cb9e1e891d fix: unindent styles in pagination (#1172)
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: vikunja/frontend#1172
Reviewed-by: konrad <k@knt.li>
Co-authored-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-committed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
2021-12-11 13:00:35 +00:00
41c0594bd2 fix(deps): update dependency marked to v4.0.7 (#1170)
Reviewed-on: vikunja/frontend#1170
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-10 06:43:05 +00:00
9acc9039a6 chore(deps): update dependency typescript to v4.5.3 (#1169)
Reviewed-on: vikunja/frontend#1169
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-10 06:42:40 +00:00
f530d4763e chore(deps): update dependency jest to v27.4.4 (#1171)
Reviewed-on: vikunja/frontend#1171
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-10 06:42:03 +00:00
3f4bcbcecd chore(deps): update dependency rollup to v2.61.0 2021-12-09 18:03:53 +00:00
89d8c9d639 chore(deps): update dependency vite-plugin-pwa to v0.11.11 2021-12-09 17:13:48 +00:00
2de523f2e0 chore(deps): update dependency netlify-cli to v8.0.18 2021-12-09 16:03:06 +00:00
22e62a2cea chore(deps): update dependency vite-svg-loader to v3.1.1 2021-12-09 15:34:24 +00:00
92c89d145c chore(deps): update dependency netlify-cli to v8.0.17 2021-12-09 15:03:05 +00:00
306d562f65 [skip ci] Updated translations via Crowdin 2021-12-08 16:05:40 +00:00
4b8a7e1556 fix(deps): update dependency @vueuse/core to v7.2.2 2021-12-08 12:03:02 +00:00
d0c6576efa fix(deps): update dependency @vueuse/core to v7.2.1 (#1158)
Reviewed-on: vikunja/frontend#1158
Reviewed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-08 11:38:43 +00:00
e684e9a90b chore(deps): update dependency ts-jest to v27.1.1 2021-12-08 09:02:52 +00:00
805e1bc554 [skip ci] Updated translations via Crowdin 2021-12-07 23:05:23 +00:00
8ee793c054 [skip ci] Updated translations via Crowdin 2021-12-07 22:10:24 +00:00
1a119f97c5 feat: add support to set the marble avatar in user settings (#1156)
Frontend for vikunja/api#1060

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: vikunja/frontend#1156
Co-authored-by: konrad <k@knt.li>
Co-committed-by: konrad <k@knt.li>
2021-12-07 21:27:04 +00:00
10fe38cef6
fix: default sentry dsn in docker 2021-12-07 22:05:19 +01:00
b4cbe1e1fd fix(deps): update sentry-javascript monorepo to v6.16.0 (#1155)
Reviewed-on: vikunja/frontend#1155
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-07 21:03:27 +00:00
8b8e413af0 feat: recurring for quick add magic (#1105)
Co-authored-by: kolaente <k@knt.li>
Reviewed-on: vikunja/frontend#1105
Reviewed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-authored-by: konrad <k@knt.li>
Co-committed-by: konrad <k@knt.li>
2021-12-07 20:08:39 +00:00
c8029ec3c4 chore(deps): update dependency vite to v2.7.1 (#1154)
Reviewed-on: vikunja/frontend#1154
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-07 19:36:57 +00:00
6225c54447 fix(deps): update dependency dompurify to v2.3.4 2021-12-07 15:03:02 +00:00
809e876091 chore(deps): update dependency @vitejs/plugin-legacy to v1.6.4 (#1152)
Reviewed-on: vikunja/frontend#1152
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-07 12:06:02 +00:00
470022899f chore(deps): update dependency netlify-cli to v8.0.16 (#1147)
Reviewed-on: vikunja/frontend#1147
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-07 09:29:06 +00:00
8d1d60ba80 chore(deps): update dependency @vitejs/plugin-vue to v1.10.2 (#1150)
Reviewed-on: vikunja/frontend#1150
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-07 09:28:38 +00:00
028ad3dc14 chore(deps): update dependency vite to v2.7.0 (#1151)
Reviewed-on: vikunja/frontend#1151
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-07 09:28:13 +00:00
f4df628e47 chore(deps): update typescript-eslint monorepo to v5.6.0 (#1148)
Reviewed-on: vikunja/frontend#1148
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-07 06:14:44 +00:00
150b847638 chore(deps): update dependency eslint to v8.4.1 (#1149)
Reviewed-on: vikunja/frontend#1149
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-07 06:13:38 +00:00
684acc01bd fix(deps): update vue monorepo to v3.2.24 2021-12-06 10:02:46 +00:00
3218cf60f0 chore(deps): update dependency eslint-plugin-vue to v8.2.0 (#1145)
Reviewed-on: vikunja/frontend#1145
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-06 06:35:53 +00:00
bba9a8e008
fix: checklist update not working
Resolves #1114
2021-12-05 14:18:59 +01:00
852d71e8b7 chore(deps): update dependency ts-jest to v27.1.0 (#1141)
Reviewed-on: vikunja/frontend#1141
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-05 10:21:04 +00:00
c65bb4e93b chore(deps): update dependency vite-plugin-pwa to v0.11.10 (#1140)
Reviewed-on: vikunja/frontend#1140
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-04 17:13:33 +00:00
1c3f655323 chore(deps): update dependency esbuild to v0.14.2 (#1139)
Reviewed-on: vikunja/frontend#1139
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-04 14:55:14 +00:00
bd19234041 chore(deps): update workbox monorepo to v6.4.2 (#1133)
Co-authored-by: kolaente <k@knt.li>
Reviewed-on: vikunja/frontend#1133
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-04 14:47:52 +00:00
Dominik Pschenitschni
ac630ac775 feat: convert simple components to script setup and use typescript (#1120)
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: vikunja/frontend#1120
Reviewed-by: konrad <k@knt.li>
Co-authored-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-committed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
2021-12-04 14:47:32 +00:00
f758eefa88 fix(deps): update dependency vue-i18n to v9.2.0-beta.23 (#1138)
Reviewed-on: vikunja/frontend#1138
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-04 14:22:11 +00:00
Dominik Pschenitschni
4137bab7fc fix: Home view (#1129)
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: vikunja/frontend#1129
Reviewed-by: konrad <k@knt.li>
Co-authored-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-committed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
2021-12-04 13:56:25 +00:00
d253d2e743 chore(deps): update dependency eslint to v8.4.0 (#1136)
Reviewed-on: vikunja/frontend#1136
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-04 13:53:31 +00:00
fe5770082a chore(deps): update dependency netlify-cli to v8.0.15 (#1135)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [netlify-cli](https://github.com/netlify/cli) | devDependencies | patch | [`8.0.14` -> `8.0.15`](https://renovatebot.com/diffs/npm/netlify-cli/8.0.14/8.0.15) |

---

### Release Notes

<details>
<summary>netlify/cli</summary>

### [`v8.0.15`](https://github.com/netlify/cli/blob/master/CHANGELOG.md#&#8203;8015-httpswwwgithubcomnetlifyclicomparev8014v8015-2021-12-03)

[Compare Source](https://github.com/netlify/cli/compare/v8.0.14...v8.0.15)

</details>

---

### Configuration

📅 **Schedule**: At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box.

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).

Reviewed-on: vikunja/frontend#1135
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-03 16:35:45 +00:00
2041722b8a chore(deps): update dependency jest to v27.4.3 2021-12-02 20:03:56 +00:00
648b947a05 chore(deps): update dependency netlify-cli to v8.0.14 (#1132)
Reviewed-on: vikunja/frontend#1132
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-12-02 19:50:07 +00:00
f58e114947 chore(deps): update dependency netlify-cli to v8.0.13 2021-12-02 17:23:47 +00:00
144e7bd10c fix(deps): update dependency marked to v4.0.6 2021-12-02 17:23:19 +00:00
b96e89ca8c fix: remove unused variable 2021-12-02 17:05:28 +00:00
Dominik Pschenitschni
20f0496fa5 fix: unit test for "should recognize dates of the month in the past but next month" (#1131)
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: vikunja/frontend#1131
Reviewed-by: konrad <k@knt.li>
Co-authored-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-committed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
2021-12-02 15:39:46 +00:00
e535584412 chore(deps): update dependency vite-plugin-pwa to v0.11.9 (#1124)
Reviewed-on: vikunja/frontend#1124
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-30 22:43:23 +00:00
c5b9e2a1ff chore(deps): update dependency netlify-cli to v8.0.6 (#1125)
Reviewed-on: vikunja/frontend#1125
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-30 22:43:03 +00:00
Dominik Pschenitschni
e45bc83132 fix: duplicate filter in gantt-component (#1121)
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: vikunja/frontend#1121
Reviewed-by: konrad <k@knt.li>
Co-authored-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-committed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
2021-11-30 21:55:24 +00:00
Dominik Pschenitschni
bc8b04fc7a fix: add import url suffix for vite svg loader (#1122)
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: vikunja/frontend#1122
Reviewed-by: konrad <k@knt.li>
Co-authored-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-committed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
2021-11-30 21:03:26 +00:00
Dominik Pschenitschni
84284a6211 feat: harden textarea auto height algorithm (#985)
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: vikunja/frontend#985
Reviewed-by: konrad <k@knt.li>
Co-authored-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-committed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
2021-11-30 20:20:40 +00:00
Dominik Pschenitschni
716de2c99c feat: convert home view to script setup and ts (#1119)
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: vikunja/frontend#1119
Reviewed-by: konrad <k@knt.li>
Co-authored-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-committed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
2021-11-30 20:06:15 +00:00
Dominik Pschenitschni
769d94e879 fix:cleanup some scss vars (#1118)
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: vikunja/frontend#1118
Reviewed-by: konrad <k@knt.li>
Co-authored-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-committed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
2021-11-30 20:04:15 +00:00
Dominik Pschenitschni
baa86530c8 fix: useColorScheme (#1117)
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: vikunja/frontend#1117
Reviewed-by: konrad <k@knt.li>
Co-authored-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-committed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
2021-11-30 20:03:27 +00:00
7613afbf27 fix(deps): update dependency date-fns to v2.27.0 2021-11-30 13:08:36 +00:00
aeb886e4c5 chore(deps): update typescript-eslint monorepo to v5.5.0 2021-11-30 12:52:53 +00:00
306bd1c179 chore(deps): update dependency esbuild to v0.14.1 2021-11-30 12:52:30 +00:00
f3cf79fa65 chore(deps): update dependency rollup to v2.60.2 (#1112)
Reviewed-on: vikunja/frontend#1112
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-30 12:34:27 +00:00
8c945b049a chore(deps): update dependency jest to v27.4.2 (#1115)
Reviewed-on: vikunja/frontend#1115
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-30 12:33:59 +00:00
f69111c105 chore(deps): update dependency vue-tsc to v0.29.8 (#1111)
Reviewed-on: vikunja/frontend#1111
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-30 06:45:57 +00:00
03afbfc6c8 chore(deps): update dependency sass to v1.44.0 (#1110)
Reviewed-on: vikunja/frontend#1110
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-30 06:45:01 +00:00
c07288dd8b chore(deps): update dependency jest to v27.4.0 (#1107)
Reviewed-on: vikunja/frontend#1107
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-29 20:50:12 +00:00
03f3c52548 chore(deps): update dependency netlify-cli to v8.0.5 (#1108)
Reviewed-on: vikunja/frontend#1108
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-29 20:00:12 +00:00
384037c694 chore(deps): update dependency vue-tsc to v0.29.7 (#1106)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [vue-tsc](https://github.com/johnsoncodehk/volar) | devDependencies | patch | [`0.29.6` -> `0.29.7`](https://renovatebot.com/diffs/npm/vue-tsc/0.29.6/0.29.7) |

---

### Release Notes

<details>
<summary>johnsoncodehk/volar</summary>

### [`v0.29.7`](https://github.com/johnsoncodehk/volar/blob/master/CHANGELOG.md#&#8203;0297)

[Compare Source](https://github.com/johnsoncodehk/volar/compare/v0.29.6...v0.29.7)

-   feat: support html, css custom data ([#&#8203;707](https://github.com/johnsoncodehk/volar/issues/707))
-   feat: support extends tsconfig `vueCompilerOptions` ([#&#8203;731](https://github.com/johnsoncodehk/volar/issues/731))
-   fix: cannot config project reference by directory path ([#&#8203;712](https://github.com/johnsoncodehk/volar/issues/712))
-   fix: pug attrs type-check borken by nested tags ([#&#8203;721](https://github.com/johnsoncodehk/volar/issues/721))
-   fix: import path rename result incorrect ([#&#8203;723](https://github.com/johnsoncodehk/volar/issues/723))
-   fix: `editor.codeActionsOnSave: ["source.organizeImports"]` not working ([#&#8203;726](https://github.com/johnsoncodehk/volar/issues/726))
-   fix: goto definition not working with some component import statement ([#&#8203;728](https://github.com/johnsoncodehk/volar/issues/728))
-   fix: don't show volar commands in non-vue document ([#&#8203;733](https://github.com/johnsoncodehk/volar/issues/733))
-   fix: vue-tsc not working with symlink ([#&#8203;738](https://github.com/johnsoncodehk/volar/issues/738))

</details>

---

### Configuration

📅 **Schedule**: At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box.

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).

Reviewed-on: vikunja/frontend#1106
Reviewed-by: dpschen <dpschen@noreply.kolaente.de>
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-28 21:40:03 +00:00
734db0795c
fix: switching from a list with a background to settings would not remove the background 2021-11-28 15:56:08 +01:00
8f6c0f3738 chore(deps): update dependency vite-plugin-pwa to v0.11.8 (#1102)
Reviewed-on: vikunja/frontend#1102
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-28 14:50:57 +00:00
f3324c6aaf [skip ci] Updated translations via Crowdin 2021-11-28 14:27:28 +00:00
f8d009a6aa feat: add message component (#1082)
This PR adds a simple message component that replaces bulma's default message.

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: vikunja/frontend#1082
Reviewed-by: dpschen <dpschen@noreply.kolaente.de>
Co-authored-by: konrad <k@knt.li>
Co-committed-by: konrad <k@knt.li>
2021-11-28 14:18:27 +00:00
dpschen
59e915cc10 feat: add packageManager field to package.json (#1099)
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: vikunja/frontend#1099
Reviewed-by: konrad <k@knt.li>
Co-authored-by: dpschen <dpschen@noreply.kolaente.de>
Co-committed-by: dpschen <dpschen@noreply.kolaente.de>
2021-11-27 19:36:57 +00:00
dpschen
0c9dad9891 fix: remove obsolete code (#1097)
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: vikunja/frontend#1097
Reviewed-by: konrad <k@knt.li>
Co-authored-by: dpschen <dpschen@noreply.kolaente.de>
Co-committed-by: dpschen <dpschen@noreply.kolaente.de>
2021-11-27 19:33:37 +00:00
dpschen
b7ad29f056 fix: upgrade cypress image (#1096)
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: vikunja/frontend#1096
Co-authored-by: dpschen <dpschen@noreply.kolaente.de>
Co-committed-by: dpschen <dpschen@noreply.kolaente.de>
2021-11-27 19:32:48 +00:00
a7434f24df chore(deps): update dependency postcss to v8.4.4 (#1100)
Reviewed-on: vikunja/frontend#1100
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-27 19:32:29 +00:00
f61d5bac46 [skip ci] Updated translations via Crowdin 2021-11-26 22:26:39 +00:00
2911dee3cc chore(deps): update dependency esbuild to v0.14.0 (#1095)
Reviewed-on: vikunja/frontend#1095
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-26 21:29:31 +00:00
58c361ee29
fix(translations): typo 2021-11-26 21:40:20 +01:00
d3fc1439b5 chore(deps): update dependency postcss to v8.4.3 (#1094)
Reviewed-on: vikunja/frontend#1094
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-26 20:33:33 +00:00
bb544c353c chore(deps): update dependency postcss to v8.4.2 (#1093)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [postcss](https://postcss.org/) ([source](https://github.com/postcss/postcss)) | devDependencies | patch | [`8.4.1` -> `8.4.2`](https://renovatebot.com/diffs/npm/postcss/8.4.1/8.4.2) |

---

### Release Notes

<details>
<summary>postcss/postcss</summary>

### [`v8.4.2`](https://github.com/postcss/postcss/blob/master/CHANGELOG.md#&#8203;842)

[Compare Source](https://github.com/postcss/postcss/compare/8.4.1...8.4.2)

-   Fixed previous source map support in zero plugins mode.

</details>

---

### Configuration

📅 **Schedule**: At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box.

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).

Reviewed-on: vikunja/frontend#1093
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-26 19:59:47 +00:00
cc90a1cea5 fix(deps): update dependency @vueuse/core to v7.1.2 (#1092)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [@vueuse/core](https://github.com/vueuse/vueuse) | dependencies | patch | [`7.1.1` -> `7.1.2`](https://renovatebot.com/diffs/npm/@vueuse%2fcore/7.1.1/7.1.2) |

---

### Release Notes

<details>
<summary>vueuse/vueuse</summary>

### [`v7.1.2`](https://github.com/vueuse/vueuse/releases/v7.1.2)

[Compare Source](https://github.com/vueuse/vueuse/compare/v7.1.1...v7.1.2)

##### Bug Fixes

-   **useAsyncState:** optional argument of `execute` ([#&#8203;972](https://github.com/vueuse/vueuse/issues/972)) ([6661a09](https://github.com/vueuse/vueuse/commit/6661a09))
-   **UseVirtualList:** fix list not being reactive in component ([#&#8203;968](https://github.com/vueuse/vueuse/issues/968)) ([fb7cd78](https://github.com/vueuse/vueuse/commit/fb7cd78))

##### Features

-   **useEyeDropper:** add initialValue option, improve types ([#&#8203;950](https://github.com/vueuse/vueuse/issues/950)) ([cf8ced3](https://github.com/vueuse/vueuse/commit/cf8ced3))

</details>

---

### Configuration

📅 **Schedule**: At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box.

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).

Reviewed-on: vikunja/frontend#1092
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-26 19:59:31 +00:00
cffba33748 chore(deps): update dependency @vitejs/plugin-vue to v1.10.1 (#1091)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [@vitejs/plugin-vue](https://github.com/vitejs/vite) | devDependencies | patch | [`1.10.0` -> `1.10.1`](https://renovatebot.com/diffs/npm/@vitejs%2fplugin-vue/1.10.0/1.10.1) |

---

### Release Notes

<details>
<summary>vitejs/vite</summary>

### [`v1.10.1`](https://github.com/vitejs/vite/blob/master/packages/plugin-vue/CHANGELOG.md#&#8203;1101-httpsgithubcomvitejsvitecompareplugin-vue1100plugin-vue1101-2021-11-26)

##### Bug Fixes

-   **plugin-vue:** fix hmr issue in vuejs/vue-next[#&#8203;4358](https://github.com/vitejs/vite/issues/4358) ([709e4b0](709e4b0428))

</details>

---

### Configuration

📅 **Schedule**: At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box.

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).

Reviewed-on: vikunja/frontend#1091
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-26 08:34:32 +00:00
055e0a2901 fix(deps): update vue monorepo to v3.2.23 (#1090)
Reviewed-on: vikunja/frontend#1090
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-26 07:12:49 +00:00
c8d1921bcd chore(deps): update dependency netlify-cli to v8.0.3 (#1089)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [netlify-cli](https://github.com/netlify/cli) | devDependencies | patch | [`8.0.2` -> `8.0.3`](https://renovatebot.com/diffs/npm/netlify-cli/8.0.2/8.0.3) |

---

### Release Notes

<details>
<summary>netlify/cli</summary>

### [`v8.0.3`](https://github.com/netlify/cli/blob/master/CHANGELOG.md#&#8203;803-httpswwwgithubcomnetlifyclicomparev802v803-2021-11-25)

[Compare Source](https://github.com/netlify/cli/compare/v8.0.2...v8.0.3)

</details>

---

### Configuration

📅 **Schedule**: At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box.

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).

Reviewed-on: vikunja/frontend#1089
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-25 21:44:19 +00:00
9e09314f75 chore(deps): update dependency netlify-cli to v8.0.2 (#1088)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [netlify-cli](https://github.com/netlify/cli) | devDependencies | patch | [`8.0.1` -> `8.0.2`](https://renovatebot.com/diffs/npm/netlify-cli/8.0.1/8.0.2) |

---

### Release Notes

<details>
<summary>netlify/cli</summary>

### [`v8.0.2`](https://github.com/netlify/cli/blob/master/CHANGELOG.md#&#8203;802-httpswwwgithubcomnetlifyclicomparev801v802-2021-11-25)

[Compare Source](https://github.com/netlify/cli/compare/v8.0.1...v8.0.2)

</details>

---

### Configuration

📅 **Schedule**: At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box.

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).

Reviewed-on: vikunja/frontend#1088
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-25 19:56:17 +00:00
c3833d90d8 chore(deps): update dependency sass to v1.43.5 2021-11-25 13:16:09 +00:00
e24cb55e1b fix(deps): update dependency vue-i18n to v9.2.0-beta.22 2021-11-25 11:02:55 +00:00
f897611ad1 chore(deps): update dependency postcss to v8.4.1 (#1083)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [postcss](https://postcss.org/) ([source](https://github.com/postcss/postcss)) | devDependencies | patch | [`8.4.0` -> `8.4.1`](https://renovatebot.com/diffs/npm/postcss/8.4.0/8.4.1) |

---

### Release Notes

<details>
<summary>postcss/postcss</summary>

### [`v8.4.1`](https://github.com/postcss/postcss/blob/master/CHANGELOG.md#&#8203;841)

[Compare Source](https://github.com/postcss/postcss/compare/8.4.0...8.4.1)

-   Fixed `Stringifier` types (by James Garbutt).

</details>

---

### Configuration

📅 **Schedule**: At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box.

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).

Reviewed-on: vikunja/frontend#1083
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-25 06:10:45 +00:00
ea8fe297d9 fix(deps): update dependency marked to v4.0.5 (#1085)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [marked](https://marked.js.org) ([source](https://github.com/markedjs/marked)) | dependencies | patch | [`4.0.4` -> `4.0.5`](https://renovatebot.com/diffs/npm/marked/4.0.4/4.0.5) |

---

### Release Notes

<details>
<summary>markedjs/marked</summary>

### [`v4.0.5`](https://github.com/markedjs/marked/releases/v4.0.5)

[Compare Source](https://github.com/markedjs/marked/compare/v4.0.4...v4.0.5)

##### Bug Fixes

-   table after paragraph without blank line ([#&#8203;2298](https://github.com/markedjs/marked/issues/2298)) ([5714212](5714212afd))

</details>

---

### Configuration

📅 **Schedule**: At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box.

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).

Reviewed-on: vikunja/frontend#1085
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-25 06:10:06 +00:00
c6b604f1fa fix(deps): update dependency @vueuse/core to v7.1.1 (#1086)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [@vueuse/core](https://github.com/vueuse/vueuse) | dependencies | patch | [`7.1.0` -> `7.1.1`](https://renovatebot.com/diffs/npm/@vueuse%2fcore/7.1.0/7.1.1) |

---

### Release Notes

<details>
<summary>vueuse/vueuse</summary>

### [`v7.1.1`](https://github.com/vueuse/vueuse/releases/v7.1.1)

[Compare Source](https://github.com/vueuse/vueuse/compare/v7.1.0...v7.1.1)

##### Bug Fixes

-   improve package.json ([0c4e770](https://github.com/vueuse/vueuse/commit/0c4e770))
-   **useMemory:** import path ([bd2346b](https://github.com/vueuse/vueuse/commit/bd2346b))

</details>

---

### Configuration

📅 **Schedule**: At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box.

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).

Reviewed-on: vikunja/frontend#1086
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-25 06:09:55 +00:00
4792adfbd1 chore(deps): update dependency netlify-cli to v8.0.1 (#1081)
Reviewed-on: vikunja/frontend#1081
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-24 21:32:12 +00:00
dpschen
04c94418d7
fix: logo overflow on login (#1050)
Resolves #1046

Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: vikunja/frontend#1050
Reviewed-by: konrad <k@knt.li>
Co-authored-by: dpschen <dpschen@noreply.kolaente.de>
Co-committed-by: dpschen <dpschen@noreply.kolaente.de>
(cherry picked from commit 44f8e3ea9b)
2021-11-24 22:30:47 +01:00
12bec04c42 chore(deps): pin dependency autoprefixer to 10.4.0 (#1080)
Reviewed-on: vikunja/frontend#1080
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-24 20:13:02 +00:00
e8eb94d71b chore(deps): update dependency postcss to v8.4.0 (#1075)
Co-authored-by: kolaente <k@knt.li>
Reviewed-on: vikunja/frontend#1075
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-24 19:50:33 +00:00
5137f9f6cb fix(deps): update dependency @vueuse/core to v7.1.0 (#1078)
Reviewed-on: vikunja/frontend#1078
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-24 19:31:43 +00:00
a2f65d86c2 chore(deps): update dependency netlify-cli to v8 (#1077)
Reviewed-on: vikunja/frontend#1077
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-24 16:33:51 +00:00
08dcc897cc chore(deps): update dependency @4tw/cypress-drag-drop to v2.1.0 (#1076)
Reviewed-on: vikunja/frontend#1076
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-24 16:33:11 +00:00
c975fb0fee fix(deps): update dependency vue-i18n to v9.2.0-beta.21 (#1072)
Reviewed-on: vikunja/frontend#1072
Reviewed-by: dpschen <dpschen@noreply.kolaente.de>
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-24 13:30:24 +00:00
b73cf344b6 [skip ci] Updated translations via Crowdin 2021-11-24 09:25:56 +00:00
d4b45dc255 fix(dark mode): flatpickr colors 2021-11-23 22:58:25 +00:00
e2beaba3b9 fix(dark mode): disabled input colors 2021-11-23 22:58:25 +00:00
dd9be97793 fix(deps): update dependency @vueuse/core to v7.0.3 (#1071)
Reviewed-on: vikunja/frontend#1071
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-23 22:31:56 +00:00
6cde8e2640 fix(dark mode): dark mode adjustments (#1069)
Co-authored-by: kolaente <k@knt.li>
Reviewed-on: vikunja/frontend#1069
Reviewed-by: dpschen <dpschen@noreply.kolaente.de>
Co-authored-by: konrad <k@knt.li>
Co-committed-by: konrad <k@knt.li>
2021-11-23 21:20:50 +00:00
5c6fcffd75 chore(deps): update dependency vite-plugin-pwa to v0.11.7 2021-11-23 20:02:55 +00:00
9b243873c5
chore: 0.18.2 release preparations
(cherry picked from commit 771eef9e54)
2021-11-23 20:22:07 +01:00
dc347ed8ba
fix: edit task comment
Resolves #1055
2021-11-23 19:21:45 +01:00
d0d1086dac chore(deps): update dependency netlify-cli to v7.1.0 (#1067)
Reviewed-on: vikunja/frontend#1067
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-23 18:12:36 +00:00
fb91b71395 fix(deps): pin dependency bulma-css-variables to 0.9.33 (#1065)
Reviewed-on: vikunja/frontend#1065
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-23 09:20:40 +00:00
dpschen
b688f35446 feat: reduce import size by only importing used modules (#1023)
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: vikunja/frontend#1023
Reviewed-by: konrad <k@knt.li>
Co-authored-by: dpschen <dpschen@noreply.kolaente.de>
Co-committed-by: dpschen <dpschen@noreply.kolaente.de>
2021-11-23 07:09:17 +00:00
dpschen
91580f97a1 feat: use popper.js v2 vue3 version of v-tooltip (#1038)
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: vikunja/frontend#1038
Reviewed-by: konrad <k@knt.li>
Co-authored-by: dpschen <dpschen@noreply.kolaente.de>
Co-committed-by: dpschen <dpschen@noreply.kolaente.de>
2021-11-23 07:08:21 +00:00
d95fc32d67 fix(deps): update dependency @vueuse/core to v7 (#1066)
Reviewed-on: vikunja/frontend#1066
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-23 07:07:44 +00:00
drone
6b5ac20ef8 [skip ci] Updated translations via Crowdin 2021-11-23 02:27:22 +00:00
drone
66f0df5037 [skip ci] Updated translations via Crowdin 2021-11-23 01:27:19 +00:00
dpschen
981babd691 fix: remove mentioning of context (#1017)
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: vikunja/frontend#1017
Reviewed-by: konrad <k@knt.li>
Co-authored-by: dpschen <dpschen@noreply.kolaente.de>
Co-committed-by: dpschen <dpschen@noreply.kolaente.de>
2021-11-22 21:36:17 +00:00
46fa43d67f Migrate to bulma-css-variables and introduce dark mode (#954)
Co-authored-by: Adrian Simmons <adrian@perlucida.co.uk>
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Co-authored-by: kolaente <k@knt.li>
Reviewed-on: vikunja/frontend#954
Reviewed-by: dpschen <dpschen@noreply.kolaente.de>
Reviewed-by: konrad <k@knt.li>
Co-authored-by: adrinux <adrian@perlucida.co.uk>
Co-committed-by: adrinux <adrian@perlucida.co.uk>
2021-11-22 21:12:54 +00:00
4ef54f1bc2
fix: deleting a namespace
Deleting a namespace would remove the item from the store and then try to remove it from the search index. That failed because the item was already removed from the store and thus undefined when it was passed to the store.
2021-11-22 21:49:19 +01:00
dpschen
b029889f27 fix: check for notification api (#1043)
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: vikunja/frontend#1043
Reviewed-by: konrad <k@knt.li>
Co-authored-by: dpschen <dpschen@noreply.kolaente.de>
Co-committed-by: dpschen <dpschen@noreply.kolaente.de>
2021-11-22 19:03:27 +00:00
dpschen
44f8e3ea9b fix #1046 logo overflow on login (#1050)
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: vikunja/frontend#1050
Reviewed-by: konrad <k@knt.li>
Co-authored-by: dpschen <dpschen@noreply.kolaente.de>
Co-committed-by: dpschen <dpschen@noreply.kolaente.de>
2021-11-22 19:01:26 +00:00
dpschen
ae36c041a7 feat: improve namespace explanation (#1040)
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: vikunja/frontend#1040
Reviewed-by: konrad <k@knt.li>
Co-authored-by: dpschen <dpschen@noreply.kolaente.de>
Co-committed-by: dpschen <dpschen@noreply.kolaente.de>
2021-11-22 18:41:00 +00:00
8a722f294c chore(deps): update dependency @vitejs/plugin-legacy to v1.6.3 2021-11-22 17:58:01 +00:00
5674acbee6 chore(deps): update dependency netlify-cli to v7.0.4 2021-11-22 17:57:31 +00:00
bf9371c60a chore(deps): update dependency slugify to v1.6.3 2021-11-22 15:02:59 +00:00
181930f537 chore(deps): update dependency esbuild to v0.13.15 2021-11-22 12:00:50 +00:00
cee22a1942 chore(deps): update dependency rollup to v2.60.1 2021-11-22 12:00:23 +00:00
673458b41d chore(deps): update dependency @vitejs/plugin-vue to v1.10.0 2021-11-22 11:02:45 +00:00
b56e99bfdf chore(deps): update dependency vue-tsc to v0.29.6 2021-11-21 12:26:11 +00:00
a5b5d99129 fix(deps): update dependency codemirror to v5.64.0 2021-11-21 12:25:48 +00:00
e1b9a9921c chore(deps): update dependency eslint to v8.3.0 2021-11-21 07:02:48 +00:00
709ebdf567 chore(deps): update dependency netlify-cli to v7.0.2 2021-11-19 18:02:47 +00:00
d41ee3dc8c chore(deps): update dependency netlify-cli to v7.0.1 2021-11-19 15:32:41 +00:00
e342f6e3ed fix(deps): update dependency marked to v4.0.4 2021-11-19 15:03:03 +00:00
8b2450d6f9 chore(deps): update dependency postcss-preset-env to v7.0.1 2021-11-19 12:02:37 +00:00
943eab5e7e fix(deps): update dependency date-fns to v2.26.0 2021-11-19 08:02:43 +00:00
d55328e03b chore(deps): update dependency vite-plugin-pwa to v0.11.6 (#1031)
Reviewed-on: vikunja/frontend#1031
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-18 21:54:59 +00:00
30aa1cd1cf chore(deps): update dependency @types/jest to v27.0.3 (#1030)
Reviewed-on: vikunja/frontend#1030
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-18 21:54:33 +00:00
01f3196938 chore(deps): update dependency netlify-cli to v7 (#1029)
Reviewed-on: vikunja/frontend#1029
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-18 20:49:36 +00:00
ced8e0fd3c chore(deps): update dependency netlify-cli to v6.15.0 (#1028)
Reviewed-on: vikunja/frontend#1028
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-18 16:24:38 +00:00
dpschen
b838e7494d fix attribute coercion for contenteditable (#1025)
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: vikunja/frontend#1025
Reviewed-by: konrad <k@knt.li>
Co-authored-by: dpschen <dpschen@noreply.kolaente.de>
Co-committed-by: dpschen <dpschen@noreply.kolaente.de>
2021-11-18 13:00:54 +00:00
745b4b56ec chore(deps): update dependency eslint-plugin-vue to v8.1.1 (#1026)
Reviewed-on: vikunja/frontend#1026
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-18 13:00:13 +00:00
c5b539912d fix(deps): update dependency vue-i18n to v9.2.0-beta.20 2021-11-18 09:02:52 +00:00
dpschen
ed6dc94873 feat: always use latest browserlist (#1021)
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: vikunja/frontend#1021
Reviewed-by: konrad <k@knt.li>
Co-authored-by: dpschen <dpschen@noreply.kolaente.de>
Co-committed-by: dpschen <dpschen@noreply.kolaente.de>
2021-11-17 19:15:57 +00:00
233b9693eb chore(deps): update dependency typescript to v4.5.2 (#1024)
Reviewed-on: vikunja/frontend#1024
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-17 19:15:01 +00:00
dpschen
2656c74f37 feat: add postcss-preset-env (#1022)
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: vikunja/frontend#1022
Reviewed-by: konrad <k@knt.li>
Co-authored-by: dpschen <dpschen@noreply.kolaente.de>
Co-committed-by: dpschen <dpschen@noreply.kolaente.de>
2021-11-17 17:58:46 +00:00
28b571588e fix(deps): update dependency vue-i18n to v9.2.0-beta.19 2021-11-17 14:10:37 +00:00
ae5d3ecac5 fix: kanban card spacing (#1005)
Co-authored-by: kolaente <k@knt.li>
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: vikunja/frontend#1005
Co-authored-by: konrad <k@knt.li>
Co-committed-by: konrad <k@knt.li>
2021-11-16 21:44:07 +00:00
189 changed files with 6567 additions and 5467 deletions

View File

@ -98,8 +98,17 @@ steps:
depends_on:
- dependencies
- name: typecheck
failure: ignore
image: node:16
pull: true
commands:
- yarn typecheck
depends_on:
- dependencies
- name: test-frontend
image: cypress/browsers:node14.17.0-chrome91-ff89
image: cypress/browsers:node16.5.0-chrome94-ff93
pull: true
environment:
CYPRESS_API_URL: http://api:3456/api/v1

View File

@ -9,6 +9,13 @@ All releases can be found on https://code.vikunja.io/frontend/releases.
The releases aim at the api versions which is why there are missing versions.
## [0.18.2] - 2021-11-23
### Fixed
* fix(docker): properly replace api url
* fix: edit saved filter title
## [0.18.1] - 2021-09-08
### Added

View File

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

View File

@ -31,7 +31,7 @@ describe('Lists', () => {
cy.url()
.should('contain', '/namespaces/1/list')
cy.get('.card-header-title')
.contains('Create a new list')
.contains('New list')
cy.get('input.input')
.type('New List')
cy.get('.button')
@ -101,7 +101,7 @@ describe('Lists', () => {
.click()
cy.url()
.should('contain', '/settings/delete')
cy.get('.modal-mask .modal-container .modal-content .actions a.button')
cy.get('[data-cy="modalPrimary"]')
.contains('Do it')
.click()
@ -392,7 +392,7 @@ describe('Lists', () => {
cy.get('.kanban .bucket .bucket-header .dropdown.options .dropdown-menu .dropdown-item .field input.input')
.first()
.type(3)
cy.get('.kanban .bucket .bucket-header .dropdown.options .dropdown-menu .dropdown-item .field a.button.is-primary')
cy.get('[data-cy="setBucketLimit"]')
.first()
.click()

View File

@ -15,7 +15,7 @@ describe('Namepaces', () => {
it('Should be all there', () => {
cy.visit('/namespaces')
cy.get('.namespace h1 span')
cy.get('[data-cy="namespace-title"]')
.should('contain', namespaces[0].title)
})
@ -23,14 +23,14 @@ describe('Namepaces', () => {
const newNamespaceTitle = 'New Namespace'
cy.visit('/namespaces')
cy.get('a.button')
.contains('Create a new namespace')
cy.get('[data-cy="new-namespace"]')
.should('contain', 'New namespace')
.click()
cy.url()
.should('contain', '/namespaces/new')
cy.get('.card-header-title')
.should('contain', 'Create a new namespace')
.should('contain', 'New namespace')
cy.get('input.input')
.type(newNamespaceTitle)
cy.get('.button')
@ -72,7 +72,7 @@ describe('Namepaces', () => {
cy.get('.namespace-container .menu.namespaces-lists')
.should('contain', newNamespaceName)
.should('not.contain', newNamespaces[0].title)
cy.get('.content.namespaces-list')
cy.get('[data-cy="namespaces-list"]')
.should('contain', newNamespaceName)
.should('not.contain', newNamespaces[0].title)
})
@ -89,7 +89,7 @@ describe('Namepaces', () => {
.click()
cy.url()
.should('contain', '/settings/delete')
cy.get('.modal-mask .modal-container .modal-content .actions a.button')
cy.get('[data-cy="modalPrimary"]')
.contains('Do it')
.click()
@ -116,30 +116,30 @@ describe('Namepaces', () => {
// Initial
cy.visit('/namespaces')
cy.get('.namespaces-list .namespace')
cy.get('.namespace')
.should('not.contain', 'Archived')
// Show archived
cy.get('.namespaces-list .fancycheckbox.show-archived-check label.check span')
cy.get('[data-cy="show-archived-check"] label.check span')
.should('be.visible')
.click()
cy.get('.namespaces-list .fancycheckbox.show-archived-check input')
cy.get('[data-cy="show-archived-check"] input')
.should('be.checked')
cy.get('.namespaces-list .namespace')
cy.get('.namespace')
.should('contain', 'Archived')
// Don't show archived
cy.get('.namespaces-list .fancycheckbox.show-archived-check label.check span')
cy.get('[data-cy="show-archived-check"] label.check span')
.should('be.visible')
.click()
cy.get('.namespaces-list .fancycheckbox.show-archived-check input')
cy.get('[data-cy="show-archived-check"] input')
.should('not.be.checked')
// Second time visiting after unchecking
cy.visit('/namespaces')
cy.get('.namespaces-list .fancycheckbox.show-archived-check input')
cy.get('[data-cy="show-archived-check"] input')
.should('not.be.checked')
cy.get('.namespaces-list .namespace')
cy.get('.namespace')
.should('not.contain', 'Archived')
})
})

View File

@ -1,35 +0,0 @@
import '../../support/authenticateUser'
const setHours = hours => {
const date = new Date()
date.setHours(hours)
cy.clock(+date)
}
describe('Home Page', () => {
it('shows the right salutation in the night', () => {
setHours(4)
cy.visit('/')
cy.get('h2').should('contain', 'Good Night')
})
it('shows the right salutation in the morning', () => {
setHours(8)
cy.visit('/')
cy.get('h2').should('contain', 'Good Morning')
})
it('shows the right salutation in the day', () => {
setHours(13)
cy.visit('/')
cy.get('h2').should('contain', 'Hi')
})
it('shows the right salutation in the night', () => {
setHours(20)
cy.visit('/')
cy.get('h2').should('contain', 'Good Evening')
})
it('shows the right salutation in the night again', () => {
setHours(23)
cy.visit('/')
cy.get('h2').should('contain', 'Good Night')
})
})

View File

@ -128,7 +128,7 @@ describe('Task', () => {
cy.visit(`/tasks/${tasks[0].id}`)
cy.get('.task-view .action-buttons .button')
.contains('Done!')
.contains('Mark task done!')
.click()
cy.get('.task-view .heading .is-done')
@ -168,7 +168,7 @@ describe('Task', () => {
.click()
cy.get('.task-view .details.content.description .editor .vue-easymde .EasyMDEContainer .CodeMirror-scroll')
.type('{selectall}New Description')
cy.get('.task-view .details.content.description .editor a')
cy.get('[data-cy="saveEditor"]')
.contains('Save')
.click()
@ -263,8 +263,7 @@ describe('Task', () => {
cy.visit(`/tasks/${tasks[0].id}`)
cy.get('.task-view .action-buttons .button')
.contains('Assign this task to a user')
cy.get('[data-cy="taskDetail.assign"]')
.click()
cy.get('.task-view .column.assignees .multiselect input')
.type(users[1].username)
@ -405,7 +404,7 @@ describe('Task', () => {
cy.get('.datepicker .datepicker-popup a')
.contains('Tomorrow')
.click()
cy.get('.datepicker .datepicker-popup a.button')
cy.get('[data-cy="closeDatepicker"]')
.contains('Confirm')
.click()

View File

@ -8,7 +8,7 @@ const testAndAssertFailed = fixture => {
cy.wait(5000) // It can take waaaayy too long to log the user in
cy.url().should('include', '/')
cy.get('div.notification.is-danger').contains('Wrong username or password.')
cy.get('div.message.danger').contains('Wrong username or password.')
}
context('Login', () => {

View File

@ -32,7 +32,7 @@ context('Registration', () => {
cy.get('h2').should('contain', `Hi ${fixture.username}!`)
})
it('Should fail', () => {
it.only('Should fail', () => {
const fixture = {
username: 'test',
password: '123456',
@ -45,6 +45,6 @@ context('Registration', () => {
cy.get('#password').type(fixture.password)
cy.get('#passwordValidation').type(fixture.password)
cy.get('#register-submit').click()
cy.get('div.notification.is-danger').contains('A user with this username already exists.')
cy.get('div.message.danger').contains('A user with this username already exists.')
})
})

View File

@ -18,7 +18,7 @@ describe('User Settings', () => {
.trigger('mousedown', {which: 1})
.trigger('mousemove', {clientY: 100})
.trigger('mouseup')
cy.get('a.button.is-primary')
cy.get('[data-cy="uploadAvatar"]')
.contains('Upload Avatar')
.click()
@ -33,7 +33,7 @@ describe('User Settings', () => {
cy.get('.general-settings .control input.input')
.first()
.type('Lorem Ipsum')
cy.get('.card.general-settings .button.is-primary')
cy.get('[data-cy="saveGeneralSettings"]')
.contains('Save')
.click()

View File

@ -49,7 +49,7 @@
inkscape:label="ink_ext_XXXXXX 1"
style="display:inline"
transform="translate(-92.67749,-674.48297)"><circle
style="fill:#5974d9;fill-opacity:1;stroke:none;stroke-width:2.88757133;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
style="fill:#196aff;fill-opacity:1;stroke:none;stroke-width:2.88757133;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
id="path920"
cx="242.67749"
cy="828.77881"

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 47 KiB

View File

@ -9,91 +9,97 @@
"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/",
"typecheck": "vue-tsc --noEmit",
"lint": "eslint --ignore-pattern '*.test.*' ./src --ext .vue,.js,.ts",
"lint:markup": "vue-tsc --noEmit",
"cypress:open": "cypress open",
"test:unit": "jest",
"test:unit": "vitest run",
"test:frontend": "cypress run",
"browserslist:update": "npx browserslist@latest --update-db"
},
"dependencies": {
"@github/hotkey": "1.6.0",
"@github/hotkey": "1.6.1",
"@kyvg/vue3-notification": "2.3.4",
"@sentry/tracing": "6.15.0",
"@sentry/vue": "6.15.0",
"@vue/compat": "3.2.22",
"bulma": "0.9.3",
"@sentry/tracing": "6.16.1",
"@sentry/vue": "6.16.1",
"@types/is-touch-device": "1.0.0",
"@vue/compat": "3.2.26",
"@vueuse/core": "7.5.2",
"@vueuse/router": "7.5.3",
"bulma-css-variables": "0.9.33",
"camel-case": "4.1.2",
"codemirror": "5.63.3",
"codemirror": "5.65.0",
"copy-to-clipboard": "3.3.1",
"date-fns": "2.25.0",
"dompurify": "2.3.3",
"date-fns": "2.28.0",
"dompurify": "2.3.4",
"easymde": "2.15.0",
"flatpickr": "4.6.9",
"flexsearch": "0.7.21",
"highlight.js": "11.3.1",
"highlight.js": "11.4.0",
"is-touch-device": "1.0.1",
"lodash.clonedeep": "4.5.0",
"lodash.debounce": "4.0.8",
"marked": "4.0.3",
"marked": "4.0.9",
"register-service-worker": "1.7.2",
"snake-case": "3.0.4",
"ufo": "0.7.9",
"vue": "3.2.22",
"vue-advanced-cropper": "2.7.0",
"v-tooltip": "4.0.0-beta.13",
"vue": "3.2.26",
"vue-advanced-cropper": "2.7.1",
"vue-drag-resize": "2.0.3",
"vue-flatpickr-component": "9.0.5",
"vue-i18n": "9.2.0-beta.18",
"vue-i18n": "9.2.0-beta.26",
"vue-router": "4.0.12",
"vuedraggable": "4.1.0",
"vuex": "4.0.2",
"workbox-precaching": "6.4.1"
"workbox-precaching": "6.4.2"
},
"devDependencies": {
"@4tw/cypress-drag-drop": "2.0.0",
"@4tw/cypress-drag-drop": "2.1.0",
"@fortawesome/fontawesome-svg-core": "1.2.36",
"@fortawesome/free-regular-svg-icons": "5.15.4",
"@fortawesome/free-solid-svg-icons": "5.15.4",
"@fortawesome/vue-fontawesome": "3.0.0-5",
"@types/flexsearch": "0.7.2",
"@types/jest": "27.0.2",
"@typescript-eslint/eslint-plugin": "5.4.0",
"@typescript-eslint/parser": "5.4.0",
"@vitejs/plugin-legacy": "1.6.2",
"@vitejs/plugin-vue": "1.9.4",
"@vue/eslint-config-typescript": "9.1.0",
"autoprefixer": "10.4.0",
"@typescript-eslint/eslint-plugin": "5.9.0",
"@typescript-eslint/parser": "5.9.0",
"@vitejs/plugin-legacy": "1.6.4",
"@vitejs/plugin-vue": "2.0.1",
"@vue/eslint-config-typescript": "10.0.0",
"autoprefixer": "10.4.2",
"axios": "0.24.0",
"browserslist": "4.18.1",
"cypress": "9.0.0",
"browserslist": "4.19.1",
"caniuse-lite": "1.0.30001298",
"cypress": "9.2.0",
"cypress-file-upload": "5.0.8",
"esbuild": "0.13.14",
"eslint": "8.2.0",
"eslint-plugin-vue": "8.0.3",
"express": "4.17.1",
"esbuild": "0.14.10",
"eslint": "8.6.0",
"eslint-plugin-vue": "8.2.0",
"express": "4.17.2",
"faker": "5.5.3",
"jest": "27.3.1",
"netlify-cli": "6.14.25",
"postcss": "8.3.11",
"rollup": "2.60.0",
"netlify-cli": "8.6.15",
"happy-dom": "2.25.1",
"postcss": "8.4.5",
"postcss-preset-env": "7.2.0",
"rollup": "2.63.0",
"rollup-plugin-visualizer": "5.5.2",
"sass": "1.43.4",
"slugify": "1.6.2",
"ts-jest": "27.0.7",
"typescript": "4.4.4",
"vite": "2.6.14",
"vite-plugin-pwa": "0.11.5",
"vite-svg-loader": "3.1.0",
"vue-tsc": "0.29.5",
"sass": "1.47.0",
"slugify": "1.6.5",
"typescript": "4.5.4",
"vite": "2.7.10",
"vite-plugin-pwa": "0.11.12",
"vite-svg-loader": "3.1.1",
"vitest": "0.0.139",
"vue-tsc": "0.30.2",
"wait-on": "6.0.0",
"workbox-cli": "6.4.1"
"workbox-cli": "6.4.2"
},
"eslintConfig": {
"root": true,
"env": {
"browser": true,
"es2021": true,
"node": true
"node": true,
"vue/setup-compiler-macros": true
},
"extends": [
"eslint:recommended",
@ -117,6 +123,7 @@
"error",
"never"
],
"vue/script-setup-uses-vars": "error",
"vue/multi-word-component-names": 0
},
"parser": "vue-eslint-parser",
@ -127,30 +134,16 @@
"ignorePatterns": [
"*.test.*",
"cypress/*"
]
],
"globals": {
"defineProps": "readonly"
}
},
"postcss": {
"plugins": {
"autoprefixer": {}
}
},
"jest": {
"testPathIgnorePatterns": [
"cypress"
],
"testEnvironment": "jsdom",
"preset": "ts-jest",
"roots": [
"<rootDir>/src"
],
"transform": {
"^.+\\.(js|tsx?)$": "ts-jest"
},
"moduleFileExtensions": [
"ts",
"js",
"json"
]
},
"license": "AGPL-3.0-or-later"
"license": "AGPL-3.0-or-later",
"packageManager": "yarn@1.22.17"
}

2
run.sh
View File

@ -4,7 +4,7 @@
VIKUNJA_API_URL="${VIKUNJA_API_URL:-"/api/v1"}"
VIKUNJA_SENTRY_ENABLED="${VIKUNJA_SENTRY_ENABLED:-"false"}"
VIKUNJA_SENTRY_DSN="${VIKUNJA_SENTRY_DSN:-"https://7e684483a06a4225b3e05cc47cae7a11@sentry.kolaente.de/2"}"
VIKUNJA_SENTRY_DSN="${VIKUNJA_SENTRY_DSN:-"https://85694a2d757547cbbc90cd4b55c5a18d@o1047380.ingest.sentry.io/6024480"}"
VIKUNJA_HTTP_PORT="${VIKUNJA_HTTP_PORT:-80}"
VIKUNJA_HTTPS_PORT="${VIKUNJA_HTTPS_PORT:-443}"

View File

@ -1,112 +1,92 @@
<template>
<ready>
<div :class="{'is-touch': isTouch}">
<div :class="{'is-hidden': !online}">
<template v-if="authUser">
<top-navigation/>
<content-auth/>
</template>
<content-link-share v-else-if="authLinkShare"/>
<content-no-auth v-else/>
<notification/>
</div>
<template v-if="authUser">
<top-navigation/>
<content-auth/>
</template>
<content-link-share v-else-if="authLinkShare"/>
<no-auth-wrapper v-else>
<router-view/>
</no-auth-wrapper>
<Notification/>
<transition name="fade">
<keyboard-shortcuts v-if="keyboardShortcutsActive"/>
</transition>
</div>
<transition name="fade">
<keyboard-shortcuts v-if="keyboardShortcutsActive"/>
</transition>
</ready>
</template>
<script>
import {defineComponent} from 'vue'
import {mapState, mapGetters} from 'vuex'
<script lang="ts" setup>
import {computed, watch, Ref} from 'vue'
import {useRouter} from 'vue-router'
import {useRouteQuery} from '@vueuse/router'
import {useStore} from 'vuex'
import {useI18n} from 'vue-i18n'
import isTouchDevice from 'is-touch-device'
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 ContentAuth from './components/home/contentAuth.vue'
import ContentLinkShare from './components/home/contentLinkShare.vue'
import NoAuthWrapper from '@/components/misc/no-auth-wrapper.vue'
import Ready from '@/components/misc/ready.vue'
import Notification from './components/misc/notification'
import {KEYBOARD_SHORTCUTS_ACTIVE, ONLINE} from './store/mutation-types'
import KeyboardShortcuts from './components/misc/keyboard-shortcuts'
import TopNavigation from './components/home/topNavigation'
import ContentAuth from './components/home/contentAuth'
import ContentLinkShare from './components/home/contentLinkShare'
import ContentNoAuth from './components/home/contentNoAuth'
import {setLanguage} from './i18n'
import AccountDeleteService from '@/services/accountDelete'
import Ready from '@/components/misc/ready'
export default defineComponent({
name: 'app',
components: {
ContentNoAuth,
ContentLinkShare,
ContentAuth,
TopNavigation,
KeyboardShortcuts,
Notification,
Ready,
},
beforeMount() {
this.setupOnlineStatus()
this.setupPasswortResetRedirect()
this.setupEmailVerificationRedirect()
this.setupAccountDeletionVerification()
},
beforeCreate() {
setLanguage()
},
created() {
// Make sure to always load the home route when running with electron
if (this.$route.fullPath.endsWith('frontend/index.html')) {
this.$router.push({name: 'home'})
}
},
computed: {
isTouch() {
return isTouchDevice()
},
...mapState({
online: ONLINE,
keyboardShortcutsActive: KEYBOARD_SHORTCUTS_ACTIVE,
}),
...mapGetters('auth', [
'authUser',
'authLinkShare',
]),
},
methods: {
setupOnlineStatus() {
this.$store.commit(ONLINE, navigator.onLine)
window.addEventListener('online', () => this.$store.commit(ONLINE, navigator.onLine))
window.addEventListener('offline', () => this.$store.commit(ONLINE, navigator.onLine))
},
setupPasswortResetRedirect() {
if (typeof this.$route.query.userPasswordReset === 'undefined') {
return
}
import {useColorScheme} from '@/composables/useColorScheme'
import {useBodyClass} from '@/composables/useBodyClass'
localStorage.setItem('passwordResetToken', this.$route.query.userPasswordReset)
this.$router.push({name: 'user.password-reset.reset'})
},
setupEmailVerificationRedirect() {
if (typeof this.$route.query.userEmailConfirm === 'undefined') {
return
}
const store = useStore()
const router = useRouter()
localStorage.setItem('emailConfirmToken', this.$route.query.userEmailConfirm)
this.$router.push({name: 'user.login'})
},
async setupAccountDeletionVerification() {
if (typeof this.$route.query.accountDeletionConfirm === 'undefined') {
return
}
useBodyClass('is-touch', isTouchDevice)
const keyboardShortcutsActive = computed(() => store.state.keyboardShortcutsActive)
const accountDeletionService = new AccountDeleteService()
await accountDeletionService.confirm(this.$route.query.accountDeletionConfirm)
this.$message.success({message: this.$t('user.deletion.confirmSuccess')})
this.$store.dispatch('auth/refreshUserInfo')
},
},
})
const authUser = computed(() => store.getters['auth/authUser'])
const authLinkShare = computed(() => store.getters['auth/authLinkShare'])
const {t} = useI18n()
// setup account deletion verification
const accountDeletionConfirm = useRouteQuery('accountDeletionConfirm') as Ref<null | string>
watch(accountDeletionConfirm, async (accountDeletionConfirm) => {
if (accountDeletionConfirm === null) {
return
}
const accountDeletionService = new AccountDeleteService()
await accountDeletionService.confirm(accountDeletionConfirm)
success({message: t('user.deletion.confirmSuccess')})
store.dispatch('auth/refreshUserInfo')
}, { immediate: true })
// setup passwort reset redirect
const userPasswordReset = useRouteQuery('userPasswordReset') as Ref<null | string>
watch(userPasswordReset, (userPasswordReset) => {
if (userPasswordReset === null) {
return
}
localStorage.setItem('passwordResetToken', userPasswordReset)
router.push({name: 'user.password-reset.reset'})
}, { immediate: true })
// setup email verification redirect
const userEmailConfirm = useRouteQuery('userEmailConfirm') as Ref<null | string>
watch(userEmailConfirm, (userEmailConfirm) => {
if (userEmailConfirm === null) {
return
}
localStorage.setItem('emailConfirmToken', userEmailConfirm)
router.push({name: 'user.login'})
}, { immediate: true })
setLanguage()
useColorScheme()
</script>
<style lang="scss">

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 519 KiB

View File

@ -0,0 +1,118 @@
<template>
<component
:is="componentNodeName"
class="base-button"
:class="{ 'base-button--type-button': isButton }"
v-bind="elementBindings"
:disabled="disabled || undefined"
>
<slot />
</component>
</template>
<script lang="ts">
// see https://v3.vuejs.org/api/sfc-script-setup.html#usage-alongside-normal-script
export default {
inheritAttrs: false,
}
</script>
<script lang="ts" setup>
// this component removes styling differences between links / vue-router links and button elements
// by doing so we make it easy abstract the functionality from style and enable easier and semantic
// correct button and link usage. Also see: https://css-tricks.com/a-complete-guide-to-links-and-buttons/#accessibility-considerations
// the component tries to heuristically determine what it should be checking the props (see the
// componentNodeName and elementBindings ref for this).
// NOTE: Do NOT use buttons with @click to push routes. => Use router-links instead!
import { ref, watchEffect, computed, useAttrs, PropType } from 'vue'
const BASE_BUTTON_TYPES_MAP = Object.freeze({
button: 'button',
submit: 'submit',
})
type BaseButtonTypes = keyof typeof BASE_BUTTON_TYPES_MAP
const props = defineProps({
type: {
type: String as PropType<BaseButtonTypes>,
default: 'button',
},
disabled: {
type: Boolean,
default: false,
},
})
const componentNodeName = ref<Node['nodeName']>('button')
interface ElementBindings {
type?: string;
rel?: string,
}
const elementBindings = ref({})
const attrs = useAttrs()
watchEffect(() => {
// by default this component is a button element with the attribute of the type "button" (default prop value)
let nodeName = 'button'
let bindings: ElementBindings = {type: props.type}
// if we find a "to" prop we set it as router-link
if ('to' in attrs) {
nodeName = 'router-link'
bindings = {}
}
// if there is a href we assume the user wants an external link via a link element
// we also set the attribute rel to "noopener" but make it possible to overwrite this by the user.
if ('href' in attrs) {
nodeName = 'a'
bindings = {rel: 'noopener'}
}
componentNodeName.value = nodeName
elementBindings.value = {
...bindings,
...attrs,
}
})
const isButton = computed(() => componentNodeName.value === 'button')
</script>
<style lang="scss">
// NOTE: we do not use scoped styles to reduce specifity and make it easy to overwrite
// We reset the default styles of a button element to enable easier styling
:where(.base-button--type-button) {
border: 0;
margin: 0;
padding: 0;
text-decoration: none;
background-color: transparent;
text-align: center;
appearance: none;
}
:where(.base-button) {
cursor: pointer;
display: block;
color: inherit;
font: inherit;
user-select: none;
pointer-events: auto; // disable possible resets
&:focus {
outline: transparent;
}
&[disabled] {
cursor: default;
}
}
</style>

View File

@ -7,5 +7,11 @@ const Logo = computed(() => new Date().getMonth() === 5 ? LogoFullPride : LogoFu
</script>
<template>
<Logo alt="Vikunja" />
</template>
<Logo alt="Vikunja" class="logo" />
</template>
<style lang="scss" scoped>
.logo {
color: var(--logo-text-color);
}
</style>

View File

@ -43,7 +43,7 @@ $size: $lineWidth + 1rem;
width: $lineWidth;
left: 50%;
transform: $transformX;
background-color: $grey-400;
background-color: var(--grey-400);
border-radius: 2px;
transition: all $transition;
}
@ -62,7 +62,7 @@ $size: $lineWidth + 1rem;
&:focus {
&::before,
&::after {
background-color: $grey-600;
background-color: var(--grey-600);
}
&::before {

View File

@ -10,7 +10,7 @@ import {POWERED_BY as poweredByUrl} from '@/urls'
<style lang="scss">
.menu-bottom-link {
color: $grey-300;
color: var(--grey-300);
text-align: center;
display: block;
padding-top: 1rem;

View File

@ -40,96 +40,92 @@
</div>
</template>
<script>
import {mapState} from 'vuex'
<script lang="ts" setup>
import {watch, computed} from 'vue'
import {useStore} from 'vuex'
import {useRoute, useRouter} from 'vue-router'
import {useEventListener} from '@vueuse/core'
import {CURRENT_LIST, KEYBOARD_SHORTCUTS_ACTIVE, MENU_ACTIVE} from '@/store/mutation-types'
import Navigation from '@/components/home/navigation.vue'
import QuickActions from '@/components/quick-actions/quick-actions.vue'
export default {
name: 'contentAuth',
components: {QuickActions, Navigation},
watch: {
'$route': {
handler: 'doStuffAfterRoute',
deep: true,
},
},
created() {
this.renewTokenOnFocus()
this.loadLabels()
},
computed: mapState({
background: 'background',
menuActive: MENU_ACTIVE,
userInfo: state => state.auth.info,
authenticated: state => state.auth.authenticated,
}),
methods: {
doStuffAfterRoute() {
// this.setTitle('') // Reset the title if the page component does not set one itself
this.hideMenuOnMobile()
this.resetCurrentList()
},
resetCurrentList() {
// Reset the current list highlight in menu if the current list is not list related.
if (
this.$route.name === 'home' ||
this.$route.name === 'namespace.edit' ||
this.$route.name === 'teams.index' ||
this.$route.name === 'teams.edit' ||
this.$route.name === 'tasks.range' ||
this.$route.name === 'labels.index' ||
this.$route.name === 'migrate.start' ||
this.$route.name === 'migrate.wunderlist' ||
this.$route.name === 'user.settings' ||
this.$route.name === 'namespaces.index'
) {
return this.$store.dispatch(CURRENT_LIST, null)
}
},
renewTokenOnFocus() {
// Try renewing the token every time vikunja is loaded initially
// (When opening the browser the focus event is not fired)
this.$store.dispatch('auth/renewToken')
const store = useStore()
// Check if the token is still valid if the window gets focus again to maybe renew it
window.addEventListener('focus', () => {
const background = computed(() => store.state.background)
const menuActive = computed(() => store.state.menuActive)
if (!this.authenticated) {
return
}
const expiresIn = (this.userInfo !== null ? this.userInfo.exp : 0) - +new Date() / 1000
// If the token expiry is negative, it is already expired and we have no choice but to redirect
// the user to the login page
if (expiresIn < 0) {
this.$store.dispatch('auth/checkAuth')
this.$router.push({name: 'user.login'})
return
}
// Check if the token is valid for less than 60 hours and renew if thats the case
if (expiresIn < 60 * 3600) {
this.$store.dispatch('auth/renewToken')
console.debug('renewed token')
}
})
},
hideMenuOnMobile() {
if (window.innerWidth < 769) {
this.$store.commit(MENU_ACTIVE, false)
}
},
showKeyboardShortcuts() {
this.$store.commit(KEYBOARD_SHORTCUTS_ACTIVE, true)
},
loadLabels() {
this.$store.dispatch('labels/loadAllLabels')
},
},
function showKeyboardShortcuts() {
store.commit(KEYBOARD_SHORTCUTS_ACTIVE, true)
}
const route = useRoute()
// hide menu on mobile
watch(() => route.fullPath, () => window.innerWidth < 769 && store.commit(MENU_ACTIVE, false))
// FIXME: this is really error prone
// Reset the current list highlight in menu if the current route is not list related.
watch(() => route.name as string, (routeName) => {
if (
routeName &&
(
[
'home',
'namespace.edit',
'teams.index',
'teams.edit',
'tasks.range',
'labels.index',
'migrate.start',
'migrate.wunderlist',
'namespaces.index',
].includes(routeName) ||
routeName.startsWith('user.settings')
)
) {
store.dispatch(CURRENT_LIST, null)
}
})
// TODO: Reset the title if the page component does not set one itself
function useRenewTokenOnFocus() {
const router = useRouter()
const userInfo = computed(() => store.state.auth.info)
const authenticated = computed(() => store.state.auth.authenticated)
// Try renewing the token every time vikunja is loaded initially
// (When opening the browser the focus event is not fired)
store.dispatch('auth/renewToken')
// Check if the token is still valid if the window gets focus again to maybe renew it
useEventListener('focus', () => {
if (!authenticated.value) {
return
}
const expiresIn = (userInfo.value !== null ? userInfo.value.exp : 0) - +new Date() / 1000
// If the token expiry is negative, it is already expired and we have no choice but to redirect
// the user to the login page
if (expiresIn < 0) {
store.dispatch('auth/checkAuth')
router.push({name: 'user.login'})
return
}
// Check if the token is valid for less than 60 hours and renew if thats the case
if (expiresIn < 60 * 3600) {
store.dispatch('auth/renewToken')
console.debug('renewed token')
}
})
}
useRenewTokenOnFocus()
store.dispatch('labels/loadAllLabels')
</script>
<style lang="scss" scoped>
@ -144,7 +140,7 @@ export default {
justify-content: center;
align-items: center;
font-size: 2rem;
color: $grey-400;
color: var(--grey-400);
line-height: 1;
transition: all $transition;
@ -155,7 +151,7 @@ export default {
&:hover,
&:focus {
height: 1rem;
color: $grey-600;
color: var(--grey-600);
}
}
@ -191,7 +187,7 @@ export default {
}
.card {
background: $white;
background: var(--white);
}
}
}
@ -220,7 +216,7 @@ export default {
right: 1rem;
z-index: 4500; // The modal has a z-index of 4000
color: $grey-500;
color: var(--grey-500);
transition: color $transition;
@media screen and (max-width: $tablet) {

View File

@ -1,6 +1,6 @@
<template>
<div
:class="[background ? 'has-background' : '', $route.name+'-view']"
:class="[background ? 'has-background' : '', $route.name as string +'-view']"
:style="{'background-image': `url(${background})`}"
class="link-share-container"
>
@ -21,23 +21,16 @@
</div>
</template>
<script>
import {mapState} from 'vuex'
<script lang="ts" setup>
import {computed} from 'vue'
import {useStore} from 'vuex'
import Logo from '@/components/home/Logo.vue'
import PoweredByLink from './PoweredByLink.vue'
export default {
name: 'contentLinkShare',
components: {
Logo,
PoweredByLink,
},
computed: mapState([
'currentList',
'background',
]),
}
const store = useStore()
const currentList = computed(() => store.state.currentList)
const background = computed(() => store.state.background)
</script>
<style lang="scss" scoped>
@ -57,11 +50,11 @@ export default {
}
.title {
text-shadow: 0 0 1rem $white;
text-shadow: 0 0 1rem var(--white);
}
// FIXME: this should be defined somewhere deep
.link-share-view .card {
background-color: $white;
background-color: var(--white);
}
</style>

View File

@ -1,47 +0,0 @@
<template>
<no-auth-wrapper>
<router-view/>
</no-auth-wrapper>
</template>
<script>
import {saveLastVisited} from '@/helpers/saveLastVisited'
import NoAuthWrapper from '@/components/misc/no-auth-wrapper'
export default {
name: 'contentNoAuth',
components: {NoAuthWrapper},
computed: {
routeName() {
return this.$route.name
},
},
watch: {
routeName: {
handler(routeName) {
if (!routeName) return
this.redirectToHome()
},
immediate: true,
},
},
methods: {
redirectToHome() {
// Check if the user is already logged in and redirect them to the home page if not
if (
this.$route.name !== 'user.login' &&
this.$route.name !== 'user.password-reset.request' &&
this.$route.name !== 'user.password-reset.reset' &&
this.$route.name !== 'user.register' &&
this.$route.name !== 'link-share.auth' &&
this.$route.name !== 'openid.auth' &&
localStorage.getItem('passwordResetToken') === null &&
localStorage.getItem('emailConfirmToken') === null
) {
saveLastVisited(this.$route.name, this.$route.params)
this.$router.push({name: 'user.login'})
}
},
},
}
</script>

View File

@ -280,8 +280,8 @@ export default {
<style lang="scss" scoped>
$navbar-padding: 2rem;
$vikunja-nav-background: $light-background;
$vikunja-nav-color: $grey-700;
$vikunja-nav-background: var(--site-background);
$vikunja-nav-color: var(--grey-700);
$vikunja-nav-selected-width: 0.4rem;
.namespace-container {
@ -349,12 +349,12 @@ $vikunja-nav-selected-width: 0.4rem;
opacity: 0;
&:hover {
color: $orange;
color: var(--warning);
}
&.is-favorite {
opacity: 1;
color: $orange;
color: var(--warning);
}
}
@ -436,7 +436,7 @@ $vikunja-nav-selected-width: 0.4rem;
align-items: center;
&:hover {
background: $white;
background: var(--white);
}
:deep(.dropdown-trigger) {
@ -456,7 +456,7 @@ $vikunja-nav-selected-width: 0.4rem;
}
.ghost {
background: $grey-200;
background: var(--grey-200);
* {
opacity: 0;
@ -496,16 +496,16 @@ $vikunja-nav-selected-width: 0.4rem;
}
&.router-link-exact-active {
color: $primary;
border-left: $vikunja-nav-selected-width solid $primary;
color: var(--primary);
border-left: $vikunja-nav-selected-width solid var(--primary);
.icon {
color: $primary;
color: var(--primary);
}
}
&:hover {
border-left: $vikunja-nav-selected-width solid $primary;
border-left: $vikunja-nav-selected-width solid var(--primary);
}
}
}
@ -526,7 +526,7 @@ $vikunja-nav-selected-width: 0.4rem;
}
.icon {
color: $grey-400 !important;
color: var(--grey-400) !important;
}
}
@ -555,4 +555,8 @@ $vikunja-nav-selected-width: 0.4rem;
width: 32px;
flex-shrink: 0;
}
.namespaces-list.loader-container.is-loading {
min-height: calc(100vh - #{$navbar-height + 1.5rem + 1rem + 1.5rem});
}
</style>

View File

@ -5,7 +5,7 @@
class="navbar main-theme is-fixed-top"
role="navigation"
>
<router-link :to="{name: 'home'}" class="navbar-item logo">
<router-link :to="{name: 'home'}" class="logo-link">
<Logo width="164" height="48"/>
</router-link>
<MenuButton class="menu-button"/>
@ -37,7 +37,7 @@
<dropdown class="is-right" ref="usernameDropdown">
<template #trigger>
<x-button
type="secondary"
variant="secondary"
:shadow="false">
<span class="username">{{ userInfo.name !== '' ? userInfo.name : userInfo.username }}</span>
<span class="icon is-small">
@ -137,13 +137,18 @@ export default {
<style lang="scss" scoped>
$vikunja-nav-logo-full-width: 164px;
$user-dropdown-width-mobile: 5rem;
$hamburger-menu-icon-spacing: 1rem;
$hamburger-menu-icon-width: 28px;
.navbar {
z-index: 4 !important;
}
.logo {
.logo-link {
display: none;
padding: 0.5rem 0.75rem;
@media screen and (min-width: $tablet) {
align-self: stretch;
@ -164,7 +169,7 @@ $vikunja-nav-logo-full-width: 164px;
}
.navbar.main-theme {
background: $light-background;
background: var(--site-background);
z-index: 5 !important;
justify-content: space-between;
align-items: center;
@ -219,7 +224,7 @@ $vikunja-nav-logo-full-width: 164px;
:deep() {
.trigger-button {
cursor: pointer;
color: $grey-400;
color: var(--grey-400);
padding: .5rem;
font-size: 1.25rem;
position: relative;
@ -278,7 +283,7 @@ $vikunja-nav-logo-full-width: 164px;
}
:deep(.dropdown-trigger) {
color: $grey-400;
color: var(--grey-400);
margin-left: 1rem;
height: 1rem;
width: 1rem;

View File

@ -57,7 +57,7 @@ export default {
padding: 0 0 0 .5rem;
border-radius: $radius;
font-size: .9rem;
color: $grey-900;
color: var(--grey-900);
justify-content: space-between;
@media screen and (max-width: $desktop) {

View File

@ -1,79 +1,64 @@
<template>
<a
<BaseButton
class="button"
:class="{
'is-loading': loading,
'has-no-shadow': !shadow,
'is-primary': type === 'primary',
'is-outlined': type === 'secondary',
'is-text is-inverted has-no-shadow underline-none':
type === 'tertary',
}"
:disabled="disabled || null"
@click="click"
:href="href !== '' ? href : null"
:class="[
variantClass,
{
'is-loading': loading,
'has-no-shadow': !shadow || variant === 'tertiary',
}
]"
>
<icon :icon="icon" v-if="showIconOnly"/>
<span class="icon is-small" v-else-if="icon !== ''">
<icon :icon="icon"/>
</span>
<slot></slot>
</a>
<slot />
</BaseButton>
</template>
<script>
<script lang="ts">
export default {
name: 'x-button',
props: {
type: {
type: String,
default: 'primary',
},
href: {
type: String,
default: '',
},
to: {
default: false,
},
icon: {
default: '',
},
loading: {
type: Boolean,
default: false,
},
shadow: {
type: Boolean,
default: true,
},
disabled: {
type: Boolean,
default: false,
},
},
emits: ['click'],
computed: {
showIconOnly() {
return this.icon !== '' && typeof this.$slots.default === 'undefined'
},
},
methods: {
click(e) {
if (this.disabled) {
return
}
if (this.to !== false) {
this.$router.push(this.to)
}
this.$emit('click', e)
},
},
}
</script>
<script setup lang="ts">
import {computed, useSlots, PropType} from 'vue'
import BaseButton from '@/components/base/BaseButton.vue'
const BUTTON_TYPES_MAP = Object.freeze({
primary: 'is-primary',
secondary: 'is-outlined',
tertiary: 'is-text is-inverted underline-none',
})
type ButtonTypes = keyof typeof BUTTON_TYPES_MAP
const props = defineProps({
variant: {
type: String as PropType<ButtonTypes>,
default: 'primary',
},
icon: {
default: '',
},
loading: {
type: Boolean,
default: false,
},
shadow: {
type: Boolean,
default: true,
},
})
const variantClass = computed(() => BUTTON_TYPES_MAP[props.variant])
const slots = useSlots()
const showIconOnly = computed(() => props.icon !== '' && typeof slots.default === 'undefined')
</script>
<style lang="scss" scoped>
.button {
transition: all $transition;
@ -82,11 +67,11 @@ export default {
font-size: 0.85rem;
font-weight: bold;
height: $button-height;
box-shadow: $shadow-sm;
box-shadow: var(--shadow-sm);
display: inline-flex;
&.is-hovered,
&:hover {
box-shadow: $shadow-md;
box-shadow: var(--shadow-md);
}
&.fullheight {
@ -99,16 +84,17 @@ export default {
&:active,
&:focus,
&:focus:not(:active) {
box-shadow: $shadow-xs !important;
box-shadow: var(--shadow-xs) !important;
}
&.is-primary.is-outlined:hover {
color: $white;
color: var(--white);
}
&.is-small {
border-radius: $radius;
}
}
.is-small {
border-radius: $radius;
}
.underline-none {

View File

@ -27,7 +27,7 @@
@click="reset"
class="is-small ml-2"
:shadow="false"
type="secondary"
variant="secondary"
>
{{ $t('input.resetColor') }}
</x-button>
@ -134,7 +134,7 @@ export default {
height: $PICKER_SIZE;
overflow: hidden;
border-radius: 100%;
border: $BORDER_WIDTH solid $grey-300;
border: $BORDER_WIDTH solid var(--grey-300);
box-shadow: $shadow;
& > * {

View File

@ -101,6 +101,7 @@
class="is-fullwidth"
:shadow="false"
@click="close"
v-cy="'closeDatepicker'"
>
{{ $t('misc.confirm') }}
</x-button>
@ -258,7 +259,7 @@ export default {
position: absolute;
z-index: 99;
width: 320px;
background: $white;
background: var(--white);
border-radius: $radius;
box-shadow: $shadow;
@ -272,7 +273,7 @@ export default {
padding: 0 .5rem;
width: 100%;
height: 2.25rem;
color: $text;
color: var(--text);
transition: all $transition;
&:first-child {
@ -280,7 +281,7 @@ export default {
}
&:hover {
background: $light;
background: var(--light);
}
.text {
@ -291,7 +292,7 @@ export default {
padding-right: .25rem;
.weekday {
color: $text-light;
color: var(--text-light);
text-transform: capitalize;
}
}

View File

@ -35,7 +35,7 @@
<a @click="toggleEdit">{{ $t('input.editor.edit') }}</a>
</li>
</ul>
<x-button v-else-if="isEditActive" @click="toggleEdit" type="secondary" :shadow="false">
<x-button v-else-if="isEditActive" @click="toggleEdit" variant="secondary" :shadow="false" v-cy="'saveEditor'">
{{ $t('misc.save') }}
</x-button>
</template>
@ -338,15 +338,20 @@ $editor-border-color: #ddd;
.CodeMirror {
padding: .5rem;
border: 1px solid $editor-border-color;
background: var(--white);
&-lines pre {
margin: 0 !important;
}
&-placeholder {
color: $grey-400 !important;
color: var(--grey-400) !important;
font-style: italic;
}
&-cursor {
border-color: var(--grey-700);
}
}
.editor-preview {
@ -383,7 +388,7 @@ $editor-border-color: #ddd;
pre.CodeMirror-line {
margin-bottom: 0 !important;
color: $grey-700 !important;
color: var(--grey-700) !important;
}
.cm-header {
@ -409,10 +414,10 @@ ul.actions {
}
&, a {
color: $grey-500;
color: var(--grey-500);
&.done-edit {
color: $primary;
color: var(--primary);
}
}

View File

@ -106,7 +106,7 @@ svg {
}
.check:hover svg {
stroke: $primary;
stroke: var(--primary);
}
.is-disabled .check:hover svg {
@ -125,7 +125,7 @@ polyline {
input[type=checkbox]:checked + .check {
svg {
stroke: $primary;
stroke: var(--primary);
}
path {

View File

@ -380,23 +380,23 @@ export default {
&.has-search-results .input-wrapper {
border-radius: $radius $radius 0 0;
border-color: $primary !important;
background: $white !important;
border-color: var(--primary) !important;
background: var(--white) !important;
&, &:focus-within {
border-bottom-color: $grey-200 !important;
border-bottom-color: var(--grey-200) !important;
}
}
.input-wrapper {
padding: 0;
background: $white !important;
border-color: $grey-200 !important;
background: var(--white) !important;
border-color: var(--grey-200) !important;
flex-wrap: wrap;
height: auto;
&:hover {
border-color: $grey-300 !important;
border-color: var(--grey-300) !important;
}
.input {
@ -422,8 +422,8 @@ export default {
}
&:focus-within {
border-color: $primary !important;
background: $white !important;
border-color: var(--primary) !important;
background: var(--white) !important;
}
.loader {
@ -432,9 +432,9 @@ export default {
}
.search-results {
background: $white;
background: var(--white);
border-radius: 0 0 $radius $radius;
border: 1px solid $primary;
border: 1px solid var(--primary);
border-top: none;
max-height: 50vh;
@ -457,7 +457,7 @@ export default {
text-transform: none;
font-family: $family-sans-serif;
font-weight: normal;
padding: .5rem 0;
padding: .5rem;
border: none;
cursor: pointer;
@ -477,20 +477,20 @@ export default {
font-size: .75rem;
color: transparent;
transition: color $transition;
padding: 0 .5rem;
padding-left: .5rem;
}
&:focus, &:hover {
background: $grey-100;
background: var(--grey-100);
box-shadow: none !important;
.hint-text {
color: $text;
color: var(--text);
}
}
&:active {
background: $grey-200;
background: var(--grey-200);
}
}
}

View File

@ -1,7 +1,7 @@
<template>
<x-button
v-if="hasFilters"
type="secondary"
variant="secondary"
@click="clearFilters"
>
{{ $t('filters.clear') }}
@ -10,7 +10,7 @@
<template #trigger="{toggle}">
<x-button
@click.prevent.stop="toggle()"
type="secondary"
variant="secondary"
icon="filter"
>
{{ $t('filters.title') }}

View File

@ -1,23 +1,24 @@
<template>
<card class="filters has-overflow">
<fancycheckbox v-model="params.filter_include_nulls">
{{ $t('filters.attributes.includeNulls') }}
</fancycheckbox>
<fancycheckbox
v-model="filters.requireAllFilters"
@change="setFilterConcat()"
>
{{ $t('filters.attributes.requireAll') }}
</fancycheckbox>
<div class="field">
<label class="label">
<fancycheckbox v-model="params.filter_include_nulls">
{{ $t('filters.attributes.includeNulls') }}
</fancycheckbox>
<fancycheckbox
v-model="filters.requireAllFilters"
@change="setFilterConcat()"
>
{{ $t('filters.attributes.requireAll') }}
</fancycheckbox>
<fancycheckbox @change="setDoneFilter" v-model="filters.done">
{{ $t('filters.attributes.showDoneTasks') }}
</label>
<div class="control">
<fancycheckbox @change="setDoneFilter" v-model="filters.done">
{{ $t('filters.attributes.showDoneTasks') }}
</fancycheckbox>
</div>
</fancycheckbox>
<fancycheckbox
v-if="!$route.name.includes('list.kanban') || !$route.name.includes('list.table')"
v-model="sortAlphabetically"
>
{{ $t('filters.attributes.sortAlphabetically') }}
</fancycheckbox>
</div>
<div class="field">
<label class="label">{{ $t('misc.search') }}</label>
@ -190,6 +191,7 @@ import NamespaceService from '@/services/namespace'
import EditLabels from '@/components/tasks/partials/editLabels.vue'
import {objectToSnakeCase} from '@/helpers/case'
import {getDefaultParams} from '@/components/tasks/mixins/taskList'
// FIXME: merge with DEFAULT_PARAMS in taskList.js
const DEFAULT_PARAMS = {
@ -220,6 +222,8 @@ const DEFAULT_FILTERS = {
namespace: '',
}
export const ALPHABETICAL_SORT = 'title'
export default {
name: 'filters',
components: {
@ -272,6 +276,18 @@ export default {
},
},
computed: {
sortAlphabetically: {
get() {
return this.params?.sort_by?.find(sortBy => sortBy === ALPHABETICAL_SORT) !== undefined
},
set(sortAlphabetically) {
this.params.sort_by = sortAlphabetically
? [ALPHABETICAL_SORT]
: getDefaultParams().sort_by
this.change()
},
},
foundLabels() {
return this.$store.getters['labels/filterLabelsByQuery'](this.labels, this.query)
},

View File

@ -20,64 +20,61 @@
:class="{'is-favorite': list.isFavorite, 'is-archived': list.isArchived}"
@click.stop="toggleFavoriteList(list)"
class="favorite">
<icon icon="star" v-if="list.isFavorite"/>
<icon :icon="['far', 'star']" v-else/>
<icon :icon="list.isFavorite ? 'star' : ['far', 'star']" />
</span>
</div>
<div class="title">{{ list.title }}</div>
</router-link>
</template>
<script>
<script lang="ts" setup>
import {ref, watch} from 'vue'
import {useStore} from 'vuex'
import ListService from '@/services/list'
export default {
name: 'list-card',
data() {
return {
background: null,
backgroundLoading: false,
}
},
props: {
list: {
required: true,
},
showArchived: {
default: false,
type: Boolean,
},
},
watch: {
list: {
handler: 'loadBackground',
immediate: true,
},
},
methods: {
async loadBackground() {
if (this.list === null || !this.list.backgroundInformation || this.backgroundLoading) {
return
}
import {colorIsDark} from '@/helpers/color/colorIsDark'
this.backgroundLoading = true
const background = ref<string | null>(null)
const backgroundLoading = ref(false)
const listService = new ListService()
try {
this.background = await listService.background(this.list)
} finally {
this.backgroundLoading = false
}
},
toggleFavoriteList(list) {
// The favorites pseudo list is always favorite
// Archived lists cannot be marked favorite
if (list.id === -1 || list.isArchived) {
return
}
this.$store.dispatch('lists/toggleListFavorite', list)
},
const props = defineProps({
list: {
type: Object,
required: true,
},
showArchived: {
default: false,
type: Boolean,
},
})
watch(props.list, loadBackground, { immediate: true })
async function loadBackground() {
if (props.list === null || !props.list.backgroundInformation || backgroundLoading.value) {
return
}
backgroundLoading.value = true
const listService = new ListService()
try {
background.value = await listService.background(props.list)
} finally {
backgroundLoading.value = false
}
}
const store = useStore()
function toggleFavoriteList(list) {
// The favorites pseudo list is always favorite
// Archived lists cannot be marked favorite
if (list.id === -1 || list.isArchived) {
return
}
store.dispatch('lists/toggleListFavorite', list)
}
</script>
@ -86,11 +83,11 @@ export default {
cursor: pointer;
width: calc((100% - #{($lists-per-row - 1) * 1rem}) / #{$lists-per-row});
height: $list-height;
background: $white;
background: var(--white);
margin: 0 $list-spacing $list-spacing 0;
padding: 1rem;
border-radius: $radius;
box-shadow: $shadow-sm;
box-shadow: var(--shadow-sm);
transition: box-shadow $transition;
display: flex;
@ -98,13 +95,13 @@ export default {
flex-wrap: wrap;
&:hover {
box-shadow: $shadow-md;
box-shadow: var(--shadow-md);
}
&:active,
&:focus,
&:focus:not(:active) {
box-shadow: $shadow-xs !important;
box-shadow: var(--shadow-xs) !important;
}
@media screen and (min-width: $widescreen) {
@ -158,7 +155,7 @@ export default {
font-family: $vikunja-font;
font-weight: 400;
font-size: 1.5rem;
color: $text;
color: var(--text);
width: 100%;
margin-bottom: 0;
max-height: calc(100% - 2rem); // 1rem padding, 1rem height of the "is archived" badge
@ -171,7 +168,7 @@ export default {
}
&.has-light-text .title {
color: $light;
color: var(--light);
}
&.has-background {
@ -180,8 +177,8 @@ export default {
background-position: center;
.title {
text-shadow: 0 0 10px $black, 1px 1px 5px $grey-700, -1px -1px 5px $grey-700;
color: $white;
text-shadow: 0 0 10px var(--black), 1px 1px 5px var(--grey-700), -1px -1px 5px var(--grey-700);
color: var(--white);
}
}
@ -190,7 +187,7 @@ export default {
opacity: 0;
&:hover {
color: $orange;
color: var(--warning);
}
&.is-archived {
@ -200,7 +197,7 @@ export default {
&.is-favorite {
display: inline-block;
opacity: 1;
color: $orange;
color: var(--warning);
}
}

View File

@ -1,47 +1,34 @@
<template>
<div
v-if="isDone"
class="is-done"
:class="{ 'is-done--small': variant === variants.SMALL }"
>
{{ $t('task.attributes.done') }}
</div>
v-if="isDone"
class="is-done"
:class="{ 'is-done--small': variant === 'small' }"
>
{{ $t('task.attributes.done') }}
</div>
</template>
<script>
const VARIANTS = {
DEFAULT: 'default',
SMALL: 'small',
}
<script lang="ts" setup>
import {PropType} from 'vue'
type Variants = 'default' | 'small'
export default {
name: 'Done',
data() {
return {
variants: VARIANTS,
}
defineProps({
isDone: {
type: Boolean,
default: false,
},
props: {
isDone: {
type: Boolean,
default: false,
},
variant: {
type: String,
default: VARIANTS.DEFAULT,
validator: (variant) => Object.values(VARIANTS).includes(variant),
},
variant: {
type: String as PropType<Variants>,
default: 'default',
},
}
})
</script>
<style lang="scss" scoped>
.is-done {
background: $green;
color: $white;
background: var(--success);
color: var(--white);
padding: .5rem;
font-weight: bold;
line-height: 1;

View File

@ -23,34 +23,32 @@
</div>
</div>
<div class="api-url-info" v-else>
<i18n-t keypath="apiConfig.signInOn">
<i18n-t keypath="apiConfig.use">
<span class="url" v-tooltip="apiUrl"> {{ apiDomain }} </span>
</i18n-t>
<br/>
<a @click="() => (configureApi = true)">{{ $t('apiConfig.change') }}</a>
</div>
<div
class="notification is-success mt-2"
v-if="successMsg !== '' && errorMsg === ''"
>
<message variant="success" v-if="successMsg !== '' && errorMsg === ''" class="mt-2">
{{ successMsg }}
</div>
<div
class="notification is-danger mt-2"
v-if="errorMsg !== '' && successMsg === ''"
>
</message>
<message variant="danger" v-if="errorMsg !== '' && successMsg === ''" class="mt-2">
{{ errorMsg }}
</div>
</message>
</div>
</template>
<script>
import Message from '@/components/misc/message'
import {parseURL} from 'ufo'
import {checkAndSetApiUrl} from '@/helpers/checkAndSetApiUrl'
export default {
name: 'apiConfig',
components: {
Message,
},
data() {
return {
configureApi: false,
@ -103,7 +101,7 @@ export default {
// Set it + save it to local storage to save us the hoops
this.errorMsg = ''
this.successMsg = this.$t('apiConfig.success', {domain: this.apiDomain})
this.$message.success({message: this.$t('apiConfig.success', {domain: this.apiDomain})})
this.configureApi = false
this.apiUrl = url
this.$emit('foundApi', this.apiUrl)
@ -128,6 +126,6 @@ export default {
}
.url {
border-bottom: 1px dashed $primary;
border-bottom: 1px dashed var(--primary);
}
</style>

View File

@ -24,61 +24,59 @@
</div>
</template>
<script>
export default {
name: 'card',
props: {
title: {
type: String,
default: '',
},
padding: {
type: Boolean,
default: true,
},
hasClose: {
type: Boolean,
default: false,
},
closeIcon: {
type: String,
default: 'times',
},
shadow: {
type: Boolean,
default: true,
},
hasContent: {
type: Boolean,
default: true,
},
loading: {
type: Boolean,
default: false,
},
<script setup lang="ts">
defineProps({
title: {
type: String,
default: '',
},
emits: ['close'],
}
padding: {
type: Boolean,
default: true,
},
hasClose: {
type: Boolean,
default: false,
},
closeIcon: {
type: String,
default: 'times',
},
shadow: {
type: Boolean,
default: true,
},
hasContent: {
type: Boolean,
default: true,
},
loading: {
type: Boolean,
default: false,
},
})
defineEmits(['close'])
</script>
<style lang="scss" scoped>
.card {
background-color: $white;
background-color: var(--white);
border-radius: $radius;
margin-bottom: 1rem;
border: 1px solid $grey-200;
box-shadow: $shadow-sm;
border: 1px solid var(--card-border-color);
box-shadow: var(--shadow-sm);
}
.card-header {
box-shadow: none;
border-bottom: 1px solid $grey-200;
border-bottom: 1px solid var(--card-border-color);
border-radius: $radius $radius 0 0;
}
// FIXME: should maybe be merged somehow with modal
:deep(.modal-card-foot) {
background-color: $grey-50;
background-color: var(--grey-50);
border-top: 0;
}
</style>

View File

@ -14,25 +14,25 @@
</div>
<footer class="modal-card-foot is-flex is-justify-content-flex-end">
<x-button
v-if="tertiary !== ''"
:shadow="false"
type="tertary"
@click.prevent.stop="$emit('tertary')"
v-if="tertary !== ''"
variant="tertiary"
@click.prevent.stop="$emit('tertiary')"
>
{{ tertary }}
{{ tertiary }}
</x-button>
<x-button
type="secondary"
variant="secondary"
@click.prevent.stop="$router.back()"
>
{{ $t('misc.cancel') }}
</x-button>
<x-button
type="primary"
v-if="primaryLabel !== ''"
variant="primary"
@click.prevent.stop="primary"
:icon="primaryIcon"
:disabled="primaryDisabled"
v-if="primaryLabel !== ''"
>
{{ primaryLabel }}
</x-button>
@ -65,7 +65,7 @@ export default {
type: Boolean,
default: false,
},
tertary: {
tertiary: {
type: String,
default: '',
},
@ -78,7 +78,7 @@ export default {
default: false,
},
},
emits: ['create', 'primary', 'tertary'],
emits: ['create', 'primary', 'tertiary'],
methods: {
primary() {
this.$emit('create')

View File

@ -11,18 +11,15 @@
</router-link>
</template>
<script>
export default {
name: 'dropdown-item',
props: {
to: {
required: true,
},
icon: {
type: String,
required: false,
default: '',
},
<script lang="ts" setup>
defineProps({
to: {
required: true,
},
}
icon: {
type: String,
required: false,
default: '',
},
})
</script>

View File

@ -1,6 +1,6 @@
<template>
<div class="dropdown is-right is-active" ref="dropdown">
<div class="dropdown-trigger" @click="open = !open">
<div class="dropdown-trigger is-flex" @click="open = !open">
<slot name="trigger" :close="close">
<icon :icon="triggerIcon" class="icon"/>
</slot>

View File

@ -1,19 +1,16 @@
<template>
<div class="notification is-danger">
<message variant="danger">
<i18n-t keypath="loadingError.failed">
<a @click="reload">{{ $t('loadingError.tryAgain') }}</a>
<a href="https://vikunja.io/contact/" rel="noreferrer noopener nofollow" target="_blank">{{ $t('loadingError.contact') }}</a>
</i18n-t>
</div>
</message>
</template>
<script>
export default {
name: 'error',
methods: {
reload() {
window.location.reload()
},
},
<script lang="ts" setup>
import Message from '@/components/misc/message.vue'
function reload() {
window.location.reload()
}
</script>

View File

@ -4,13 +4,11 @@
<template v-for="(s, i) in shortcuts" :key="i">
<h3>{{ $t(s.title) }}</h3>
<div class="message is-primary">
<div class="message-body">
{{
s.available($route) ? $t('keyboardShortcuts.currentPageOnly') : $t('keyboardShortcuts.allPages')
}}
</div>
</div>
<message>
{{
s.available($route) ? $t('keyboardShortcuts.currentPageOnly') : $t('keyboardShortcuts.allPages')
}}
</message>
<dl class="shortcut-list">
<template v-for="(sc, si) in s.shortcuts" :key="si">
@ -30,11 +28,15 @@
<script>
import {KEYBOARD_SHORTCUTS_ACTIVE} from '@/store/mutation-types'
import Shortcut from '@/components/misc/shortcut.vue'
import Message from '@/components/misc/message'
import {KEYBOARD_SHORTCUTS} from './shortcuts'
export default {
name: 'keyboard-shortcuts',
components: {Shortcut},
components: {
Message,
Shortcut,
},
data() {
return {
shortcuts: KEYBOARD_SHORTCUTS,

View File

@ -6,23 +6,21 @@
</div>
</template>
<script>
import {mapState} from 'vuex'
<script lang="ts" setup>
import {computed} from 'vue'
import {useStore} from 'vuex'
export default {
name: 'legal',
computed: mapState({
imprintUrl: state => state.config.legal.imprintUrl,
privacyPolicyUrl: state => state.config.legal.privacyPolicyUrl,
}),
}
const store = useStore()
const imprintUrl = computed(() => store.state.config.legal.imprintUrl)
const privacyPolicyUrl = computed(() => store.state.config.legal.privacyPolicyUrl)
</script>
<style lang="scss" scoped>
.legal-links {
margin-top: 1rem;
text-align: right;
color: $grey-300;
color: var(--grey-300);
font-size: 1rem;
}
</style>

View File

@ -2,12 +2,6 @@
<div class="loader-container is-loading"></div>
</template>
<script>
export default {
name: 'loading',
}
</script>
<style scoped>
.loader-container {
height: 100%;

View File

@ -0,0 +1,48 @@
<template>
<div class="message-wrapper">
<div class="message" :class="variant">
<slot/>
</div>
</div>
</template>
<script lang="ts" setup>
defineProps({
variant: {
type: String,
default: 'info',
},
})
</script>
<style lang="scss" scoped>
.message-wrapper {
border-radius: $radius;
background: var(--white);
}
.message {
padding: .75rem 1rem;
border-radius: $radius;
}
.info {
border: 1px solid var(--primary);
background: hsla(var(--primary-hsl), .05);
}
.danger {
border: 1px solid var(--danger);
background: hsla(var(--danger-h), var(--danger-s), var(--danger-l), .05);
}
.warning {
border: 1px solid var(--warning);
background: hsla(var(--warning-h), var(--warning-s), var(--warning-l), .05);
}
.success {
border: 1px solid var(--success);
background: hsla(var(--success-h), var(--success-s), var(--success-l), .05);
}
</style>

View File

@ -1,39 +1,134 @@
<template>
<div class="no-auth-wrapper">
<Logo class="logo" width="200" height="58"/>
<div class="noauth-container">
<Logo width="400" height="117" />
<div class="message is-info" v-if="motd !== ''">
<div class="message-header">
<p>{{ $t('misc.info') }}</p>
</div>
<div class="message-body">
<section class="image" :class="{'has-message': motd !== ''}">
<Message v-if="motd !== ''">
{{ motd }}
</Message>
<h2 class="image-title">
{{ $t('misc.welcomeBack') }}
</h2>
</section>
<section class="content">
<div>
<h2 class="title" v-if="title">{{ title }}</h2>
<api-config/>
<slot/>
</div>
</div>
<slot/>
<legal/>
</section>
</div>
</div>
</template>
<script setup>
<script lang="ts" setup>
import Logo from '@/components/home/Logo.vue'
import Message from '@/components/misc/message.vue'
import Legal from '@/components/misc/legal.vue'
import ApiConfig from '@/components/misc/api-config.vue'
import {useStore} from 'vuex'
import {computed} from 'vue'
import {useRoute} from 'vue-router'
import {useI18n} from 'vue-i18n'
import {useTitle} from '@/composables/useTitle'
const route = useRoute()
const store = useStore()
const {t} = useI18n()
const motd = computed(() => store.state.config.motd)
// @ts-ignore
const title = computed(() => t(route.meta.title ?? ''))
useTitle(() => title.value)
</script>
<style lang="scss" scoped>
.no-auth-wrapper {
background: url('@/assets/llama.svg') no-repeat bottom left fixed $light-background;
background: var(--site-background) url('@/assets/llama.svg?url') no-repeat fixed bottom left;
min-height: 100vh;
display: flex;
flex-direction: column;
place-items: center;
@media screen and (max-width: $fullhd) {
padding-bottom: 15rem;
}
}
.noauth-container {
max-width: 450px;
max-width: $desktop;
width: 100%;
margin: 0 auto;
min-height: 60vh;
display: flex;
background-color: var(--white);
box-shadow: var(--shadow-md);
overflow: hidden;
@media screen and (min-width: $desktop) {
border-radius: $radius;
}
}
.image {
width: 50%;
padding: 1rem;
display: flex;
flex-direction: column;
justify-content: flex-end;
@media screen and (max-width: $tablet) {
display: none;
}
@media screen and (min-width: $tablet) {
background: url('@/assets/no-auth-image.jpg') no-repeat bottom/cover;
position: relative;
&.has-message {
justify-content: space-between;
}
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, .2);
}
> * {
position: relative;
}
}
}
.content {
display: flex;
justify-content: space-between;
flex-direction: column;
padding: 2rem 2rem 1.5rem;
@media screen and (max-width: $desktop) {
width: 100%;
max-width: 450px;
margin-inline: auto;
}
@media screen and (min-width: $desktop) {
width: 50%;
}
}
.logo {
max-width: 100%;
margin: 1rem 0;
}
.image-title {
color: var(--white);
font-size: 2.5rem;
}
</style>

View File

@ -26,7 +26,7 @@
@click="action.callback"
:shadow="false"
class="is-small"
type="secondary"
variant="secondary"
v-for="(action, i) in item.data.actions"
>
{{ action.title }}

View File

@ -21,11 +21,11 @@
<li :key="`page-${i}`" v-for="(p, i) in pages">
<span class="pagination-ellipsis" v-if="p.isEllipsis">&hellip;</span>
<router-link
v-else
class="pagination-link"
:aria-label="'Goto page ' + p.number"
:class="{ 'is-current': p.number === currentPage }"
:to="getRouteForPagination(p.number)"
class="pagination-link"
v-else
>
{{ p.number }}
</router-link>
@ -34,8 +34,10 @@
</nav>
</template>
<script>
function createPagination(totalPages, currentPage) {
<script lang="ts" setup>
import {computed} from 'vue'
function createPagination(totalPages: number, currentPage: number) {
const pages = []
for (let i = 0; i < totalPages; i++) {
@ -79,42 +81,30 @@ function getRouteForPagination(page = 1, type = 'list') {
}
}
export default {
name: 'Pagination',
props: {
totalPages: {
type: Number,
required: true,
},
currentPage: {
type: Number,
default: 0,
},
const props = defineProps({
totalPages: {
type: Number,
required: true,
},
computed: {
pages() {
return createPagination(this.totalPages, this.currentPage)
},
currentPage: {
type: Number,
default: 0,
},
})
methods: {
getRouteForPagination,
},
}
const pages = computed(() => createPagination(props.totalPages, props.currentPage))
</script>
<style lang="scss" scoped>
.pagination {
padding-bottom: 1rem;
}
.pagination-previous,
.pagination-next {
&:not(:disabled):hover {
background: $scheme-main;
cursor: pointer;
}
.pagination-previous,
.pagination-next {
&:not(:disabled):hover {
background: $scheme-main;
cursor: pointer;
}
}
</style>

View File

@ -13,10 +13,10 @@
<section v-else-if="error !== ''">
<no-auth-wrapper>
<card>
<p v-if="error === errorNoApiUrl">
<p v-if="error === ERROR_NO_API_URL">
{{ $t('ready.noApiUrlConfigured') }}
</p>
<div class="notification is-danger" v-else>
<message variant="danger" v-else>
<p>
{{ $t('ready.errorOccured') }}<br/>
{{ error }}
@ -24,7 +24,7 @@
<p>
{{ $t('ready.checkApiUrl') }}
</p>
</div>
</message>
<api-config :configure-open="true" @found-api="load"/>
</card>
</no-auth-wrapper>
@ -40,49 +40,35 @@
</transition>
</template>
<script>
import Logo from '@/assets/logo.svg?component'
import ApiConfig from '@/components/misc/api-config'
import NoAuthWrapper from '@/components/misc/no-auth-wrapper'
import {mapState} from 'vuex'
import {ERROR_NO_API_URL} from '@/helpers/checkAndSetApiUrl'
<script lang="ts" setup>
import {ref, computed} from 'vue'
import {useStore} from 'vuex'
export default {
name: 'ready',
components: {
Logo,
NoAuthWrapper,
ApiConfig,
},
data() {
return {
error: '',
errorNoApiUrl: ERROR_NO_API_URL,
}
},
created() {
this.load()
},
computed: {
ready() {
return this.$store.state.vikunjaReady
},
showLoading() {
return !this.ready && this.error === ''
},
...mapState([
'online',
]),
},
methods: {
load() {
this.$store.dispatch('loadApp')
.catch(e => {
this.error = e
})
},
},
import Logo from '@/assets/logo.svg?component'
import ApiConfig from '@/components/misc/api-config.vue'
import Message from '@/components/misc/message.vue'
import NoAuthWrapper from '@/components/misc/no-auth-wrapper.vue'
import {ERROR_NO_API_URL} from '@/helpers/checkAndSetApiUrl'
import {useOnline} from '@/composables/useOnline'
const store = useStore()
const ready = computed(() => store.state.vikunjaReady)
const online = useOnline()
const error = ref('')
const showLoading = computed(() => !ready.value && error.value === '')
async function load() {
try {
await store.dispatch('loadApp')
} catch(e: any) {
error.value = e
}
}
load()
</script>
<style lang="scss" scoped>
@ -98,7 +84,7 @@ export default {
left: 0;
bottom: 0;
right: 0;
background: $grey-100;
background: var(--grey-100);
z-index: 99;
}
@ -112,8 +98,8 @@ export default {
margin-right: 1rem;
&.is-loading::after {
border-left-color: $grey-400;
border-bottom-color: $grey-400;
border-left-color: var(--grey-400);
border-bottom-color: var(--grey-400);
}
}

View File

@ -7,24 +7,21 @@
</component>
</template>
<script>
export default {
name: 'shortcut',
props: {
keys: {
type: Array,
required: true,
},
combination: {
type: String,
default: '+',
},
is: {
type: String,
default: 'div',
},
<script lang="ts" setup>
defineProps({
keys: {
type: Array,
required: true,
},
}
combination: {
type: String,
default: '+',
},
is: {
type: String,
default: 'div',
},
})
</script>
<style lang="scss" scoped>
@ -35,8 +32,8 @@ export default {
kbd {
padding: .1rem .35rem;
border: 1px solid $grey-300;
background: $grey-100;
border: 1px solid var(--grey-300);
background: var(--grey-100);
border-radius: 3px;
font-size: .75rem;
}

View File

@ -1,6 +1,6 @@
<template>
<x-button
type="secondary"
variant="secondary"
:icon="icon"
v-tooltip="tooltipText"
@click="changeSubscription"
@ -22,91 +22,89 @@
</a>
</template>
<script>
<script lang="ts" setup>
import {computed, shallowRef} from 'vue'
import {useI18n} from 'vue-i18n'
import SubscriptionService from '@/services/subscription'
import SubscriptionModel from '@/models/subscription'
export default {
name: 'task-subscription',
data() {
return {
subscriptionService: new SubscriptionService(),
}
},
props: {
entity: {
required: true,
type: String,
},
subscription: {
required: true,
},
entityId: {
required: true,
},
isButton: {
type: Boolean,
default: true,
},
},
emits: ['change'],
computed: {
tooltipText() {
if (this.disabled) {
return this.$t('task.subscription.subscribedThroughParent', {
entity: this.entity,
parent: this.subscription.entity,
})
}
import {success} from '@/message'
return this.subscription !== null ?
this.$t('task.subscription.subscribed', {entity: this.entity}) :
this.$t('task.subscription.notSubscribed', {entity: this.entity})
},
buttonText() {
return this.subscription !== null ? this.$t('task.subscription.unsubscribe') : this.$t('task.subscription.subscribe')
},
icon() {
return this.subscription !== null ? ['far', 'bell-slash'] : 'bell'
},
disabled() {
if (this.subscription === null) {
return false
}
return this.subscription.entity !== this.entity
},
const props = defineProps({
entity: {
required: true,
type: String,
},
methods: {
changeSubscription() {
if (this.disabled) {
return
}
if (this.subscription === null) {
this.subscribe()
} else {
this.unsubscribe()
}
},
async subscribe() {
const subscription = new SubscriptionModel({
entity: this.entity,
entityId: this.entityId,
})
await this.subscriptionService.create(subscription)
this.$emit('change', subscription)
this.$message.success({message: this.$t('task.subscription.subscribeSuccess', {entity: this.entity})})
},
async unsubscribe() {
const subscription = new SubscriptionModel({
entity: this.entity,
entityId: this.entityId,
})
await this.subscriptionService.delete(subscription)
this.$emit('change', null)
this.$message.success({message: this.$t('task.subscription.unsubscribeSuccess', {entity: this.entity})})
},
subscription: {
required: true,
},
entityId: {
required: true,
},
isButton: {
type: Boolean,
default: true,
},
})
const emit = defineEmits(['change'])
const subscriptionService = shallowRef(new SubscriptionService())
const {t} = useI18n()
const tooltipText = computed(() => {
if (disabled.value) {
return t('task.subscription.subscribedThroughParent', {
entity: props.entity,
parent: props.subscription.entity,
})
}
return props.subscription !== null ?
t('task.subscription.subscribed', {entity: props.entity}) :
t('task.subscription.notSubscribed', {entity: props.entity})
})
const buttonText = computed(() => props.subscription !== null ? t('task.subscription.unsubscribe') : t('task.subscription.subscribe'))
const icon = computed(() => props.subscription !== null ? ['far', 'bell-slash'] : 'bell')
const disabled = computed(() => {
if (props.subscription === null) {
return false
}
return props.subscription.entity !== props.entity
})
function changeSubscription() {
if (disabled.value) {
return
}
if (props.subscription === null) {
subscribe()
} else {
unsubscribe()
}
}
async function subscribe() {
const subscription = new SubscriptionModel({
entity: props.entity,
entityId: props.entityId,
})
await subscriptionService.value.create(subscription)
emit('change', subscription)
success({message: t('task.subscription.subscribeSuccess', {entity: props.entity})})
}
async function unsubscribe() {
const subscription = new SubscriptionModel({
entity: props.entity,
entityId: props.entityId,
})
await subscriptionService.value.delete(subscription)
emit('change', null)
success({message: t('task.subscription.unsubscribeSuccess', {entity: props.entity})})
}
</script>

View File

@ -11,31 +11,28 @@
</div>
</template>
<script>
export default {
name: 'user',
props: {
user: {
required: true,
type: Object,
},
showUsername: {
required: false,
type: Boolean,
default: true,
},
avatarSize: {
required: false,
type: Number,
default: 50,
},
isInline: {
required: false,
type: Boolean,
default: false,
},
<script lang="ts" setup>
defineProps({
user: {
required: true,
type: Object,
},
}
showUsername: {
required: false,
type: Boolean,
default: true,
},
avatarSize: {
required: false,
type: Number,
default: 50,
},
isInline: {
required: false,
type: Boolean,
default: false,
},
})
</script>
<style lang="scss" scoped>

View File

@ -31,14 +31,15 @@
<div class="actions">
<x-button
@click="$emit('close')"
type="tertary"
variant="tertiary"
class="has-text-danger"
>
{{ $t('misc.cancel') }}
</x-button>
<x-button
@click="$emit('submit')"
type="primary"
variant="primary"
v-cy="'modalPrimary'"
:shadow="false"
>
{{ $t('misc.doit') }}
@ -193,10 +194,6 @@ export default {
align-items: center;
}
.message-body {
padding: .5rem .75rem;
}
}
}

View File

@ -9,32 +9,23 @@
/>
</template>
<script>
<script lang="ts" setup>
import {ref, computed} from 'vue'
import {useStore} from 'vuex'
import Multiselect from '@/components/input/multiselect.vue'
export default {
name: 'namespace-search',
emits: ['selected'],
data() {
return {
query: '',
}
},
components: {
Multiselect,
},
computed: {
namespaces() {
return this.$store.getters['namespaces/searchNamespace'](this.query)
},
},
methods: {
findNamespaces(query) {
this.query = query
},
select(namespace) {
this.$emit('selected', namespace)
},
},
const emit = defineEmits(['selected'])
const query = ref('')
const store = useStore()
const namespaces = computed(() => store.getters['namespaces/searchNamespace'](query.value))
function findNamespaces(newQuery: string) {
query.value = newQuery
}
function select(namespace) {
emit('selected', namespace)
}
</script>

View File

@ -52,30 +52,22 @@
</dropdown>
</template>
<script>
<script setup lang="ts">
import {ref, onMounted} from 'vue'
import Dropdown from '@/components/misc/dropdown.vue'
import DropdownItem from '@/components/misc/dropdown-item.vue'
import TaskSubscription from '@/components/misc/subscription.vue'
export default {
name: 'namespace-settings-dropdown',
data() {
return {
subscription: null,
}
const props = defineProps({
namespace: {
type: Object, // NamespaceModel
required: true,
},
components: {
DropdownItem,
Dropdown,
TaskSubscription,
},
props: {
namespace: {
required: true,
},
},
mounted() {
this.subscription = this.namespace.subscription
},
}
})
const subscription = ref(null)
onMounted(() => {
subscription.value = props.namespace.subscription
})
</script>

View File

@ -145,9 +145,9 @@ export default {
width: .75rem;
height: .75rem;
background: $primary;
background: var(--primary);
border-radius: 100%;
border: 2px solid $white;
border: 2px solid var(--white);
}
.notifications-list {
@ -157,12 +157,12 @@ export default {
max-height: 400px;
overflow-y: auto;
background: $white;
background: var(--white);
width: 350px;
max-width: calc(100vw - 2rem);
padding: .75rem .25rem;
border-radius: $radius;
box-shadow: $shadow-sm;
box-shadow: var(--shadow-sm);
font-size: .85rem;
@media screen and (max-width: $tablet) {
@ -183,14 +183,14 @@ export default {
transition: background-color $transition;
&:hover {
background: $grey-100;
background: var(--grey-100);
border-radius: $radius;
}
.read-indicator {
width: .35rem;
height: .35rem;
background: $primary;
background: var(--primary);
border-radius: 100%;
margin-left: .5rem;
@ -219,7 +219,7 @@ export default {
}
.created {
color: $grey-400;
color: var(--grey-400);
}
&:last-child {
@ -227,14 +227,14 @@ export default {
}
a {
color: $grey-800;
color: var(--grey-800);
}
}
.nothing {
text-align: center;
padding: 1rem 0;
color: $grey-500;
color: var(--grey-500);
.explainer {
font-size: .75rem;

View File

@ -507,17 +507,19 @@ export default {
.active-cmd {
font-size: 1.25rem;
margin-left: .5rem;
background-color: var(--grey-100);
color: var(--grey-800);
}
}
.results {
text-align: left;
width: 100%;
color: $grey-800;
color: var(--grey-800);
.result {
&-title {
background: $grey-50;
background: var(--grey-50);
padding: .5rem;
display: block;
font-size: .75rem;
@ -528,6 +530,7 @@ export default {
font-size: .9rem;
width: 100%;
background: transparent;
color: var(--grey-800);
text-align: left;
box-shadow: none;
border-radius: 0;
@ -539,12 +542,12 @@ export default {
cursor: pointer;
&:focus, &:hover {
background: $grey-50;
background: var(--grey-50);
box-shadow: none !important;
}
&:active {
background: $grey-100;
background: var(--grey-100);
}
}
}

View File

@ -3,17 +3,13 @@
<div class="field is-grouped">
<p class="control has-icons-left is-expanded">
<textarea
:disabled="taskService.loading || null"
class="input"
:disabled="taskService.loading || undefined"
class="add-task-textarea input"
:placeholder="$t('list.list.addPlaceholder')"
cols="1"
rows="1"
v-focus
v-model="newTaskTitle"
ref="newTaskInput"
:style="{
'minHeight': `${initialTextAreaHeight}px`,
'height': `calc(${textAreaHeight}px - 2px + 1rem)`
}"
@keyup="errorMessage = ''"
@keydown.enter="handleEnter"
/>
@ -23,7 +19,8 @@
</p>
<p class="control">
<x-button
:disabled="newTaskTitle === '' || taskService.loading || null"
class="add-task-button"
:disabled="newTaskTitle === '' || taskService.loading || undefined"
@click="addTask()"
icon="plus"
:loading="taskService.loading"
@ -35,121 +32,171 @@
<p class="help is-danger" v-if="errorMessage !== ''">
{{ errorMessage }}
</p>
<quick-add-magic v-if="errorMessage === ''"/>
<quick-add-magic v-else />
</div>
</template>
<script>
import TaskService from '../../services/task'
<script setup lang="ts">
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 TaskService from '@/services/task'
import QuickAddMagic from '@/components/tasks/partials/quick-add-magic.vue'
const INPUT_BORDER_PX = 2
const LINE_HEIGHT = 1.5 // using getComputedStyles().lineHeight returns an (wrong) absolute pixel value, we need the factor to do calculations with it.
const cleanupTitle = title => {
function cleanupTitle(title: string) {
return title.replace(/^((\* |\+ |- )(\[ \] )?)/g, '')
}
export default {
name: 'add-task',
emits: ['taskAdded'],
data() {
return {
newTaskTitle: '',
taskService: new TaskService(),
errorMessage: '',
textAreaHeight: null,
initialTextAreaHeight: null,
function useAutoHeightTextarea(value: MaybeRef<string>) {
const textarea = ref<HTMLInputElement>()
const minHeight = ref(0)
// adapted from https://github.com/LeaVerou/stretchy/blob/47f5f065c733029acccb755cae793009645809e2/src/stretchy.js#L34
function resize(textareaEl: HTMLInputElement|undefined) {
if (!textareaEl) return
let empty
// the value here is the the attribute value
if (!textareaEl.value && textareaEl.placeholder) {
empty = true
textareaEl.value = textareaEl.placeholder
}
},
components: {
QuickAddMagic,
},
props: {
defaultPosition: {
type: Number,
required: false,
const cs = getComputedStyle(textareaEl)
textareaEl.style.minHeight = ''
textareaEl.style.height = '0'
const offset = textareaEl.offsetHeight - parseFloat(cs.paddingTop) - parseFloat(cs.paddingBottom)
const height = textareaEl.scrollHeight + offset + 'px'
textareaEl.style.height = height
// calculate min-height for the first time
if (!minHeight.value) {
minHeight.value = parseFloat(height)
}
textareaEl.style.minHeight = minHeight.value.toString()
if (empty) {
textareaEl.value = ''
}
}
tryOnMounted(() => {
if (textarea.value) {
// we don't want scrollbars
textarea.value.style.overflowY = 'hidden'
}
})
const { width: windowWidth } = useWindowSize()
debouncedWatch(
windowWidth,
() => resize(textarea.value),
{ debounce: 200 },
)
// It is not possible to get notified of a change of the value attribute of a textarea without workarounds (setTimeout)
// So instead we watch the value that we bound to it.
watch(
() => [textarea.value, unref(value)],
() => resize(textarea.value),
{
immediate: true, // calculate initial size
flush: 'post', // resize after value change is rendered to DOM
},
)
return textarea
}
const props = defineProps({
defaultPosition: {
type: Number,
required: false,
},
watch: {
newTaskTitle(newVal) {
// Calculating the textarea height based on lines of input in it.
// That is more reliable when removing a line from the input.
const numberOfLines = newVal.split(/\r\n|\r|\n/).length
const fontSize = parseFloat(window.getComputedStyle(this.$refs.newTaskInput, null).getPropertyValue('font-size'))
})
this.textAreaHeight = numberOfLines * fontSize * LINE_HEIGHT + INPUT_BORDER_PX
},
},
mounted() {
this.initialTextAreaHeight = this.$refs.newTaskInput.scrollHeight + INPUT_BORDER_PX
},
methods: {
async addTask() {
if (this.newTaskTitle === '') {
this.errorMessage = this.$t('list.create.addTitleRequired')
return
}
this.errorMessage = ''
const emit = defineEmits(['taskAdded'])
if (this.taskService.loading) {
return
}
const newTaskTitle = ref('')
const newTaskInput = useAutoHeightTextarea(newTaskTitle)
const newTasks = this.newTaskTitle.split(/[\r\n]+/).map(async t => {
const title = cleanupTitle(t)
if (title === '') {
return
}
const { t } = useI18n()
const store = useStore()
const task = await this.$store.dispatch('tasks/createNewTask', {
title,
listId: this.$store.state.auth.settings.defaultListId,
position: this.defaultPosition,
})
this.$emit('taskAdded', task)
return task
})
const taskService = shallowReactive(new TaskService())
const errorMessage = ref('')
try {
await Promise.all(newTasks)
this.newTaskTitle = ''
} catch (e) {
if (e.message === 'NO_LIST') {
this.errorMessage = this.$t('list.create.addListRequired')
return
}
throw e
}
},
handleEnter(e) {
// when pressing shift + enter we want to continue as we normally would. Otherwise, we want to create
// the new task(s). The vue event modifier don't allow this, hence this method.
if (e.shiftKey) {
return
}
async function addTask() {
if (newTaskTitle.value === '') {
errorMessage.value = t('list.create.addTitleRequired')
return
}
errorMessage.value = ''
e.preventDefault()
this.addTask()
},
},
if (taskService.loading) {
return
}
const taskTitleBackup = newTaskTitle.value
const newTasks = newTaskTitle.value.split(/[\r\n]+/).map(async uncleanedTitle => {
const title = cleanupTitle(uncleanedTitle)
if (title === '') {
return
}
const task = await store.dispatch('tasks/createNewTask', {
title,
listId: store.state.auth.settings.defaultListId,
position: props.defaultPosition,
})
emit('taskAdded', task)
return task
})
try {
newTaskTitle.value = ''
await Promise.all(newTasks)
} catch (e: any) {
newTaskTitle.value = taskTitleBackup
if (e?.message === 'NO_LIST') {
errorMessage.value = t('list.create.addListRequired')
return
}
throw e
}
}
function handleEnter(e: KeyboardEvent) {
// when pressing shift + enter we want to continue as we normally would. Otherwise, we want to create
// the new task(s). The vue event modifier don't allow this, hence this method.
if (e.shiftKey) {
return
}
e.preventDefault()
addTask()
}
</script>
<style lang="scss" scoped>
.task-add {
margin-bottom: 0;
.button {
height: 2.5rem;
}
}
.input, .textarea {
.add-task-button {
height: 2.5rem;
}
.add-task-textarea {
transition: border-color $transition;
}
.input {
resize: vertical;
resize: none;
}
</style>

View File

@ -78,7 +78,6 @@
<script>
import AsyncEditor from '@/components/input/AsyncEditor'
import ListService from '../../services/list'
import TaskService from '../../services/task'
import TaskModel from '../../models/task'
import priorities from '../../models/constants/priorities'
@ -90,14 +89,10 @@ export default {
name: 'edit-task',
data() {
return {
listId: this.$route.params.id,
listService: new ListService(),
taskService: new TaskService(),
priorities: priorities,
list: {},
editorActive: false,
newTask: new TaskModel(),
isTaskEdit: false,
taskEditTask: TaskModel,
}
@ -167,7 +162,7 @@ ul.assingees {
a {
float: right;
color: $red;
color: var(--danger);
transition: all $transition;
}
}

View File

@ -2,15 +2,7 @@
<div class="gantt-chart">
<div class="filter-container">
<div class="items">
<x-button
@click.prevent.stop="showTaskFilter = !showTaskFilter"
type="secondary"
icon="filter"
>
{{ $t('filters.title') }}
</x-button>
<filter-popup
:visible="showTaskFilter"
v-model="params"
@update:modelValue="loadTasks()"
/>
@ -191,6 +183,8 @@ import {mapState} from 'vuex'
import Rights from '../../models/constants/rights.json'
import FilterPopup from '@/components/list/partials/filter-popup.vue'
import {colorIsDark} from '@/helpers/color/colorIsDark'
export default {
name: 'GanttChart',
components: {
@ -209,10 +203,10 @@ export default {
default: false,
},
dateFrom: {
default: new Date(new Date().setDate(new Date().getDate() - 15)),
default: () => new Date(new Date().setDate(new Date().getDate() - 15)),
},
dateTo: {
default: new Date(new Date().setDate(new Date().getDate() + 30)),
default: () => new Date(new Date().setDate(new Date().getDate() + 30)),
},
// The width of a day in pixels, used to calculate all sorts of things.
dayWidth: {
@ -237,7 +231,6 @@ export default {
newTaskFieldActive: false,
priorities: priorities,
taskCollectionService: new TaskCollectionService(),
showTaskFilter: false,
params: {
sort_by: ['done', 'id'],
@ -261,6 +254,7 @@ export default {
canWrite: (state) => state.currentList.maxRight > Rights.READ,
}),
methods: {
colorIsDark,
buildTheGanttChart() {
this.setDates()
this.prepareGanttDays()
@ -445,12 +439,12 @@ export default {
</script>
<style lang="scss" scoped>
$gantt-border: 1px solid $grey-200;
$gantt-vertical-border-color: $grey-100;
$gantt-border: 1px solid var(--grey-200);
$gantt-vertical-border-color: var(--grey-100);
.gantt-chart {
overflow-x: auto;
border-top: 1px solid $grey-200;
border-top: 1px solid var(--grey-200);
.dates {
display: flex;
@ -477,8 +471,8 @@ $gantt-vertical-border-color: $grey-100;
font-weight: normal;
&.today {
background: $primary;
color: $white;
background: var(--primary);
color: var(--white);
border-radius: 5px 5px 0 0;
font-weight: bold;
}
@ -500,7 +494,6 @@ $gantt-vertical-border-color: $grey-100;
.tasks {
max-width: unset !important;
margin: 0;
border-top: $gantt-border;
.row {
@ -508,7 +501,7 @@ $gantt-vertical-border-color: $grey-100;
.task {
display: inline-block;
border: 2px solid $primary;
border: 2px solid var(--primary);
font-size: 0.85rem;
margin: 0.5rem;
border-radius: 6px;
@ -521,30 +514,30 @@ $gantt-vertical-border-color: $grey-100;
user-select: none; // Non-prefixed version
&.is-current-edit {
border-color: $orange !important;
border-color: var(--warning) !important;
}
&.has-light-text {
color: $light;
color: var(--light);
&.done span:after {
border-top: 1px solid $light;
border-top: 1px solid var(--light);
}
.edit-toggle {
color: $light;
color: var(--light);
}
}
&.has-dark-text {
color: $text;
color: var(--text);
&.done span:after {
border-top: 1px solid $dark;
border-top: 1px solid var(--dark);
}
.edit-toggle {
color: $text;
color: var(--text);
}
}
@ -597,8 +590,8 @@ $gantt-vertical-border-color: $grey-100;
}
&.nodate {
border: 2px dashed $grey-300;
background: $grey-100;
border: 2px dashed var(--grey-300);
background: var(--grey-100);
}
&:active {

View File

@ -44,7 +44,6 @@ export default {
params = null,
forceLoading = false,
) {
// Because this function is triggered every time on topNavigation, we're putting a condition here to only load it when we actually want to show tasks
// FIXME: This is a bit hacky -> Cleanup.
if (

View File

@ -83,7 +83,7 @@
@click="$refs.files.click()"
class="mb-4"
icon="cloud-upload-alt"
type="secondary"
variant="secondary"
:shadow="false"
>
{{ $t('task.attachment.upload') }}
@ -267,17 +267,17 @@ export default {
padding: .5rem;
&:hover {
background-color: $grey-200;
background-color: var(--grey-200);
}
.filename {
font-weight: bold;
margin-bottom: .25rem;
color: $text;
color: var(--text);
}
.info {
color: $grey-500;
color: var(--grey-500);
font-size: .9rem;
p {
@ -339,17 +339,17 @@ export default {
width: 100%;
font-size: 5rem;
height: auto;
text-shadow: $shadow-md;
text-shadow: var(--shadow-md);
animation: bounce 2s infinite;
}
.hint {
margin: .5rem auto 2rem;
border-radius: 2px;
box-shadow: $shadow-md;
background: $primary;
box-shadow: var(--shadow-md);
background: var(--primary);
padding: 1rem;
color: $white;
color: var(--white);
width: 100%;
max-width: 300px;
}

View File

@ -39,7 +39,7 @@ export default {
<style scoped lang="scss">
.checklist-summary {
color: $grey-500;
color: var(--grey-500);
display: inline-flex;
align-items: center;
@ -49,10 +49,10 @@ export default {
margin-right: .25rem;
circle {
stroke: $grey-400;
stroke: var(--grey-400);
&:last-child {
stroke: $primary;
stroke: var(--primary);
}
}
}

View File

@ -276,7 +276,7 @@ export default {
this.commentEdit.taskId = this.taskId
try {
const comment = this.taskCommentService.update(this.commentEdit)
const comment = await this.taskCommentService.update(this.commentEdit)
for (const c in this.comments) {
if (this.comments[c].id === this.commentEdit.id) {
this.comments[c] = comment

View File

@ -8,21 +8,21 @@
<x-button
@click.prevent.stop="() => deferDays(1)"
:shadow="false"
type="secondary"
variant="secondary"
>
{{ $t('task.deferDueDate.1day') }}
</x-button>
<x-button
@click.prevent.stop="() => deferDays(3)"
:shadow="false"
type="secondary"
variant="secondary"
>
{{ $t('task.deferDueDate.3days') }}
</x-button>
<x-button
@click.prevent.stop="() => deferDays(7)"
:shadow="false"
type="secondary"
variant="secondary"
>
{{ $t('task.deferDueDate.1week') }}
</x-button>
@ -141,14 +141,14 @@ $defer-task-max-width: 350px + 100px;
width: 100%;
max-width: $defer-task-max-width;
border-radius: $radius;
border: 1px solid $grey-200;
border: 1px solid var(--grey-200);
padding: 1rem;
margin: 1rem;
background: $white;
color: $text;
background: var(--white);
color: var(--text);
cursor: default;
z-index: 10;
box-shadow: $shadow-lg;
box-shadow: var(--shadow-lg);
@media screen and (max-width: ($defer-task-max-width)) {
left: .5rem;

View File

@ -127,7 +127,7 @@ export default {
}
:deep(.user img) {
border: 2px solid $white;
border: 2px solid var(--white);
margin-right: 0;
}
@ -135,8 +135,8 @@ export default {
position: absolute;
top: 4px;
left: 2px;
color: $red;
background: $white;
color: var(--danger);
background: var(--white);
padding: 0 4px;
display: block;
border-radius: 100%;

View File

@ -7,7 +7,7 @@
:class="{'disabled': !canWrite}"
@blur="save($event.target.textContent)"
@keydown.enter.prevent.stop="$event.target.blur()"
:contenteditable="canWrite ? 'true' : 'false'"
:contenteditable="canWrite ? true : undefined"
:spellcheck="false"
>
{{ task.title.trim() }}

View File

@ -1,5 +1,6 @@
<template>
<div
class="task loader-container draggable"
:class="{
'is-loading': loadingInternal || loading,
'draggable': !(loadingInternal || loading),
@ -9,7 +10,6 @@
@click.ctrl="() => toggleTaskDone(task)"
@click.exact="() => $router.push({ name: 'task.kanban.detail', params: { id: task.id } })"
@click.meta="() => toggleTaskDone(task)"
class="task loader-container draggable"
>
<span class="task-id">
<Done class="kanban-card__done" :is-done="task.done" variant="small" />
@ -73,6 +73,8 @@ import Done from '@/components/misc/Done.vue'
import Labels from '../../../components/tasks/partials/labels'
import ChecklistSummary from './checklist-summary'
import {colorIsDark} from '@/helpers/color/colorIsDark'
export default {
name: 'kanban-card',
components: {
@ -98,6 +100,7 @@ export default {
},
},
methods: {
colorIsDark,
async toggleTaskDone(task) {
this.loadingInternal = true
try {
@ -117,13 +120,13 @@ export default {
</script>
<style lang="scss" scoped>
$task-background: $white;
$task-background: var(--white);
.task {
-webkit-touch-callout: none; // iOS Safari
user-select: none;
cursor: pointer;
box-shadow: $shadow-xs;
box-shadow: var(--shadow-xs);
display: block;
border: 3px solid transparent;
@ -163,7 +166,7 @@ $task-background: $white;
}
&.overdue {
color: $red;
color: var(--danger);
}
}
@ -219,7 +222,7 @@ $task-background: $white;
.footer .icon,
.due-date,
.priority-label {
background: $grey-100;
background: var(--grey-100);
border-radius: $radius;
padding: 0 .5rem;
}
@ -229,7 +232,7 @@ $task-background: $white;
}
.task-id {
color: $grey-500;
color: var(--grey-500);
font-size: .8rem;
margin-bottom: .25rem;
display: flex;
@ -244,21 +247,21 @@ $task-background: $white;
}
&.has-light-text {
color: $white;
color: var(--white);
.task-id {
color: $grey-200;
color: var(--grey-200);
}
.footer .icon,
.due-date,
.priority-label {
background: $grey-800;
background: var(--grey-800);
}
.footer {
.icon svg {
fill: $white;
fill: var(--white);
}
}
}

View File

@ -16,60 +16,54 @@
</multiselect>
</template>
<script>
import ListModel from '../../../models/list'
<script lang="ts" setup>
import {reactive, ref, watchEffect} from 'vue'
import {useStore} from 'vuex'
import {useI18n} from 'vue-i18n'
import ListModel from '@/models/list'
import Multiselect from '@/components/input/multiselect.vue'
export default {
name: 'listSearch',
data() {
return {
list: new ListModel(),
foundLists: [],
}
},
props: {
modelValue: {
required: false,
},
},
emits: ['update:modelValue', 'selected'],
components: {
Multiselect,
},
watch: {
modelValue: {
handler(value) {
this.list = value
},
immeditate: true,
deep: true,
},
},
methods: {
findLists(query) {
this.foundLists = this.$store.getters['lists/searchList'](query)
},
const store = useStore()
const {t} = useI18n()
select(list) {
this.list = list
this.$emit('selected', list)
this.$emit('update:modelValue', list)
},
namespace(namespaceId) {
const namespace = this.$store.getters['namespaces/getNamespaceById'](namespaceId)
if (namespace !== null) {
return namespace.title
}
return this.$t('list.shared')
const list = reactive(new ListModel())
const props = defineProps({
modelValue: {
validator(value) {
return value instanceof ListModel
},
required: false,
},
})
const emit = defineEmits(['update:modelValue'])
watchEffect(() => {
Object.assign(list, props.modelValue)
})
const foundLists = ref([])
function findLists(query: string) {
if (query === '') {
select(null)
}
foundLists.value = store.getters['lists/searchList'](query)
}
function select(l: ListModel | null) {
Object.assign(list, l)
emit('update:modelValue', list)
}
function namespace(namespaceId: number) {
const namespace = store.getters['namespaces/getNamespaceById'](namespaceId)
return namespace !== null
? namespace.title
: t('list.shared')
}
</script>
<style lang="scss" scoped>
.list-namespace-title {
color: $grey-500;
color: var(--grey-500);
}
</style>

View File

@ -54,7 +54,7 @@ export default {
}
span.high-priority {
color: $red;
color: var(--danger);
width: auto !important; // To override the width set in tasks
.icon {
@ -64,7 +64,7 @@ span.high-priority {
}
&.not-so-high {
color: $orange;
color: var(--warning);
}
}
</style>

View File

@ -65,6 +65,21 @@
<li>17th ({{ $t('task.quickAddMagic.dateNth', {day: '17'}) }})</li>
</ul>
<p>{{ $t('task.quickAddMagic.dateTime', {time: 'at 17:00', timePM: '5pm'}) }}</p>
<h3>{{ $t('task.quickAddMagic.repeats') }}</h3>
<p>{{ $t('task.quickAddMagic.repeatsDescription', {suffix: 'every {amount} {type}'}) }}</p>
<p>{{ $t('misc.forExample') }}</p>
<ul>
<!-- Not localized because these only work in english -->
<li>Every day</li>
<li>Every 3 days</li>
<li>Every week</li>
<li>Every 2 weeks</li>
<li>Every month</li>
<li>Every 6 months</li>
<li>Every year</li>
<li>Every 2 years</li>
</ul>
</card>
</modal>
</div>

View File

@ -6,7 +6,7 @@
class="is-pulled-right add-task-relation-button"
:class="{'is-active': showNewRelationForm}"
v-tooltip="$t('task.relation.add')"
type="secondary"
variant="secondary"
icon="plus"
:shadow="false"
/>
@ -310,7 +310,7 @@ export default {
}
.different-list {
color: $grey-500;
color: var(--grey-500);
width: auto;
}
@ -319,6 +319,10 @@ export default {
margin: 0;
}
.tasks {
padding: .5rem;
}
.task {
display: flex;
flex-wrap: wrap;
@ -328,21 +332,21 @@ export default {
border-radius: $radius;
&:hover {
background-color: $grey-200;
background-color: var(--grey-200);
}
a {
color: $text;
color: var(--text);
transition: color ease $transition-duration;
&:hover {
color: $grey-900;
color: var(--grey-900);
}
}
.remove {
text-align: center;
color: $red;
color: var(--danger);
opacity: 0;
transition: opacity $transition;
}

View File

@ -112,7 +112,7 @@ export default {
align-items: center;
&.overdue :deep(.datepicker a.show) {
color: $red;
color: var(--danger);
}
&:last-child {
@ -120,7 +120,7 @@ export default {
}
a.remove {
color: $red;
color: var(--danger);
padding-left: .5rem;
}
}

View File

@ -1,9 +1,9 @@
<template>
<div class="control repeat-after-input">
<div class="buttons has-addons is-centered mt-2">
<x-button type="secondary" class="is-small" @click="() => setRepeatAfter(1, 'days')">{{ $t('task.repeat.everyDay') }}</x-button>
<x-button type="secondary" class="is-small" @click="() => setRepeatAfter(1, 'weeks')">{{ $t('task.repeat.everyWeek') }}</x-button>
<x-button type="secondary" class="is-small" @click="() => setRepeatAfter(1, 'months')">{{ $t('task.repeat.everyMonth') }}</x-button>
<x-button variant="secondary" class="is-small" @click="() => setRepeatAfter(1, 'days')">{{ $t('task.repeat.everyDay') }}</x-button>
<x-button variant="secondary" class="is-small" @click="() => setRepeatAfter(1, 'weeks')">{{ $t('task.repeat.everyWeek') }}</x-button>
<x-button variant="secondary" class="is-small" @click="() => setRepeatAfter(1, 'months')">{{ $t('task.repeat.everyMonth') }}</x-button>
</div>
<div class="is-flex is-align-items-center mb-2">
<label for="repeatMode" class="is-fullwidth">

View File

@ -227,7 +227,7 @@ export default {
border: 2px solid transparent;
&:hover {
background-color: $grey-100;
background-color: var(--grey-100);
}
.tasktext,
@ -239,13 +239,13 @@ export default {
flex: 1 0 50%;
.overdue {
color: $red;
color: var(--danger);
}
}
.task-list {
width: auto;
color: $grey-400;
color: var(--grey-400);
font-size: .9rem;
white-space: nowrap;
}
@ -273,11 +273,11 @@ export default {
}
a {
color: $text;
color: var(--text);
transition: color ease $transition-duration;
&:hover {
color: $grey-900;
color: var(--grey-900);
}
}
@ -288,12 +288,12 @@ export default {
transition: opacity $transition, color $transition;
&:hover {
color: $orange;
color: var(--warning);
}
&.is-favorite {
opacity: 1;
color: $orange;
color: var(--warning);
}
}
@ -324,16 +324,16 @@ export default {
.tasktext.done {
text-decoration: line-through;
color: $grey-500;
color: var(--grey-500);
}
span.parent-tasks {
color: $grey-500;
color: var(--grey-500);
width: auto;
}
.remove {
color: $red;
color: var(--danger);
}
input[type="checkbox"] {
@ -351,8 +351,8 @@ export default {
left: calc(50% - 1rem);
width: 2rem;
height: 2rem;
border-left-color: $grey-300;
border-bottom-color: $grey-300;
border-left-color: var(--grey-300);
border-bottom-color: var(--grey-300);
}
}
</style>

View File

@ -0,0 +1,16 @@
import {ref, watchEffect} from 'vue'
import {tryOnBeforeUnmount} from '@vueuse/core'
export function useBodyClass(className: string, defaultValue = false) {
const isActive = ref(defaultValue)
watchEffect(() => {
isActive.value
? document.body.classList.add(className)
: document.body.classList.remove(className)
})
tryOnBeforeUnmount(() => isActive.value && document.body.classList.remove(className))
return isActive
}

View File

@ -0,0 +1,48 @@
import {computed, watch, readonly} from 'vue'
import {useStorage, createSharedComposable, ColorSchema, usePreferredColorScheme, tryOnMounted} from '@vueuse/core'
const STORAGE_KEY = 'color-scheme'
const DEFAULT_COLOR_SCHEME_SETTING: ColorSchema = 'light'
const CLASS_DARK = 'dark'
const CLASS_LIGHT = 'light'
// This is built upon the vueuse useDark
// Main differences:
// - usePreferredColorScheme
// - doesn't allow setting via the `isDark` ref.
// - instead the store is exposed
// - value is synced via `createSharedComposable`
// https://github.com/vueuse/vueuse/blob/main/packages/core/useDark/index.ts
export const useColorScheme = createSharedComposable(() => {
const store = useStorage<ColorSchema>(STORAGE_KEY, DEFAULT_COLOR_SCHEME_SETTING)
const preferredColorScheme = usePreferredColorScheme()
const isDark = computed<boolean>(() => {
if (store.value !== 'auto') {
return store.value === 'dark'
}
const autoColorScheme = preferredColorScheme.value === 'no-preference'
? DEFAULT_COLOR_SCHEME_SETTING
: preferredColorScheme.value
return autoColorScheme === 'dark'
})
function onChanged(v: boolean) {
const el = window?.document.querySelector('html')
el?.classList.toggle(CLASS_DARK, v)
el?.classList.toggle(CLASS_LIGHT, !v)
}
watch(isDark, onChanged, { flush: 'post' })
tryOnMounted(() => onChanged(isDark.value))
return {
store,
isDark: readonly(isDark),
}
})

View File

@ -0,0 +1,31 @@
import {describe, it, expect} from 'vitest'
import {hourToSalutation} from './useDateTimeSalutation'
const dateWithHour = (hours: number): Date => {
const date = new Date()
date.setHours(hours)
return date
}
describe('Salutation', () => {
it('shows the right salutation in the night', () => {
const salutation = hourToSalutation(dateWithHour(4))
expect(salutation).toBe('home.welcomeNight')
})
it('shows the right salutation in the morning', () => {
const salutation = hourToSalutation(dateWithHour(8))
expect(salutation).toBe('home.welcomeMorning')
})
it('shows the right salutation in the day', () => {
const salutation = hourToSalutation(dateWithHour(13))
expect(salutation).toBe('home.welcomeDay')
})
it('shows the right salutation in the night', () => {
const salutation = hourToSalutation(dateWithHour(20))
expect(salutation).toBe('home.welcomeEvening')
})
it('shows the right salutation in the night again', () => {
const salutation = hourToSalutation(dateWithHour(23))
expect(salutation).toBe('home.welcomeNight')
})
})

View File

@ -0,0 +1,31 @@
import {computed} from 'vue'
import {useNow} from '@vueuse/core'
const TRANSLATION_KEY_PREFIX = 'home.welcome'
export function hourToSalutation(now: Date) {
const hours = now.getHours()
if (hours < 5) {
return `${TRANSLATION_KEY_PREFIX}Night`
}
if (hours < 11) {
return `${TRANSLATION_KEY_PREFIX}Morning`
}
if (hours < 18) {
return `${TRANSLATION_KEY_PREFIX}Day`
}
if (hours < 23) {
return `${TRANSLATION_KEY_PREFIX}Evening`
}
return `${TRANSLATION_KEY_PREFIX}Night`
}
export function useDateTimeSalutation() {
const now = useNow()
return computed(() => hourToSalutation(now.value))
}

View File

@ -0,0 +1,14 @@
import {ref} from 'vue'
import {useOnline as useNetworkOnline, ConfigurableWindow} from '@vueuse/core'
export function useOnline(options?: ConfigurableWindow) {
const fakeOnlineState = !!import.meta.env.VITE_IS_ONLINE
if (fakeOnlineState) {
console.log('Setting fake online state', fakeOnlineState)
}
return fakeOnlineState
? ref(true)
: useNetworkOnline(options)
}

23
src/directives/cypress.ts Normal file
View File

@ -0,0 +1,23 @@
import {Directive} from 'vue'
declare global {
interface Window {
Cypress: object;
}
}
const cypressDirective: Directive = {
mounted(el, {value}) {
if (
(window.Cypress || import.meta.env.DEV) &&
value
) {
el.setAttribute('data-cy', value)
}
},
beforeUnmount(el) {
el.removeAttribute('data-cy')
},
}
export default cypressDirective

View File

@ -5,7 +5,7 @@ export default {
// auto focusing elements on mobile can be annoying since in these cases the
// keyboard always pops up and takes half of the available space on the screen.
// The threshhold is the same as the breakpoints in css.
if (window.innerWidth > 769 || (typeof modifiers.always !== 'undefined' && modifiers.always)) {
if (window.innerWidth > 769 || modifiers?.always) {
el.focus()
}
},

View File

@ -1,83 +0,0 @@
const calculateTop = (coords, tooltip) => {
// Bottom tooltip use the exact inverse calculation compared to the default.
if (tooltip.classList.contains('bottom')) {
return coords.top + tooltip.offsetHeight + 5
}
// The top position of the tooltip is the coordinates of the bound element - the height of the tooltip -
// 5px spacing for the arrow (which is exactly 5px high)
return coords.top - tooltip.offsetHeight - 5
}
const calculateArrowTop = (top, tooltip) => {
if (tooltip.classList.contains('bottom')) {
return `${top - 5}px` // 5px arrow height
}
return `${top + tooltip.offsetHeight}px`
}
// This global object holds all created tooltip elements (and their arrows) using the element they were created for as
// key. This allows us to find the tooltip elements if the element the tooltip was created for is unbound so that
// we can remove the tooltip element.
const createdTooltips = {}
export default {
mounted(el, {value, modifiers}) {
// First, we create the tooltip and arrow elements
const tooltip = document.createElement('div')
tooltip.style.position = 'fixed'
tooltip.innerText = value
tooltip.classList.add('tooltip')
const arrow = document.createElement('div')
arrow.classList.add('tooltip-arrow')
arrow.style.position = 'fixed'
if (typeof modifiers.bottom !== 'undefined') {
tooltip.classList.add('bottom')
arrow.classList.add('bottom')
}
// We don't append the element until hovering over it because that's the most reliable way to determine
// where the parent elemtent is located at the time the user hovers over it.
el.addEventListener('mouseover', () => {
// Appending the element right away because we can only calculate the height of the element if it is
// already in the DOM.
document.body.appendChild(tooltip)
document.body.appendChild(arrow)
const coords = el.getBoundingClientRect()
const top = calculateTop(coords, tooltip)
// The left position of the tooltip is calculated so that the middle point of the tooltip
// (where the arrow will be) is the middle of the bound element
const left = coords.left - (tooltip.offsetWidth / 2) + (el.offsetWidth / 2)
// Now setting all the values
tooltip.style.top = `${top}px`
tooltip.style.left = `${coords.left}px`
tooltip.style.left = `${left}px`
arrow.style.left = `${left + (tooltip.offsetWidth / 2) - (arrow.offsetWidth / 2)}px`
arrow.style.top = calculateArrowTop(top, tooltip)
// And finally make it visible to the user. This will also trigger a nice fade-in animation through
// css transitions
tooltip.classList.add('visible')
arrow.classList.add('visible')
})
el.addEventListener('mouseout', () => {
tooltip.classList.remove('visible')
arrow.classList.remove('visible')
})
createdTooltips[el] = {
tooltip: tooltip,
arrow: arrow,
}
},
unmounted(el) {
if (typeof createdTooltips[el] !== 'undefined') {
createdTooltips[el].tooltip.remove()
createdTooltips[el].arrow.remove()
}
},
}

View File

@ -1,3 +1,5 @@
import {it, expect} from 'vitest'
import {calculateItemPosition} from './calculateItemPosition'
it('should calculate the task position', () => {

View File

@ -1,3 +1,5 @@
import {describe, it, expect} from 'vitest'
import {findCheckboxesInText, getChecklistStatistics} from './checklistFromText'
describe('Find checklists in text', () => {
@ -21,6 +23,7 @@ Here's some text in between
expect(checkboxes[0]).toBe(0)
expect(checkboxes[1]).toBe(18)
expect(checkboxes[2]).toBe(69)
expect(checkboxes[3]).toBe(90)
})
it('should find one checkbox with *', () => {
const text: string = '* [ ] Lorem Ipsum'

View File

@ -40,7 +40,7 @@ export const findCheckboxesInText = (text: string): number[] => {
return [
...checkboxes.checked,
...checkboxes.unchecked,
].sort()
].sort((a, b) => a < b ? -1 : 1)
}
export const getChecklistStatistics = (text: string): CheckboxStatistics => {

View File

@ -1,3 +1,5 @@
import {test, expect} from 'vitest'
import {colorFromHex} from './colorFromHex'
test('hex', () => {

View File

@ -1,3 +1,5 @@
import {test, expect} from 'vitest'
import {colorIsDark} from './colorIsDark'
test('dark color', () => {

View File

@ -1,3 +1,5 @@
import {describe, it, expect} from 'vitest'
import {filterLabelsByQuery} from './labels'
import {createNewIndexer} from '../indexes'

View File

@ -1,11 +0,0 @@
export const playSoundWhenDoneKey = 'playSoundWhenTaskDone'
export const playPop = () => {
const enabled = localStorage.getItem(playSoundWhenDoneKey) === 'true' || localStorage.getItem(playSoundWhenDoneKey) === null
if(!enabled) {
return
}
const popSound = new Audio('/audio/pop.mp3')
popSound.play()
}

13
src/helpers/playPop.ts Normal file
View File

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

View File

@ -1,4 +1,5 @@
import {createRandomID} from '@/helpers/randomId'
import {parseURL} from 'ufo'
interface Provider {
name: string
@ -7,7 +8,15 @@ interface Provider {
clientId: string
}
export const redirectToProvider = (provider: Provider, redirectUrl: string) => {
export const redirectToProvider = (provider: Provider, redirectUrl: string = '') => {
// We're not using the redirect url provided by the server to allow redirects when using the electron app.
// The implications are not quite clear yet hence the logic to pass in another redirect url still exists.
if (redirectUrl === '') {
const {host, protocol} = parseURL(window.location.href)
redirectUrl = `${protocol}//${host}/auth/openid/`
}
const state = createRandomID(24)
localStorage.setItem('state', state)

View File

@ -1,3 +1,5 @@
import {test, expect} from 'vitest'
import {calculateDayInterval} from './calculateDayInterval'
const days = {

View File

@ -1,3 +1,5 @@
import {test, expect} from 'vitest'
import {calculateNearestHours} from './calculateNearestHours'
test('5:00', () => {

View File

@ -1,3 +1,5 @@
import {test, expect} from 'vitest'
import {createDateFromString} from './createDateFromString'
test('YYYY-MM-DD HH:MM', () => {

View File

@ -135,18 +135,18 @@ export const getDateFromText = (text: string, now: Date = new Date()) => {
if (result === null) {
// 3. Try parsing the date as "27/01" or "01/27"
const monthNumericRegex:RegExp = /([0-9][0-9]?\/[0-9][0-9]?)/ig
const monthNumericRegex: RegExp = /([0-9][0-9]?\/[0-9][0-9]?)/ig
results = monthNumericRegex.exec(text)
// Put the year before or after the date, depending on what works
result = results === null ? null : `${now.getFullYear()}/${results[0]}`
if(result === null) {
if (result === null) {
return {
foundText,
date: null,
}
}
foundText = results === null ? '' : results[0]
if (result === null || isNaN(new Date(result).getTime())) {
result = results === null ? null : `${results[0]}/${now.getFullYear()}`
@ -280,7 +280,7 @@ const getDateFromWeekday = (text: string): dateFoundResult => {
if (foundText.endsWith(' ')) {
foundText = foundText.substr(0, foundText.length - 1)
}
return {
foundText: foundText,
date: date,
@ -297,19 +297,20 @@ const getDayFromText = (text: string) => {
}
}
const date = new Date()
const now = new Date()
const date = new Date(now)
const day = parseInt(results[0])
date.setDate(day)
// If the parsed day is the 31st but the next month only has 30 days, setting the day to 31 will "overflow" the
// date to the next month, but the first.
// This would look like a very weired bug. Now, to prevent that, we check if the day is the same as parsed after
// setting it for the first time and set it again if it isn't - that would mean the month overflowed.
if(day === 31 && date.getDate() !== day) {
if (day === 31 && date.getDate() !== day) {
date.setDate(day)
}
if (date < new Date()) {
if (date < now) {
date.setMonth(date.getMonth() + 1)
}

Some files were not shown because too many files have changed in this diff Show More