diff --git a/.github/workflows/pr-docker.yml b/.github/workflows/pr-docker.yml index d1e78b9ad..c0cf48239 100644 --- a/.github/workflows/pr-docker.yml +++ b/.github/workflows/pr-docker.yml @@ -39,7 +39,7 @@ jobs: version: latest - name: Docker meta id: meta - uses: docker/metadata-action@318604b99e75e41977312d83839a89be02ca4893 # v5 + uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5 with: images: ghcr.io/go-vikunja/vikunja tags: | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2856b4e86..850cc911d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -30,7 +30,7 @@ jobs: - name: Docker meta version if: ${{ github.ref_type == 'tag' }} id: meta - uses: docker/metadata-action@318604b99e75e41977312d83839a89be02ca4893 # v5 + uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5 with: images: | vikunja/vikunja diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3578370ef..fa9766914 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -362,10 +362,10 @@ jobs: ports: - 5556:5556 container: - image: mcr.microsoft.com/playwright:v1.57.0-jammy + image: mcr.microsoft.com/playwright:v1.57.0-jammy@sha256:6aca677c27a967caf7673d108ac67ffaf8fed134f27e17b27a05464ca0ace831 options: --user 1001 steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 - name: Download Vikunja Binary uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6 with: diff --git a/desktop/package.json b/desktop/package.json index 6f421739a..e1be59153 100644 --- a/desktop/package.json +++ b/desktop/package.json @@ -5,7 +5,7 @@ "main": "main.js", "repository": "https://code.vikunja.io/desktop", "license": "GPL-3.0-or-later", - "packageManager": "pnpm@10.22.0", + "packageManager": "pnpm@10.23.0", "author": { "email": "maintainers@vikunja.io", "name": "Vikunja Team" diff --git a/frontend/package.json b/frontend/package.json index d1ace1125..91ca71abc 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -13,7 +13,7 @@ }, "homepage": "https://vikunja.io/", "funding": "https://opencollective.com/vikunja", - "packageManager": "pnpm@10.22.0", + "packageManager": "pnpm@10.23.0", "keywords": [ "todo", "productivity", @@ -93,7 +93,7 @@ "is-touch-device": "1.0.1", "klona": "2.0.6", "lowlight": "3.3.0", - "marked": "16.4.2", + "marked": "17.0.1", "pinia": "3.0.4", "register-service-worker": "1.7.2", "sortablejs": "1.15.6", @@ -102,10 +102,10 @@ "vue": "3.5.24", "vue-advanced-cropper": "2.8.9", "vue-flatpickr-component": "11.0.5", - "vue-i18n": "11.1.12", + "vue-i18n": "11.2.1", "vue-router": "4.6.3", "vuemoji-picker": "0.3.2", - "workbox-precaching": "7.3.0", + "workbox-precaching": "7.4.0", "zhyswan-vuedraggable": "4.1.3" }, "devDependencies": { diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index d7341fc3e..47405dd35 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -36,7 +36,7 @@ importers: version: 3.1.1(patch_hash=145ab3233cbcd3bc934b4961cd8710e2b15e4ae5dd20862a8d1d6621d7f9d4a8) '@intlify/unplugin-vue-i18n': specifier: 11.0.1 - version: 11.0.1(@vue/compiler-dom@3.5.24)(eslint@9.39.1(jiti@2.4.2))(rollup@4.53.3)(typescript@5.9.3)(vue-i18n@11.1.12(vue@3.5.24(typescript@5.9.3)))(vue@3.5.24(typescript@5.9.3)) + version: 11.0.1(@vue/compiler-dom@3.5.24)(eslint@9.39.1(jiti@2.4.2))(rollup@4.53.3)(typescript@5.9.3)(vue-i18n@11.2.1(vue@3.5.24(typescript@5.9.3)))(vue@3.5.24(typescript@5.9.3)) '@kyvg/vue3-notification': specifier: 3.4.2 version: 3.4.2(vue@3.5.24(typescript@5.9.3)) @@ -134,8 +134,8 @@ importers: specifier: 3.3.0 version: 3.3.0 marked: - specifier: 16.4.2 - version: 16.4.2 + specifier: 17.0.1 + version: 17.0.1 pinia: specifier: 3.0.4 version: 3.0.4(typescript@5.9.3)(vue@3.5.24(typescript@5.9.3)) @@ -161,8 +161,8 @@ importers: specifier: 11.0.5 version: 11.0.5(vue@3.5.24(typescript@5.9.3)) vue-i18n: - specifier: 11.1.12 - version: 11.1.12(vue@3.5.24(typescript@5.9.3)) + specifier: 11.2.1 + version: 11.2.1(vue@3.5.24(typescript@5.9.3)) vue-router: specifier: 4.6.3 version: 4.6.3(vue@3.5.24(typescript@5.9.3)) @@ -170,8 +170,8 @@ importers: specifier: 0.3.2 version: 0.3.2(vue@3.5.24(typescript@5.9.3)) workbox-precaching: - specifier: 7.3.0 - version: 7.3.0 + specifier: 7.4.0 + version: 7.4.0 zhyswan-vuedraggable: specifier: 4.1.3 version: 4.1.3(vue@3.5.24(typescript@5.9.3)) @@ -1722,18 +1722,26 @@ packages: vue-i18n: optional: true - '@intlify/core-base@11.1.12': - resolution: {integrity: sha512-whh0trqRsSqVLNEUCwU59pyJZYpU8AmSWl8M3Jz2Mv5ESPP6kFh4juas2NpZ1iCvy7GlNRffUD1xr84gceimjg==} + '@intlify/core-base@11.2.1': + resolution: {integrity: sha512-2V1A4yaN9ElAnQ6ih3HHEc+jZ+sHV6BlQHjCsnIVlOotL5NCUgJElIxgUFiJs6zV4puoAq3hHuQIfWNp+J+8yQ==} engines: {node: '>= 16'} '@intlify/message-compiler@11.1.12': resolution: {integrity: sha512-Fv9iQSJoJaXl4ZGkOCN1LDM3trzze0AS2zRz2EHLiwenwL6t0Ki9KySYlyr27yVOj5aVz0e55JePO+kELIvfdQ==} engines: {node: '>= 16'} + '@intlify/message-compiler@11.2.1': + resolution: {integrity: sha512-J2454D3Agg3Kvgaj14gxTleJU8/H06Sisz7C2BwiHF0/i5Soyfb5ySpwn8GCL6yscDbOGj6xM+lUe6gO6BFQyg==} + engines: {node: '>= 16'} + '@intlify/shared@11.1.12': resolution: {integrity: sha512-Om86EjuQtA69hdNj3GQec9ZC0L0vPSAnXzB3gP/gyJ7+mA7t06d9aOAiqMZ+xEOsumGP4eEBlfl8zF2LOTzf2A==} engines: {node: '>= 16'} + '@intlify/shared@11.2.1': + resolution: {integrity: sha512-O67LZM4dbfr70WCsZLW+g+pIXdgQ66laLVd/FicW7iYgP/RuH0X1FDGSh+Hr9Gou/8TeldUE6KmTGdLwX2ufIA==} + engines: {node: '>= 16'} + '@intlify/unplugin-vue-i18n@11.0.1': resolution: {integrity: sha512-nH5NJdNjy/lO6Ne8LDtZzv4SbpVsMhPE+LbvBDmMeIeJDiino8sOJN2QB3MXzTliYTnqe3aB9Fw5+LJ/XVaXCg==} engines: {node: '>= 20'} @@ -4836,8 +4844,8 @@ packages: resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==} hasBin: true - marked@16.4.2: - resolution: {integrity: sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA==} + marked@17.0.1: + resolution: {integrity: sha512-boeBdiS0ghpWcSwoNm/jJBwdpFaMnZWRzjA6SkUMYb40SVaN1x7mmfGKp0jvexGcx+7y2La5zRZsYFZI6Qpypg==} engines: {node: '>= 20'} hasBin: true @@ -6838,8 +6846,8 @@ packages: peerDependencies: vue: ^3.2.0 - vue-i18n@11.1.12: - resolution: {integrity: sha512-BnstPj3KLHLrsqbVU2UOrPmr0+Mv11bsUZG0PyCOzsawCivk8W00GMXHeVUWIDOgNaScCuZah47CZFE+Wnl8mw==} + vue-i18n@11.2.1: + resolution: {integrity: sha512-cc3Wx4eJZac9WMS8mxhfYiCipm9PBQ2Dz15piWYm7DwNcCehaKRgpolEdiqrjjT27T3Wijz3xJ7NeIc8ofIWAA==} engines: {node: '>= 16'} peerDependencies: vue: ^3.0.0 @@ -6986,9 +6994,6 @@ packages: engines: {node: '>=20.0.0'} hasBin: true - workbox-core@7.3.0: - resolution: {integrity: sha512-Z+mYrErfh4t3zi7NVTvOuACB0A/jA3bgxUN3PwtAVHvfEsZxV9Iju580VEETug3zYJRc0Dmii/aixI/Uxj8fmw==} - workbox-core@7.4.0: resolution: {integrity: sha512-6BMfd8tYEnN4baG4emG9U0hdXM4gGuDU3ectXuVHnj71vwxTFI7WOpQJC4siTOlVtGqCUtj0ZQNsrvi6kZZTAQ==} @@ -7001,9 +7006,6 @@ packages: workbox-navigation-preload@7.4.0: resolution: {integrity: sha512-etzftSgdQfjMcfPgbfaZCfM2QuR1P+4o8uCA2s4rf3chtKTq/Om7g/qvEOcZkG6v7JZOSOxVYQiOu6PbAZgU6w==} - workbox-precaching@7.3.0: - resolution: {integrity: sha512-ckp/3t0msgXclVAYaNndAGeAoWQUv7Rwc4fdhWL69CCAb2UHo3Cef0KIUctqfQj1p8h6aGyz3w8Cy3Ihq9OmIw==} - workbox-precaching@7.4.0: resolution: {integrity: sha512-VQs37T6jDqf1rTxUJZXRl3yjZMf5JX/vDPhmx2CPgDDKXATzEoqyRqhYnRoxl6Kr0rqaQlp32i9rtG5zTzIlNg==} @@ -7013,15 +7015,9 @@ packages: workbox-recipes@7.4.0: resolution: {integrity: sha512-kOkWvsAn4H8GvAkwfJTbwINdv4voFoiE9hbezgB1sb/0NLyTG4rE7l6LvS8lLk5QIRIto+DjXLuAuG3Vmt3cxQ==} - workbox-routing@7.3.0: - resolution: {integrity: sha512-ZUlysUVn5ZUzMOmQN3bqu+gK98vNfgX/gSTZ127izJg/pMMy4LryAthnYtjuqcjkN4HEAx1mdgxNiKJMZQM76A==} - workbox-routing@7.4.0: resolution: {integrity: sha512-C/ooj5uBWYAhAqwmU8HYQJdOjjDKBp9MzTQ+otpMmd+q0eF59K+NuXUek34wbL0RFrIXe/KKT+tUWcZcBqxbHQ==} - workbox-strategies@7.3.0: - resolution: {integrity: sha512-tmZydug+qzDFATwX7QiEL5Hdf7FrkhjaF9db1CbB39sDmEZJg3l9ayDvPxy8Y18C3Y66Nrr9kkN1f/RlkDgllg==} - workbox-strategies@7.4.0: resolution: {integrity: sha512-T4hVqIi5A4mHi92+5EppMX3cLaVywDp8nsyUgJhOZxcfSV/eQofcOA6/EMo5rnTNmNTpw0rUgjAI6LaVullPpg==} @@ -8627,7 +8623,7 @@ snapshots: '@humanwhocodes/retry@0.4.2': {} - '@intlify/bundle-utils@11.0.1(vue-i18n@11.1.12(vue@3.5.24(typescript@5.9.3)))': + '@intlify/bundle-utils@11.0.1(vue-i18n@11.2.1(vue@3.5.24(typescript@5.9.3)))': dependencies: '@intlify/message-compiler': 11.1.12 '@intlify/shared': 11.1.12 @@ -8639,26 +8635,33 @@ snapshots: source-map-js: 1.2.1 yaml-eslint-parser: 1.2.3 optionalDependencies: - vue-i18n: 11.1.12(vue@3.5.24(typescript@5.9.3)) + vue-i18n: 11.2.1(vue@3.5.24(typescript@5.9.3)) - '@intlify/core-base@11.1.12': + '@intlify/core-base@11.2.1': dependencies: - '@intlify/message-compiler': 11.1.12 - '@intlify/shared': 11.1.12 + '@intlify/message-compiler': 11.2.1 + '@intlify/shared': 11.2.1 '@intlify/message-compiler@11.1.12': dependencies: '@intlify/shared': 11.1.12 source-map-js: 1.2.1 + '@intlify/message-compiler@11.2.1': + dependencies: + '@intlify/shared': 11.2.1 + source-map-js: 1.2.1 + '@intlify/shared@11.1.12': {} - '@intlify/unplugin-vue-i18n@11.0.1(@vue/compiler-dom@3.5.24)(eslint@9.39.1(jiti@2.4.2))(rollup@4.53.3)(typescript@5.9.3)(vue-i18n@11.1.12(vue@3.5.24(typescript@5.9.3)))(vue@3.5.24(typescript@5.9.3))': + '@intlify/shared@11.2.1': {} + + '@intlify/unplugin-vue-i18n@11.0.1(@vue/compiler-dom@3.5.24)(eslint@9.39.1(jiti@2.4.2))(rollup@4.53.3)(typescript@5.9.3)(vue-i18n@11.2.1(vue@3.5.24(typescript@5.9.3)))(vue@3.5.24(typescript@5.9.3))': dependencies: '@eslint-community/eslint-utils': 4.7.0(eslint@9.39.1(jiti@2.4.2)) - '@intlify/bundle-utils': 11.0.1(vue-i18n@11.1.12(vue@3.5.24(typescript@5.9.3))) + '@intlify/bundle-utils': 11.0.1(vue-i18n@11.2.1(vue@3.5.24(typescript@5.9.3))) '@intlify/shared': 11.1.12 - '@intlify/vue-i18n-extensions': 8.0.0(@intlify/shared@11.1.12)(@vue/compiler-dom@3.5.24)(vue-i18n@11.1.12(vue@3.5.24(typescript@5.9.3)))(vue@3.5.24(typescript@5.9.3)) + '@intlify/vue-i18n-extensions': 8.0.0(@intlify/shared@11.1.12)(@vue/compiler-dom@3.5.24)(vue-i18n@11.2.1(vue@3.5.24(typescript@5.9.3)))(vue@3.5.24(typescript@5.9.3)) '@rollup/pluginutils': 5.1.3(rollup@4.53.3) '@typescript-eslint/scope-manager': 8.40.0 '@typescript-eslint/typescript-estree': 8.40.0(typescript@5.9.3) @@ -8669,7 +8672,7 @@ snapshots: unplugin: 2.3.10 vue: 3.5.24(typescript@5.9.3) optionalDependencies: - vue-i18n: 11.1.12(vue@3.5.24(typescript@5.9.3)) + vue-i18n: 11.2.1(vue@3.5.24(typescript@5.9.3)) transitivePeerDependencies: - '@vue/compiler-dom' - eslint @@ -8677,14 +8680,14 @@ snapshots: - supports-color - typescript - '@intlify/vue-i18n-extensions@8.0.0(@intlify/shared@11.1.12)(@vue/compiler-dom@3.5.24)(vue-i18n@11.1.12(vue@3.5.24(typescript@5.9.3)))(vue@3.5.24(typescript@5.9.3))': + '@intlify/vue-i18n-extensions@8.0.0(@intlify/shared@11.1.12)(@vue/compiler-dom@3.5.24)(vue-i18n@11.2.1(vue@3.5.24(typescript@5.9.3)))(vue@3.5.24(typescript@5.9.3))': dependencies: '@babel/parser': 7.28.3 optionalDependencies: '@intlify/shared': 11.1.12 '@vue/compiler-dom': 3.5.24 vue: 3.5.24(typescript@5.9.3) - vue-i18n: 11.1.12(vue@3.5.24(typescript@5.9.3)) + vue-i18n: 11.2.1(vue@3.5.24(typescript@5.9.3)) '@isaacs/balanced-match@4.0.1': {} @@ -12053,7 +12056,7 @@ snapshots: punycode.js: 2.3.1 uc.micro: 2.1.0 - marked@16.4.2: {} + marked@17.0.1: {} math-intrinsics@1.1.0: {} @@ -14291,10 +14294,10 @@ snapshots: flatpickr: 4.6.13 vue: 3.5.24(typescript@5.9.3) - vue-i18n@11.1.12(vue@3.5.24(typescript@5.9.3)): + vue-i18n@11.2.1(vue@3.5.24(typescript@5.9.3)): dependencies: - '@intlify/core-base': 11.1.12 - '@intlify/shared': 11.1.12 + '@intlify/core-base': 11.2.1 + '@intlify/shared': 11.2.1 '@vue/devtools-api': 6.6.4 vue: 3.5.24(typescript@5.9.3) @@ -14505,8 +14508,6 @@ snapshots: - '@types/babel__core' - supports-color - workbox-core@7.3.0: {} - workbox-core@7.4.0: {} workbox-expiration@7.4.0: @@ -14525,12 +14526,6 @@ snapshots: dependencies: workbox-core: 7.4.0 - workbox-precaching@7.3.0: - dependencies: - workbox-core: 7.3.0 - workbox-routing: 7.3.0 - workbox-strategies: 7.3.0 - workbox-precaching@7.4.0: dependencies: workbox-core: 7.4.0 @@ -14550,18 +14545,10 @@ snapshots: workbox-routing: 7.4.0 workbox-strategies: 7.4.0 - workbox-routing@7.3.0: - dependencies: - workbox-core: 7.3.0 - workbox-routing@7.4.0: dependencies: workbox-core: 7.4.0 - workbox-strategies@7.3.0: - dependencies: - workbox-core: 7.3.0 - workbox-strategies@7.4.0: dependencies: workbox-core: 7.4.0 diff --git a/frontend/src/components/input/editor/TipTap.vue b/frontend/src/components/input/editor/TipTap.vue index 1c9a5f06c..1041a30f9 100644 --- a/frontend/src/components/input/editor/TipTap.vue +++ b/frontend/src/components/input/editor/TipTap.vue @@ -145,7 +145,7 @@ import {eventToHotkeyString} from '@github/hotkey' import EditorToolbar from './EditorToolbar.vue' import StarterKit from '@tiptap/starter-kit' -import {Extension, mergeAttributes} from '@tiptap/core' +import {Extension, mergeAttributes, type SetContentOptions} from '@tiptap/core' import {EditorContent, type Extensions, useEditor, VueNodeViewRenderer} from '@tiptap/vue-3' import {Plugin, PluginKey} from '@tiptap/pm/state' import {marked} from 'marked' @@ -216,6 +216,12 @@ const tiptapInstanceRef = ref(null) const {t} = useI18n() +const defaultSetContentOptions: SetContentOptions = { + parseOptions: { + preserveWhitespace: true, + }, +} + const CustomTableCell = TableCell.extend({ addAttributes() { return { @@ -549,6 +555,9 @@ const editor = useEditor({ onUpdate: () => { bubbleNow() }, + parseOptions: { + preserveWhitespace: true, + }, }) watch( @@ -606,7 +615,10 @@ function bubbleSave() { } function exitEditMode() { - editor.value?.commands.setContent(lastSavedState, {emitUpdate: false}) + editor.value?.commands.setContent(lastSavedState, { + ...defaultSetContentOptions, + emitUpdate: false, + }) // Clear draft from localStorage when discarding changes if (props.storageKey) { @@ -659,7 +671,10 @@ function uploadAndInsertFiles(files: File[] | FileList) { const html = editor.value?.getHTML().replace(UPLOAD_PLACEHOLDER_ELEMENT, '') ?? '' - editor.value?.commands.setContent(html, {emitUpdate: false}) + editor.value?.commands.setContent(html, { + ...defaultSetContentOptions, + emitUpdate: false, + }) bubbleNow() }) @@ -733,7 +748,10 @@ onBeforeUnmount(() => { function setModeAndValue(value: string) { internalMode.value = isEditorContentEmpty(value) ? 'edit' : 'preview' - editor.value?.commands.setContent(value, {emitUpdate: false}) + editor.value?.commands.setContent(value, { + ...defaultSetContentOptions, + emitUpdate: false, + }) } diff --git a/frontend/src/components/tasks/partials/Attachments.vue b/frontend/src/components/tasks/partials/Attachments.vue index 34397da6d..6b5f54bd7 100644 --- a/frontend/src/components/tasks/partials/Attachments.vue +++ b/frontend/src/components/tasks/partials/Attachments.vue @@ -126,7 +126,7 @@
@@ -172,8 +172,8 @@