Compare commits

..

76 Commits

Author SHA1 Message Date
Carl Schwan
8ebeeaa755 perf: Use getBoard to get the board
So that this can benefit from a local cache

Signed-off-by: Carl Schwan <carl.schwan@nextclound.com>
2025-08-13 16:51:40 +02:00
Carl Schwan
ce81c89b03 perf: Only enrich with labels when no labels was prefetched
Signed-off-by: Carl Schwan <carl.schwan@nextclound.com>
2025-08-13 13:32:17 +02:00
Carl Schwan
1e59511d8d perf: Don't call twice the same query
Find entities will execute the query already, there is no need to do it
twice.

Signed-off-by: Carl Schwan <carl.schwan@nextclound.com>
2025-08-13 13:31:41 +02:00
Nextcloud bot
0ed8b21b3c fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-08-12 00:29:18 +00:00
github-actions[bot]
6f4f59a976 Merge pull request #7161 from nextcloud/automated/noid/main-update-nextcloud-ocp
[main] Update nextcloud/ocp dependency
2025-08-10 04:05:05 +00:00
nextcloud-command
f80d7a5e79 chore(dev-deps): Bump nextcloud/ocp package
Signed-off-by: GitHub <noreply@github.com>
2025-08-10 03:47:48 +00:00
Nextcloud bot
e3843f9808 fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-08-10 00:28:20 +00:00
Nextcloud bot
1ec7f1a971 fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-08-09 00:28:47 +00:00
Nextcloud bot
18eea3584e fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-08-04 00:31:06 +00:00
github-actions[bot]
844d492c8d Merge pull request #7153 from nextcloud/automated/noid/main-update-nextcloud-ocp
[main] Update nextcloud/ocp dependency
2025-08-03 04:40:26 +00:00
nextcloud-command
840e9f309f chore(dev-deps): Bump nextcloud/ocp package
Signed-off-by: GitHub <noreply@github.com>
2025-08-03 03:56:02 +00:00
Nextcloud bot
fe53440ee4 fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-08-03 00:28:38 +00:00
Nextcloud bot
162dbf25dd fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-08-02 00:29:05 +00:00
Nextcloud bot
17de153ec8 fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-08-01 00:28:49 +00:00
grnd-alt
58027c8294 Merge pull request #7124 from stpronk/patch-1
[main] Add `$changes->getBefore()` to event in reorder
2025-07-31 10:40:35 +02:00
StPronk
79eba77b49 Updated all functionalities within cardService to include a before state where possible
Signed-off-by: StPronk <stpronk@gmail.com>
2025-07-31 08:14:00 +02:00
Nextcloud bot
0efdfab232 fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-07-30 00:28:59 +00:00
grnd-alt
5744944957 Merge pull request #7139 from nextcloud/fix/6739
fix:  Use getId() method for card ID retrieval
2025-07-29 10:58:11 +02:00
grnd-alt
1c1e3e944e fix: make labels in dialog deletable
Signed-off-by: grnd-alt <github@belakkaf.net>
2025-07-29 10:39:39 +02:00
grnd-alt
85bb603103 fix: dont add labels without id
Signed-off-by: grnd-alt <github@belakkaf.net>
2025-07-29 10:37:19 +02:00
Nextcloud bot
90f10190ac fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-07-29 00:28:40 +00:00
Enjeck C.
ab3b2aa23c fix: Use getId() method for card ID retrieval
Signed-off-by: Enjeck C. <patrathewhiz@gmail.com>
2025-07-28 09:03:43 +01:00
Nextcloud bot
b9c0d454d5 fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-07-28 00:28:48 +00:00
github-actions[bot]
438825530c Merge pull request #7134 from nextcloud/automated/noid/main-update-nextcloud-ocp
[main] Update nextcloud/ocp dependency
2025-07-27 04:09:50 +00:00
nextcloud-command
c346c3cdf8 chore(dev-deps): Bump nextcloud/ocp package
Signed-off-by: GitHub <noreply@github.com>
2025-07-27 03:50:55 +00:00
Luka Trovic
f1da8b30a4 Merge pull request #7131 from nextcloud/fix-board-acl-check
fix: acl check when delete, update board acl
2025-07-25 17:51:00 +02:00
Luka Trovic
8229d40981 fix: acl check when delete, update board acl
Signed-off-by: Luka Trovic <luka@nextcloud.com>
2025-07-25 16:21:10 +02:00
Luka Trovic
244d61c783 Merge pull request #7127 from nextcloud/fix/allow-foreign-label-deletion
fix:allow foreign label deletion
2025-07-25 12:26:54 +02:00
Nextcloud bot
879e59c003 fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-07-25 00:29:30 +00:00
grnd-alt
4741817594 fix:allow foreign label deletion
Signed-off-by: grnd-alt <github@belakkaf.net>
2025-07-24 12:02:30 +02:00
grnd-alt
af99211d6b Merge pull request #7114 from nextcloud/use-outline-icons
feat: use outline icons
2025-07-24 10:50:40 +02:00
Nextcloud bot
b120ce868d fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-07-24 00:30:25 +00:00
Luka Trovic
f0ea3f3ce5 Merge pull request #7126 from nextcloud/update-workflows
chore: update workflows to skip stable29
2025-07-23 20:41:36 +02:00
dependabot[bot]
2f0caac403 Merge pull request #7118 from nextcloud/dependabot/composer/tests/integration/behat/behat-approx-3.23.0 2025-07-23 15:53:24 +00:00
dependabot[bot]
cc93386da6 Chore(deps-dev): Update behat/behat requirement in /tests/integration
Updates the requirements on [behat/behat](https://github.com/Behat/Behat) to permit the latest version.
- [Release notes](https://github.com/Behat/Behat/releases)
- [Changelog](https://github.com/Behat/Behat/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Behat/Behat/compare/v3.22.0...v3.23.0)

---
updated-dependencies:
- dependency-name: behat/behat
  dependency-version: 3.23.0
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-23 17:47:59 +02:00
Luka Trovic
5573a8bb1a chore: update workflows to skip stable29
Signed-off-by: Luka Trovic <luka@nextcloud.com>
2025-07-23 17:46:16 +02:00
Nextcloud bot
c2e2e73b88 fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-07-23 00:33:41 +00:00
Nextcloud bot
e509ac77d4 fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-07-22 00:29:05 +00:00
Luka Trovic
909af7e1bb Merge pull request #7080 from Fledermaus-20/main
Add OCC commands for global calendar feature opt-in and opt-out in Deck
2025-07-21 13:58:09 +02:00
github-actions[bot]
6828144815 Merge pull request #7120 from nextcloud/automated/noid/main-update-nextcloud-ocp
[main] Update nextcloud/ocp dependency
2025-07-20 04:29:44 +00:00
nextcloud-command
1d9382429e chore(dev-deps): Bump nextcloud/ocp package
Signed-off-by: GitHub <noreply@github.com>
2025-07-20 03:49:47 +00:00
Fledermaus-20
f68f7b54d6 Merge branch 'main' into main 2025-07-18 19:40:01 +02:00
Luka Trovic
dd4da2dd34 Merge pull request #7110 from nextcloud/dependabot/github_actions/svenstaro/upload-release-action-2.11.2
Chore(deps): Bump svenstaro/upload-release-action from 2.9.0 to 2.11.2
2025-07-16 09:30:11 +02:00
Luka Trovic
327bfff315 feat: use outline icons
Signed-off-by: Luka Trovic <luka@nextcloud.com>
2025-07-15 20:57:36 +02:00
dependabot[bot]
0b6c492c75 Chore(deps): Bump svenstaro/upload-release-action from 2.9.0 to 2.11.2
Bumps [svenstaro/upload-release-action](https://github.com/svenstaro/upload-release-action) from 2.9.0 to 2.11.2.
- [Release notes](https://github.com/svenstaro/upload-release-action/releases)
- [Changelog](https://github.com/svenstaro/upload-release-action/blob/master/CHANGELOG.md)
- [Commits](04733e069f...81c65b7cd4)

---
updated-dependencies:
- dependency-name: svenstaro/upload-release-action
  dependency-version: 2.11.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-15 18:57:33 +00:00
Luka Trovic
bbe1b37dfe Merge pull request #7084 from nextcloud/dependabot/github_actions/svenstaro/upload-release-action-2.10.0
Chore(deps): Bump svenstaro/upload-release-action from 2.9.0 to 2.10.0
2025-07-15 20:56:20 +02:00
Luka Trovic
3b5bf56049 Merge pull request #7053 from nextcloud/dependabot/composer/justinrainbow/json-schema-6.4.2
Chore(deps): Bump justinrainbow/json-schema from 6.4.1 to 6.4.2
2025-07-15 20:56:12 +02:00
dependabot[bot]
97ab42ad5c Chore(deps): Bump svenstaro/upload-release-action from 2.9.0 to 2.10.0
Bumps [svenstaro/upload-release-action](https://github.com/svenstaro/upload-release-action) from 2.9.0 to 2.10.0.
- [Release notes](https://github.com/svenstaro/upload-release-action/releases)
- [Changelog](https://github.com/svenstaro/upload-release-action/blob/master/CHANGELOG.md)
- [Commits](04733e069f...ebd922b779)

---
updated-dependencies:
- dependency-name: svenstaro/upload-release-action
  dependency-version: 2.10.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-15 20:51:00 +02:00
dependabot[bot]
42d3e54841 Chore(deps): Bump justinrainbow/json-schema from 6.4.1 to 6.4.2
Bumps [justinrainbow/json-schema](https://github.com/jsonrainbow/json-schema) from 6.4.1 to 6.4.2.
- [Release notes](https://github.com/jsonrainbow/json-schema/releases)
- [Changelog](https://github.com/jsonrainbow/json-schema/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jsonrainbow/json-schema/compare/6.4.1...6.4.2)

---
updated-dependencies:
- dependency-name: justinrainbow/json-schema
  dependency-version: 6.4.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-15 20:50:25 +02:00
dependabot[bot]
8dd62dd8d9 Merge pull request #7047 from nextcloud/dependabot/npm_and_yarn/webpack-dev-server-5.2.2 2025-07-15 18:49:03 +00:00
dependabot[bot]
160900f2bb Chore(deps-dev): Bump webpack-dev-server from 5.1.0 to 5.2.2
Bumps [webpack-dev-server](https://github.com/webpack/webpack-dev-server) from 5.1.0 to 5.2.2.
- [Release notes](https://github.com/webpack/webpack-dev-server/releases)
- [Changelog](https://github.com/webpack/webpack-dev-server/blob/master/CHANGELOG.md)
- [Commits](https://github.com/webpack/webpack-dev-server/compare/v5.1.0...v5.2.2)

---
updated-dependencies:
- dependency-name: webpack-dev-server
  dependency-version: 5.2.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-15 20:42:21 +02:00
Luka Trovic
020107d3f4 Merge pull request #7036 from nextcloud/dependabot/npm_and_yarn/main/nextcloud/vue-8.27.0
Chore(deps): Bump @nextcloud/vue from 8.26.0 to 8.27.0
2025-07-15 20:42:10 +02:00
dependabot[bot]
68fb689df9 Merge pull request #6989 from nextcloud/dependabot/composer/tests/integration/behat/behat-approx-3.22.0 2025-07-15 18:38:53 +00:00
dependabot[bot]
97d8018cd1 Chore(deps): Bump @nextcloud/vue from 8.26.0 to 8.27.0
Bumps [@nextcloud/vue](https://github.com/nextcloud-libraries/nextcloud-vue) from 8.26.0 to 8.27.0.
- [Release notes](https://github.com/nextcloud-libraries/nextcloud-vue/releases)
- [Changelog](https://github.com/nextcloud-libraries/nextcloud-vue/blob/v8.27.0/CHANGELOG.md)
- [Commits](https://github.com/nextcloud-libraries/nextcloud-vue/compare/v8.26.0...v8.27.0)

---
updated-dependencies:
- dependency-name: "@nextcloud/vue"
  dependency-version: 8.27.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-15 20:36:31 +02:00
dependabot[bot]
d666cba097 Chore(deps-dev): Update behat/behat requirement in /tests/integration
Updates the requirements on [behat/behat](https://github.com/Behat/Behat) to permit the latest version.
- [Release notes](https://github.com/Behat/Behat/releases)
- [Changelog](https://github.com/Behat/Behat/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Behat/Behat/compare/v3.21.1...v3.22.0)

---
updated-dependencies:
- dependency-name: behat/behat
  dependency-version: 3.22.0
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-15 20:33:37 +02:00
dependabot[bot]
a8c337eb07 Merge pull request #6984 from nextcloud/dependabot/npm_and_yarn/main/nextcloud/moment-1.3.4 2025-07-15 18:23:20 +00:00
dependabot[bot]
a3a46012a4 Chore(deps): Bump @nextcloud/moment from 1.3.2 to 1.3.4
Bumps [@nextcloud/moment](https://github.com/nextcloud-libraries/nextcloud-moment) from 1.3.2 to 1.3.4.
- [Release notes](https://github.com/nextcloud-libraries/nextcloud-moment/releases)
- [Changelog](https://github.com/nextcloud-libraries/nextcloud-moment/blob/main/CHANGELOG.md)
- [Commits](https://github.com/nextcloud-libraries/nextcloud-moment/compare/v1.3.2...v1.3.4)

---
updated-dependencies:
- dependency-name: "@nextcloud/moment"
  dependency-version: 1.3.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-15 20:18:00 +02:00
dependabot[bot]
1aa7105ceb Merge pull request #6983 from nextcloud/dependabot/npm_and_yarn/main/nextcloud/cypress-1.0.0-beta.15 2025-07-15 17:34:35 +00:00
dependabot[bot]
a042a4b076 Chore(deps-dev): Bump @nextcloud/cypress
Bumps [@nextcloud/cypress](https://github.com/nextcloud/nextcloud-cypress) from 1.0.0-beta.13 to 1.0.0-beta.15.
- [Release notes](https://github.com/nextcloud/nextcloud-cypress/releases)
- [Commits](https://github.com/nextcloud/nextcloud-cypress/compare/v1.0.0-beta.13...v1.0.0-beta.15)

---
updated-dependencies:
- dependency-name: "@nextcloud/cypress"
  dependency-version: 1.0.0-beta.15
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-15 19:28:33 +02:00
dependabot[bot]
d0f992ecbb Merge pull request #6973 from nextcloud/dependabot/npm_and_yarn/main/babel/runtime-7.27.1 2025-07-15 17:25:51 +00:00
dependabot[bot]
fc245759a3 Chore(deps): Bump @babel/runtime from 7.27.0 to 7.27.1
Bumps [@babel/runtime](https://github.com/babel/babel/tree/HEAD/packages/babel-runtime) from 7.27.0 to 7.27.1.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.27.1/packages/babel-runtime)

---
updated-dependencies:
- dependency-name: "@babel/runtime"
  dependency-version: 7.27.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-15 19:19:41 +02:00
Luka Trovic
60bba3332b Merge pull request #7104 from nextcloud/fix-unstable-cypress
fix: unstable cypress
2025-07-15 16:47:08 +02:00
Luka Trovic
c93e07e0bd Merge pull request #7074 from nextcloud/automated/noid/main-update-nextcloud-ocp
[main] Update nextcloud/ocp dependency
2025-07-15 11:19:49 +02:00
Luka Trovic
9e6975b22b chore: update query count
Signed-off-by: Luka Trovic <luka@nextcloud.com>
2025-07-15 11:11:37 +02:00
nextcloud-command
979f9b2c53 chore(dev-deps): Bump nextcloud/ocp package
Signed-off-by: GitHub <noreply@github.com>
2025-07-15 11:11:37 +02:00
Luka Trovic
307bdf5e68 Merge pull request #7078 from nextcloud/dependabot/npm_and_yarn/pbkdf2-3.1.3
Chore(deps-dev): Bump pbkdf2 from 3.1.2 to 3.1.3
2025-07-15 10:52:09 +02:00
Luka Trovic
4380533a66 Merge pull request #7107 from nextcloud/fix-new-stack-input-field
fix: styling for new stack input field
2025-07-14 15:13:32 +02:00
Nextcloud bot
3a1fbb90c3 fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-07-14 00:27:50 +00:00
Luka Trovic
dd64e0c73d fix: styling for new stack input field
Signed-off-by: Luka Trovic <luka@nextcloud.com>
2025-07-11 18:59:52 +02:00
Fledermaus-20
8a9751ac6b Merge branch 'main' into main 2025-07-11 12:54:25 +02:00
Luka Trovic
c16f26d8d2 fix: unstable cypress
Signed-off-by: Luka Trovic <luka@nextcloud.com>
2025-07-10 16:53:03 +02:00
Fledermaus-20
c7edec8f6e updated composer.json
Signed-off-by: Fledermaus-20 <benno.traub@icloud.com>
2025-07-10 11:37:57 +02:00
Nextcloud bot
a6de59fe9c fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-07-10 00:28:44 +00:00
Fledermaus-20
8c891c7f57 Merge branch 'main' into main
Signed-off-by: Fledermaus-20 <139645999+Fledermaus-20@users.noreply.github.com>
2025-07-06 12:55:53 +02:00
Fledermaus-20
b73c2becda Add toggle for calendar feature with OCC
Signed-off-by: Fledermaus-20 <benno.traub@icloud.com>
2025-07-06 12:52:58 +02:00
dependabot[bot]
26861c890d Chore(deps-dev): Bump pbkdf2 from 3.1.2 to 3.1.3
Bumps [pbkdf2](https://github.com/crypto-browserify/pbkdf2) from 3.1.2 to 3.1.3.
- [Changelog](https://github.com/browserify/pbkdf2/blob/master/CHANGELOG.md)
- [Commits](https://github.com/crypto-browserify/pbkdf2/compare/v3.1.2...v3.1.3)

---
updated-dependencies:
- dependency-name: pbkdf2
  dependency-version: 3.1.3
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-25 21:26:44 +02:00
90 changed files with 6979 additions and 7881 deletions

View File

@@ -173,7 +173,7 @@ jobs:
tar -zcvf ${{ env.APP_NAME }}.tar.gz ${{ env.APP_NAME }}
- name: Attach tarball to github release
uses: svenstaro/upload-release-action@04733e069f2d7f7f0b4aebc4fbdbce8613b03ccd # v2
uses: svenstaro/upload-release-action@81c65b7cd4de9b2570615ce3aad67a41de5b1a13 # v2
id: attach_to_release
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -24,7 +24,7 @@ jobs:
strategy:
fail-fast: false
matrix:
branches: ['main', 'master', 'stable31', 'stable30', 'stable29']
branches: ['main', 'master', 'stable31', 'stable30']
name: npm-audit-fix-${{ matrix.branches }}

View File

@@ -23,7 +23,7 @@ jobs:
strategy:
fail-fast: false
matrix:
branches: ['main', 'master', 'stable31', 'stable30', 'stable29']
branches: ['main', 'master', 'stable31', 'stable30']
name: update-nextcloud-ocp-${{ matrix.branches }}

View File

@@ -62,6 +62,7 @@
<command>OCA\Deck\Command\UserExport</command>
<command>OCA\Deck\Command\BoardImport</command>
<command>OCA\Deck\Command\TransferOwnership</command>
<command>OCA\Deck\Command\CalendarToggle</command>
</commands>
<activity>
<settings>

20
composer.lock generated
View File

@@ -8,16 +8,16 @@
"packages": [
{
"name": "justinrainbow/json-schema",
"version": "6.4.1",
"version": "6.4.2",
"source": {
"type": "git",
"url": "https://github.com/jsonrainbow/json-schema.git",
"reference": "35d262c94959571e8736db1e5c9bc36ab94ae900"
"reference": "ce1fd2d47799bb60668643bc6220f6278a4c1d02"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/35d262c94959571e8736db1e5c9bc36ab94ae900",
"reference": "35d262c94959571e8736db1e5c9bc36ab94ae900",
"url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/ce1fd2d47799bb60668643bc6220f6278a4c1d02",
"reference": "ce1fd2d47799bb60668643bc6220f6278a4c1d02",
"shasum": ""
},
"require": {
@@ -77,9 +77,9 @@
],
"support": {
"issues": "https://github.com/jsonrainbow/json-schema/issues",
"source": "https://github.com/jsonrainbow/json-schema/tree/6.4.1"
"source": "https://github.com/jsonrainbow/json-schema/tree/6.4.2"
},
"time": "2025-04-04T13:08:07+00:00"
"time": "2025-06-03T18:27:04+00:00"
},
{
"name": "marc-mabe/php-enum",
@@ -380,12 +380,12 @@
"source": {
"type": "git",
"url": "https://github.com/nextcloud-deps/ocp.git",
"reference": "97d7aa6e535670437a178084eea91a42998fef5c"
"reference": "c2c75ad8fdc54cbc6341764b5a2a8ecf860e6160"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nextcloud-deps/ocp/zipball/97d7aa6e535670437a178084eea91a42998fef5c",
"reference": "97d7aa6e535670437a178084eea91a42998fef5c",
"url": "https://api.github.com/repos/nextcloud-deps/ocp/zipball/c2c75ad8fdc54cbc6341764b5a2a8ecf860e6160",
"reference": "c2c75ad8fdc54cbc6341764b5a2a8ecf860e6160",
"shasum": ""
},
"require": {
@@ -421,7 +421,7 @@
"issues": "https://github.com/nextcloud-deps/ocp/issues",
"source": "https://github.com/nextcloud-deps/ocp/tree/master"
},
"time": "2025-06-13T00:53:13+00:00"
"time": "2025-08-10T01:01:23+00:00"
},
{
"name": "nikic/php-parser",

View File

@@ -84,7 +84,7 @@ describe('Card', function () {
cy.get('.modal-mask.card-selector .multiselect-list').should('be.visible').click()
cy.get('.vs__dropdown-menu span[title="TestList"]').should('be.visible').click()
cy.get('.modal-mask.card-selector button.button-vue--primary').contains('Create card').should('be.visible').click()
cy.get('.modal-mask.card-selector button.button-vue--vue-primary').should('be.visible').click()
cy.wait('@save', { timeout: 7000 })
cy.reload()
@@ -187,7 +187,7 @@ describe('Card', function () {
cy.get('.file-picker__main').should('be.visible')
cy.get('.file-picker__main [data-filename="welcome.txt"]', { timeout: 30000 }).should('be.visible')
.click()
cy.get('.dialog__actions button.button-vue--primary').click()
cy.get('.dialog__actions button.button-vue--vue-primary').click()
cy.get('.attachment-list .filename').contains('welcome')
cy.get('.attachment-list .filename .extension').contains('txt')
})
@@ -302,10 +302,11 @@ describe('Card', function () {
.first().click()
cy.get(`.card:contains("${newCardTitle}")`).should('be.visible').click()
cy.get('#app-sidebar-vue [data-test="tag-selector"] .vs__dropdown-toggle .vs__actions').should('be.visible').click()
// Add delay to ensure the events are bound
cy.wait(1000)
cy.get('#app-sidebar-vue [data-test="tag-selector"] .vs__dropdown-toggle').should('be.visible').click()
cy.get('.vs__dropdown-menu .tag:contains("Action needed")').should('be.visible').click()
cy.get('.vs__dropdown-menu .tag:contains("Later")').should('not.exist')
cy.get('#app-sidebar-vue [data-test="tag-selector"] .vs__dropdown-toggle .vs__actions').should('be.visible').click()
cy.get('.vs__dropdown-menu .tag:contains("Later")').should('be.visible').click()
cy.get('.vs__selected .tag:contains("Action needed")').should('be.visible')

View File

@@ -27,7 +27,7 @@ describe('Deck dashboard', function() {
const defaultBoard = 'Welcome to Nextcloud Deck!'
cy.get('#deck-navigation-all')
cy.get('.app-navigation-entry-wrapper[icon=icon-deck]')
.find('ul.app-navigation-entry__children .app-navigation-entry:contains(' + defaultBoard + ')')
.first()
.contains(defaultBoard)

View File

@@ -93,7 +93,7 @@ Cypress.Commands.add('createExampleBoard', ({ user, board }) => {
})
Cypress.Commands.add('getNavigationEntry', (boardTitle) => {
return cy.get('#deck-navigation-all')
return cy.get('.app-navigation-entry-wrapper[icon=icon-deck]')
.find('ul.app-navigation-entry__children .app-navigation-entry:contains(' + boardTitle + ')')
.find('a.app-navigation-entry-link')
})
@@ -102,7 +102,11 @@ Cypress.Commands.add('shareBoardWithUi', (query, userId=query) => {
cy.intercept({ method: 'GET', url: `**/ocs/v2.php/apps/files_sharing/api/v1/sharees?search=${query}*` }).as('fetchRecipients')
cy.get('[aria-label="Open details"]').click()
cy.get('.app-sidebar').should('be.visible')
cy.get('.select input').type(`${query}`)
// Add delay to ensure the events are bound
cy.wait(1000)
cy.get('.select input').click().type(`${query}`)
cy.wait('@fetchRecipients', { timeout: 7000 })
cy.get('.vs__dropdown-menu .option').first().contains(query)

40
l10n/be.js Normal file
View File

@@ -0,0 +1,40 @@
OC.L10N.register(
"deck",
{
"Missing a temporary folder" : "Адсутнічае часовая папка",
"Could not write file to disk" : "Не ўдалося запісаць файл на дыск",
"A PHP extension stopped the file upload" : "Пашырэнне PHP спыніла запампоўванне файла",
"copy" : "копія",
"Done" : "Гатова",
"File" : "Файл",
"Cancel" : "Скасаваць",
"Active filters" : "Актыўныя фільтры",
"Apply filter" : "Ужыць фільтр",
"Open" : "Адкрыць",
"Clear filter" : "Ачысціць фільтр",
"Tags" : "Тэгі",
"Activity" : "Актыўнасць",
"Can edit" : "Можа рэдагаваць",
"Can share" : "Можа абагульваць",
"Owner" : "Уладальнік",
"Delete" : "Выдаліць",
"Edit" : "Рэдагаваць",
"Download" : "Спампаваць",
"Modified" : "Зменены",
"Save" : "Захаваць",
"Created:" : "Створана:",
"Reply" : "Адказаць",
"Open link" : "Адкрыць спасылку",
"seconds ago" : "с таму",
"Keyboard shortcuts" : "Спалучэнні клавіш",
"Keyboard shortcut" : "Спалучэнне клавіш",
"Action" : "Дзеянне",
"Search" : "Пошук",
"Shared with you" : "Абагулена з вамі",
"An error occurred" : "Узнікла памылка",
"No notifications" : "Няма апавяшчэнняў",
"Today" : "Сёння",
"Close" : "Закрыць",
"Share" : "Абагуліць"
},
"nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);");

38
l10n/be.json Normal file
View File

@@ -0,0 +1,38 @@
{ "translations": {
"Missing a temporary folder" : "Адсутнічае часовая папка",
"Could not write file to disk" : "Не ўдалося запісаць файл на дыск",
"A PHP extension stopped the file upload" : "Пашырэнне PHP спыніла запампоўванне файла",
"copy" : "копія",
"Done" : "Гатова",
"File" : "Файл",
"Cancel" : "Скасаваць",
"Active filters" : "Актыўныя фільтры",
"Apply filter" : "Ужыць фільтр",
"Open" : "Адкрыць",
"Clear filter" : "Ачысціць фільтр",
"Tags" : "Тэгі",
"Activity" : "Актыўнасць",
"Can edit" : "Можа рэдагаваць",
"Can share" : "Можа абагульваць",
"Owner" : "Уладальнік",
"Delete" : "Выдаліць",
"Edit" : "Рэдагаваць",
"Download" : "Спампаваць",
"Modified" : "Зменены",
"Save" : "Захаваць",
"Created:" : "Створана:",
"Reply" : "Адказаць",
"Open link" : "Адкрыць спасылку",
"seconds ago" : "с таму",
"Keyboard shortcuts" : "Спалучэнні клавіш",
"Keyboard shortcut" : "Спалучэнне клавіш",
"Action" : "Дзеянне",
"Search" : "Пошук",
"Shared with you" : "Абагулена з вамі",
"An error occurred" : "Узнікла памылка",
"No notifications" : "Няма апавяшчэнняў",
"Today" : "Сёння",
"Close" : "Закрыць",
"Share" : "Абагуліць"
},"pluralForm" :"nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);"
}

View File

@@ -37,9 +37,9 @@ OC.L10N.register(
"{user} has archived card {card} in list {stack} on board {board}" : "{user} ha archivado la tarjeta {card} en la lista {stack} del tablero {board}",
"You have unarchived card {card} in list {stack} on board {board}" : "Has desarchivado la tarjeta {card} en la lista {stack} del tablero {board}",
"{user} has unarchived card {card} in list {stack} on board {board}" : "{user} ha desarchivado la tarjeta {card} en la lista {stack} del tablero {board}",
"You have marked the card {card} as done in list {stack} on board {board}" : "Has marcado la tarjeta {card} como completada en la lista {stack} del tablero {board}",
"You have marked the card {card} as done in list {stack} on board {board}" : "Ud. ha marcado la tarjeta {card} como completada en la lista {stack} del tablero {board}",
"{user} has marked card {card} as done in list {stack} on board {board}" : "{user} ha marcado la tarjeta {card} como completada en la lista {stack} del tablero {board}",
"You have marked the card {card} as undone in list {stack} on board {board}" : "Has marcado la tarjeta {card} como no completada en la lista {stack} del tablero {board}",
"You have marked the card {card} as undone in list {stack} on board {board}" : "Ud. ha marcado la tarjeta {card} como no completada en la lista {stack} del tablero {board}",
"{user} has marked the card {card} as undone in list {stack} on board {board}" : "{user} ha marcado la tarjeta {card} como no completada en la lista {stack} del tablero {board}",
"You have removed the due date of card {card}" : "Has eliminado la fecha de vencimiento de {card}",
"{user} has removed the due date of card {card}" : "{user} ha eliminado la fecha de vencimiento de {card}",
@@ -81,10 +81,14 @@ OC.L10N.register(
"Could not write file to disk" : "No se ha podido escribir el archivo al disco",
"A PHP extension stopped the file upload" : "Una extensión de PHP ha detenido la subida del archivo",
"No file uploaded or file size exceeds maximum of %s" : "No se ha subido ningún archivo, o el tamaño del archivo excede el máximo de %s",
"Invalid file type. Only JSON files are allowed." : "Tipo de archivo inválido. Solo se permiten archivos JSON",
"Invalid JSON data" : "Datos JSON inválidos",
"Failed to import board" : "Fallo al importar tablero",
"Cards due today" : "Tarjetas que vencen hoy",
"Cards due tomorrow" : "Tarjetas que vencen mañana",
"Upcoming cards" : "Próximas tarjetas",
"Load more" : "Cargar más",
"Welcome to Nextcloud Deck!" : "¡Bienvenido a Nextcloud Deck!",
"The card \"%s\" on \"%s\" has been assigned to you by %s." : "La tarjeta \"%s\" en \"%s\" te ha sido asignada por %s.",
"{user} has assigned the card {deck-card} on {deck-board} to you." : "{user} te ha asigando la tarjeta {deck-card} de {deck-board} a ti.",
"The card \"%s\" on \"%s\" has reached its due date." : "La tarjeta \"%s\" en \"%s\" ha alcanzado su fecha límite.",
@@ -94,7 +98,7 @@ OC.L10N.register(
"The board \"%s\" has been shared with you by %s." : "El tablero \"%s\" ha sido compartido contigo por %s.",
"{user} has shared {deck-board} with you." : "{user} ha compartido {deck-board} contigo.",
"Deck board" : "Tablero Deck",
"Owned by %1$s" : "Apropiado por %1$s",
"Owned by %1$s" : "Propiedad de %1$s",
"Deck boards, cards and comments" : "Tableros Deck, tarjetas y comentarios",
"From %1$s, in %2$s/%3$s, owned by %4$s" : "De %1$s, en %2$s/%3$s, propiedad de %4$s",
"Create a new deck card" : "Crear una nueva tarjeta de tablero",
@@ -107,17 +111,25 @@ OC.L10N.register(
"Action needed" : "Acción necesaria",
"Later" : "Después",
"copy" : "copiar",
"Read more inside" : "Lea más, adentro",
"Custom lists - click to rename!" : "Listas personalizadas - ¡Haga clic para renombrar!",
"To Do" : "Por hacer",
"In Progress" : "En progreso",
"Done" : "Hecho",
"This comment has more than %s characters.\nAdded as an attachment to the card with name %s.\nAccessible on URL: %s." : "Este comentario tiene más de %s caracteres.\nAñadido como adjunto a la tarjeta con el nombre %s.\nAccesible en la URL: %s.",
"1. Open to learn more about boards and cards" : "1. Abra aquí para aprender más sobre los tableros y las tarjetas",
"2. Drag cards left and right, up and down" : "2. Arrastre las tarjetas a la izquierda y derecha, arriba y abajo",
"3. Apply rich formatting and link content" : "3. Aplique formato enriquecido y contenido a los enlaces",
"4. Share, comment and collaborate!" : "4. ¡Comparta, comente y colabore!",
"Create your first card!" : "¡Cree su primera tarjeta!",
"This comment has more than %s characters.\nAdded as an attachment to the card with name %s.\nAccessible on URL: %s." : "Este comentario tiene más de %s caracteres.\nSe ha añadido como adjunto a la tarjeta con el nombre %s.\nAccesible en la URL: %s.",
"Attachments" : "Adjuntos",
"File" : "Archivo",
"date" : "fecha",
"Card not found" : "Tarjeta no encontrada",
"Path is already shared with this card" : "La ruta ya se ha compartido con esta tarjeta",
"Invalid date, date format must be YYYY-MM-DD" : "Fecha no válida, el formato de las fechas debe ser AAAA-MM-DD",
"Personal planning and team project organization" : "Planificación personal y organización de proyecto de equipo",
"Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deck es una herramienta de organización de estilo kanban dirigida a la planificación personal y la organización de proyectos para equipos integrados con Nextcloud.\n\n\n- 📥 Agrega tus tareas a las tarjetas y ordénalas.\n- 📄 Escriba notas adicionales\n- 🔖 Asignar etiquetas para una organización mejor\n- 👥 Comparte con tu equipo, amigos o familia.\n- 📎 Adjuntar archivos e incrustarlos en su descripción\n- 💬 Discuta con su equipo usando comentarios.\n- ⚡ Mantenga un registro de los cambios en el flujo de actividad\n- 🚀 Organiza tu proyecto",
"Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deck es una herramienta de organización de estilo kanban dirigida a la planificación personal y la organización de proyectos para equipos, integrada a Nextcloud.\n\n\n- 📥 Agregue sus tareas a las tarjetas y póngalas en orden.\n- 📄 Escriba notas adicionales en Markdown\n- 🔖 Asigne etiquetas para una organización mejor\n- 👥 Comparta con su equipo, amigos o familia.\n- 📎 Adjunte archivos e incruste los mismos en su descripción Markdown\n- 💬 Discuta con su equipo usando comentarios.\n- ⚡ Mantenga un registro de los cambios en el flujo de actividad\n- 🚀 Organice su proyecto",
"Add board" : "Añadir tablero",
"Card details" : "Detalles de la tarjeta",
"Select the board to link to a project" : "Selecciona el tablero que enlazar a un proyecto",
@@ -165,8 +177,8 @@ OC.L10N.register(
"Hide archived cards" : "Ocultar tarjetas archivadas",
"Show archived cards" : "Mostrar tarjetas archivadas",
"Toggle compact mode" : "Mostrar/ocultar modo compacto",
"Hide card cover images" : "Ocultar la imagen principal de las tarjetas",
"Show card cover images" : "Mostrar la imagen principal de las tarjetas",
"Hide card cover images" : "Ocultar la imagen de portada de las tarjetas",
"Show card cover images" : "Mostrar la imagen de portada de las tarjetas",
"Open details" : "Abrir detalles",
"Details" : "Detalles",
"Currently present people" : "Personas presentes actualmente",
@@ -181,11 +193,11 @@ OC.L10N.register(
"Undo" : "Deshacer",
"Deleted cards" : "Cartas eliminadas",
"Failed to create share with {displayName}" : "Fallo al crear el recurso compartido denominado {displayName}",
"Are you sure you want to transfer the board {title} to {user}?" : "¿Estás seguro de que quieres transferir el tablero {título} a {usuario}?",
"Transfer the board." : "Transfiere el tablero.",
"Are you sure you want to transfer the board {title} to {user}?" : "¿Está seguro de que quiere transferir el tablero {title} a {user}?",
"Transfer the board." : "Transfiera el tablero.",
"Transfer" : "Transferir",
"The board has been transferred to {user}" : "El tablero ha sido transferido a {usuario}",
"Failed to transfer the board to {user}" : "Failed to transfer the board to {user}",
"The board has been transferred to {user}" : "El tablero ha sido transferido a {user}",
"Failed to transfer the board to {user}" : "Fallo al transferir el tablero a {user}",
"Share board with a user, group or team …" : "Compartir tablero con un usuario, grupo o equipo …",
"Searching for users, groups and teams …" : "Buscando usuarios, grupos y equipos …",
"No participants found" : "No se encontraron participantes",
@@ -218,7 +230,7 @@ OC.L10N.register(
"Invalid path selected" : "Ruta seleccionada no válida",
"Upload new files" : "Subir nuevos archivos",
"Share from Files" : "Compartir desde Archivos",
"Pending share" : "Pendiente de compartir",
"Pending share" : "Recurso compartido pendiente",
"Add this attachment" : "Añadir este adjunto",
"Show in Files" : "Mostrar en Archivos",
"Download" : "Descargar",
@@ -228,6 +240,7 @@ OC.L10N.register(
"Modified" : "Modificado",
"Created" : "Creado",
"The title cannot be empty." : "El título no puede estar vacío.",
"Cannot close unsaved card!" : "¡No se puede cerrar esta tarjeta no guardada!",
"Open in sidebar view" : "Abrir en vista de barra lateral",
"Open in bigger view" : "Abrir en vista más grande",
"Comments" : "Comentarios",
@@ -242,6 +255,7 @@ OC.L10N.register(
"Reply" : "Responder",
"Update" : "Actualizar",
"Write a description …" : "Escribe una descripción...",
"Could not save description" : "No se pudo guardar la descripción",
"Description" : "Descripción",
"(Unsaved)" : "(Sin salvar)",
"(Saving…)" : "(Guardando...)",
@@ -259,12 +273,12 @@ OC.L10N.register(
"Set due date for this weekend" : "Establecer este fin de semana como fecha de vencimiento",
"Next week {timeLocale}" : "Próxima semana {timeLocale}",
"Set due date for next week" : "Establecer la próxima semana como fecha de vencimiento",
"Assign a due date to this card…" : "Asignar una fecha de caducidad a esta tarjeta…",
"Assign a due date to this card…" : "Asignar una fecha de vencimiento a esta tarjeta…",
"Set a due date" : "Fijar una fecha límite",
"Add due date" : "Añadir fecha de vencimiento",
"Choose a date" : "Elija una fecha",
"Remove due date" : "Eliminar fecha límite",
"Mark as done" : "Marcar como hecho",
"Mark as done" : "Marcar como completado",
"Due at:" : "Vence el:",
"Not done" : "No está finalizado",
"Unarchive card" : "Desarchivar tarjeta",
@@ -328,6 +342,7 @@ OC.L10N.register(
"An error occurred" : "Ocurrió un error",
"Are you sure you want to delete the board {title}? This will delete all the data of this board including archived cards." : "¿Está seguro de querer eliminar el tablero {title}? Esto eliminará todos los datos del tablero incluyendo las tarjetas archivadas.",
"Delete the board?" : "¿Borrar el tablero?",
"Exporting board..." : "Exportando tablero...",
"Board details" : "Detalles del tablero",
"Edit board" : "Editar tablero",
"Clone board" : "Clonar tablero",
@@ -340,16 +355,22 @@ OC.L10N.register(
"Assigned cards" : "Tarjetas asignadas",
"No notifications" : "No hay notificaciones",
"Delete board" : "Eliminar tablero",
"Importing board..." : "Importando tablero...",
"Board imported successfully" : "Se importó el tablero exitosamente",
"Import board" : "Importar tablero",
"Clone {boardTitle}" : "Clonar {boardTitle}",
"Clone cards" : "Clonar tarjetas",
"Clone assignments" : "Clonar asignaciones",
"Clone labels" : "Clonar etiquetas",
"Clone due dates" : "Clonar fechas límite",
"Clone due dates" : "Clonar fechas de vencimiento",
"Advanced options" : "Opciones avanzadas",
"Move all cards to the first list" : "Mover todas las tarjetas a la primera lista",
"Restore archived cards" : "Restaurar tarjetas archivadas",
"Clone" : "Clonar",
"Export {boardTitle}" : "Exportar {boardTitle}",
"Export as JSON" : "Exportar como JSON",
"Export as CSV" : "Exportar como CSV",
"Note: Only the JSON format is supported for importing back into the Deck app." : "Nota: Solo el formato JSON es soportar al importar de vuelta en la app Deck.",
"Export" : "Exportar",
"Loading filtered view" : "Cargando vista filtrada",
"Today" : "Hoy",
@@ -357,17 +378,17 @@ OC.L10N.register(
"No due" : "Sin finalizar",
"Search for {searchQuery} in all boards" : "Buscar {searchQuery} en todos los tableros",
"No results found" : "No se encontraron resultados",
"Deck board {name}\n* Last modified on {lastMod}" : "Tablero Deck {name}\n* Última modificación en {lastMod}",
"* Created on {created}\n* Last modified on {lastMod}\n* {nbAttachments} attachments\n* {nbComments} comments" : "* Creada en {created}\n* Ultima moficiación en {lastMod}\n* {nbAttachments} adjuntos\n* {nbComments} comentarios",
"Deck board {name}\n* Last modified on {lastMod}" : "Tablero Deck {name}\n* Se modificó por última vez el {lastMod}",
"* Created on {created}\n* Last modified on {lastMod}\n* {nbAttachments} attachments\n* {nbComments} comments" : "* Creado en {created}\n* Se modificó por última vez el {lastMod}\n* {nbAttachments} adjuntos\n* {nbComments} comentarios",
"{nbCards} cards" : "{nbCards} tarjetas",
"Due on {date}" : "Vence en {date}",
"{stack} in {board}" : "{stack} en {board}",
"Click to expand description" : "Pulse para expandir la descripción",
"Click to expand comment" : "Pulse para expandir el comentario",
"Click to expand description" : "Haga clic para expandir la descripción",
"Click to expand comment" : "Haga clic para expandir el comentario",
"Create card" : "Crear tarjeta",
"Create a new card" : "Crear una nueva tarjeta",
"Create a new card" : "Crear una tarjeta nueva",
"Card title" : "Título de la tarjeta",
"Creating the new card …" : "Creando una nueva tarjeta …",
"Creating the new card …" : "Creando una tarjeta nueva …",
"Card \"{card}\" was added to \"{board}\"" : "La tarjeta \"{card}\" fue añadida a \"{board}\"",
"Open card" : "Abrir tarjeta",
"Close" : "Cerrar",
@@ -383,7 +404,8 @@ OC.L10N.register(
"Something went wrong" : "Algo ha ido mal",
"Failed to upload {name}" : "Error al subir {name}",
"Maximum file size of {size} exceeded" : "Tamaño máximo de archivo de {size} excedido",
"Due date" : "Fecha de fin",
"Assigned users" : "Usuarios asignados",
"Due date" : "Fecha de vencimiento",
"Error creating the share" : "Error creando el recurso compartido",
"Share with a Deck card" : "Compartir con una tarjeta de Deck",
"Share {file} with a Deck card" : "Compartir {file} con una tarjeta de Deck",

View File

@@ -35,9 +35,9 @@
"{user} has archived card {card} in list {stack} on board {board}" : "{user} ha archivado la tarjeta {card} en la lista {stack} del tablero {board}",
"You have unarchived card {card} in list {stack} on board {board}" : "Has desarchivado la tarjeta {card} en la lista {stack} del tablero {board}",
"{user} has unarchived card {card} in list {stack} on board {board}" : "{user} ha desarchivado la tarjeta {card} en la lista {stack} del tablero {board}",
"You have marked the card {card} as done in list {stack} on board {board}" : "Has marcado la tarjeta {card} como completada en la lista {stack} del tablero {board}",
"You have marked the card {card} as done in list {stack} on board {board}" : "Ud. ha marcado la tarjeta {card} como completada en la lista {stack} del tablero {board}",
"{user} has marked card {card} as done in list {stack} on board {board}" : "{user} ha marcado la tarjeta {card} como completada en la lista {stack} del tablero {board}",
"You have marked the card {card} as undone in list {stack} on board {board}" : "Has marcado la tarjeta {card} como no completada en la lista {stack} del tablero {board}",
"You have marked the card {card} as undone in list {stack} on board {board}" : "Ud. ha marcado la tarjeta {card} como no completada en la lista {stack} del tablero {board}",
"{user} has marked the card {card} as undone in list {stack} on board {board}" : "{user} ha marcado la tarjeta {card} como no completada en la lista {stack} del tablero {board}",
"You have removed the due date of card {card}" : "Has eliminado la fecha de vencimiento de {card}",
"{user} has removed the due date of card {card}" : "{user} ha eliminado la fecha de vencimiento de {card}",
@@ -79,10 +79,14 @@
"Could not write file to disk" : "No se ha podido escribir el archivo al disco",
"A PHP extension stopped the file upload" : "Una extensión de PHP ha detenido la subida del archivo",
"No file uploaded or file size exceeds maximum of %s" : "No se ha subido ningún archivo, o el tamaño del archivo excede el máximo de %s",
"Invalid file type. Only JSON files are allowed." : "Tipo de archivo inválido. Solo se permiten archivos JSON",
"Invalid JSON data" : "Datos JSON inválidos",
"Failed to import board" : "Fallo al importar tablero",
"Cards due today" : "Tarjetas que vencen hoy",
"Cards due tomorrow" : "Tarjetas que vencen mañana",
"Upcoming cards" : "Próximas tarjetas",
"Load more" : "Cargar más",
"Welcome to Nextcloud Deck!" : "¡Bienvenido a Nextcloud Deck!",
"The card \"%s\" on \"%s\" has been assigned to you by %s." : "La tarjeta \"%s\" en \"%s\" te ha sido asignada por %s.",
"{user} has assigned the card {deck-card} on {deck-board} to you." : "{user} te ha asigando la tarjeta {deck-card} de {deck-board} a ti.",
"The card \"%s\" on \"%s\" has reached its due date." : "La tarjeta \"%s\" en \"%s\" ha alcanzado su fecha límite.",
@@ -92,7 +96,7 @@
"The board \"%s\" has been shared with you by %s." : "El tablero \"%s\" ha sido compartido contigo por %s.",
"{user} has shared {deck-board} with you." : "{user} ha compartido {deck-board} contigo.",
"Deck board" : "Tablero Deck",
"Owned by %1$s" : "Apropiado por %1$s",
"Owned by %1$s" : "Propiedad de %1$s",
"Deck boards, cards and comments" : "Tableros Deck, tarjetas y comentarios",
"From %1$s, in %2$s/%3$s, owned by %4$s" : "De %1$s, en %2$s/%3$s, propiedad de %4$s",
"Create a new deck card" : "Crear una nueva tarjeta de tablero",
@@ -105,17 +109,25 @@
"Action needed" : "Acción necesaria",
"Later" : "Después",
"copy" : "copiar",
"Read more inside" : "Lea más, adentro",
"Custom lists - click to rename!" : "Listas personalizadas - ¡Haga clic para renombrar!",
"To Do" : "Por hacer",
"In Progress" : "En progreso",
"Done" : "Hecho",
"This comment has more than %s characters.\nAdded as an attachment to the card with name %s.\nAccessible on URL: %s." : "Este comentario tiene más de %s caracteres.\nAñadido como adjunto a la tarjeta con el nombre %s.\nAccesible en la URL: %s.",
"1. Open to learn more about boards and cards" : "1. Abra aquí para aprender más sobre los tableros y las tarjetas",
"2. Drag cards left and right, up and down" : "2. Arrastre las tarjetas a la izquierda y derecha, arriba y abajo",
"3. Apply rich formatting and link content" : "3. Aplique formato enriquecido y contenido a los enlaces",
"4. Share, comment and collaborate!" : "4. ¡Comparta, comente y colabore!",
"Create your first card!" : "¡Cree su primera tarjeta!",
"This comment has more than %s characters.\nAdded as an attachment to the card with name %s.\nAccessible on URL: %s." : "Este comentario tiene más de %s caracteres.\nSe ha añadido como adjunto a la tarjeta con el nombre %s.\nAccesible en la URL: %s.",
"Attachments" : "Adjuntos",
"File" : "Archivo",
"date" : "fecha",
"Card not found" : "Tarjeta no encontrada",
"Path is already shared with this card" : "La ruta ya se ha compartido con esta tarjeta",
"Invalid date, date format must be YYYY-MM-DD" : "Fecha no válida, el formato de las fechas debe ser AAAA-MM-DD",
"Personal planning and team project organization" : "Planificación personal y organización de proyecto de equipo",
"Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deck es una herramienta de organización de estilo kanban dirigida a la planificación personal y la organización de proyectos para equipos integrados con Nextcloud.\n\n\n- 📥 Agrega tus tareas a las tarjetas y ordénalas.\n- 📄 Escriba notas adicionales\n- 🔖 Asignar etiquetas para una organización mejor\n- 👥 Comparte con tu equipo, amigos o familia.\n- 📎 Adjuntar archivos e incrustarlos en su descripción\n- 💬 Discuta con su equipo usando comentarios.\n- ⚡ Mantenga un registro de los cambios en el flujo de actividad\n- 🚀 Organiza tu proyecto",
"Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deck es una herramienta de organización de estilo kanban dirigida a la planificación personal y la organización de proyectos para equipos, integrada a Nextcloud.\n\n\n- 📥 Agregue sus tareas a las tarjetas y póngalas en orden.\n- 📄 Escriba notas adicionales en Markdown\n- 🔖 Asigne etiquetas para una organización mejor\n- 👥 Comparta con su equipo, amigos o familia.\n- 📎 Adjunte archivos e incruste los mismos en su descripción Markdown\n- 💬 Discuta con su equipo usando comentarios.\n- ⚡ Mantenga un registro de los cambios en el flujo de actividad\n- 🚀 Organice su proyecto",
"Add board" : "Añadir tablero",
"Card details" : "Detalles de la tarjeta",
"Select the board to link to a project" : "Selecciona el tablero que enlazar a un proyecto",
@@ -163,8 +175,8 @@
"Hide archived cards" : "Ocultar tarjetas archivadas",
"Show archived cards" : "Mostrar tarjetas archivadas",
"Toggle compact mode" : "Mostrar/ocultar modo compacto",
"Hide card cover images" : "Ocultar la imagen principal de las tarjetas",
"Show card cover images" : "Mostrar la imagen principal de las tarjetas",
"Hide card cover images" : "Ocultar la imagen de portada de las tarjetas",
"Show card cover images" : "Mostrar la imagen de portada de las tarjetas",
"Open details" : "Abrir detalles",
"Details" : "Detalles",
"Currently present people" : "Personas presentes actualmente",
@@ -179,11 +191,11 @@
"Undo" : "Deshacer",
"Deleted cards" : "Cartas eliminadas",
"Failed to create share with {displayName}" : "Fallo al crear el recurso compartido denominado {displayName}",
"Are you sure you want to transfer the board {title} to {user}?" : "¿Estás seguro de que quieres transferir el tablero {título} a {usuario}?",
"Transfer the board." : "Transfiere el tablero.",
"Are you sure you want to transfer the board {title} to {user}?" : "¿Está seguro de que quiere transferir el tablero {title} a {user}?",
"Transfer the board." : "Transfiera el tablero.",
"Transfer" : "Transferir",
"The board has been transferred to {user}" : "El tablero ha sido transferido a {usuario}",
"Failed to transfer the board to {user}" : "Failed to transfer the board to {user}",
"The board has been transferred to {user}" : "El tablero ha sido transferido a {user}",
"Failed to transfer the board to {user}" : "Fallo al transferir el tablero a {user}",
"Share board with a user, group or team …" : "Compartir tablero con un usuario, grupo o equipo …",
"Searching for users, groups and teams …" : "Buscando usuarios, grupos y equipos …",
"No participants found" : "No se encontraron participantes",
@@ -216,7 +228,7 @@
"Invalid path selected" : "Ruta seleccionada no válida",
"Upload new files" : "Subir nuevos archivos",
"Share from Files" : "Compartir desde Archivos",
"Pending share" : "Pendiente de compartir",
"Pending share" : "Recurso compartido pendiente",
"Add this attachment" : "Añadir este adjunto",
"Show in Files" : "Mostrar en Archivos",
"Download" : "Descargar",
@@ -226,6 +238,7 @@
"Modified" : "Modificado",
"Created" : "Creado",
"The title cannot be empty." : "El título no puede estar vacío.",
"Cannot close unsaved card!" : "¡No se puede cerrar esta tarjeta no guardada!",
"Open in sidebar view" : "Abrir en vista de barra lateral",
"Open in bigger view" : "Abrir en vista más grande",
"Comments" : "Comentarios",
@@ -240,6 +253,7 @@
"Reply" : "Responder",
"Update" : "Actualizar",
"Write a description …" : "Escribe una descripción...",
"Could not save description" : "No se pudo guardar la descripción",
"Description" : "Descripción",
"(Unsaved)" : "(Sin salvar)",
"(Saving…)" : "(Guardando...)",
@@ -257,12 +271,12 @@
"Set due date for this weekend" : "Establecer este fin de semana como fecha de vencimiento",
"Next week {timeLocale}" : "Próxima semana {timeLocale}",
"Set due date for next week" : "Establecer la próxima semana como fecha de vencimiento",
"Assign a due date to this card…" : "Asignar una fecha de caducidad a esta tarjeta…",
"Assign a due date to this card…" : "Asignar una fecha de vencimiento a esta tarjeta…",
"Set a due date" : "Fijar una fecha límite",
"Add due date" : "Añadir fecha de vencimiento",
"Choose a date" : "Elija una fecha",
"Remove due date" : "Eliminar fecha límite",
"Mark as done" : "Marcar como hecho",
"Mark as done" : "Marcar como completado",
"Due at:" : "Vence el:",
"Not done" : "No está finalizado",
"Unarchive card" : "Desarchivar tarjeta",
@@ -326,6 +340,7 @@
"An error occurred" : "Ocurrió un error",
"Are you sure you want to delete the board {title}? This will delete all the data of this board including archived cards." : "¿Está seguro de querer eliminar el tablero {title}? Esto eliminará todos los datos del tablero incluyendo las tarjetas archivadas.",
"Delete the board?" : "¿Borrar el tablero?",
"Exporting board..." : "Exportando tablero...",
"Board details" : "Detalles del tablero",
"Edit board" : "Editar tablero",
"Clone board" : "Clonar tablero",
@@ -338,16 +353,22 @@
"Assigned cards" : "Tarjetas asignadas",
"No notifications" : "No hay notificaciones",
"Delete board" : "Eliminar tablero",
"Importing board..." : "Importando tablero...",
"Board imported successfully" : "Se importó el tablero exitosamente",
"Import board" : "Importar tablero",
"Clone {boardTitle}" : "Clonar {boardTitle}",
"Clone cards" : "Clonar tarjetas",
"Clone assignments" : "Clonar asignaciones",
"Clone labels" : "Clonar etiquetas",
"Clone due dates" : "Clonar fechas límite",
"Clone due dates" : "Clonar fechas de vencimiento",
"Advanced options" : "Opciones avanzadas",
"Move all cards to the first list" : "Mover todas las tarjetas a la primera lista",
"Restore archived cards" : "Restaurar tarjetas archivadas",
"Clone" : "Clonar",
"Export {boardTitle}" : "Exportar {boardTitle}",
"Export as JSON" : "Exportar como JSON",
"Export as CSV" : "Exportar como CSV",
"Note: Only the JSON format is supported for importing back into the Deck app." : "Nota: Solo el formato JSON es soportar al importar de vuelta en la app Deck.",
"Export" : "Exportar",
"Loading filtered view" : "Cargando vista filtrada",
"Today" : "Hoy",
@@ -355,17 +376,17 @@
"No due" : "Sin finalizar",
"Search for {searchQuery} in all boards" : "Buscar {searchQuery} en todos los tableros",
"No results found" : "No se encontraron resultados",
"Deck board {name}\n* Last modified on {lastMod}" : "Tablero Deck {name}\n* Última modificación en {lastMod}",
"* Created on {created}\n* Last modified on {lastMod}\n* {nbAttachments} attachments\n* {nbComments} comments" : "* Creada en {created}\n* Ultima moficiación en {lastMod}\n* {nbAttachments} adjuntos\n* {nbComments} comentarios",
"Deck board {name}\n* Last modified on {lastMod}" : "Tablero Deck {name}\n* Se modificó por última vez el {lastMod}",
"* Created on {created}\n* Last modified on {lastMod}\n* {nbAttachments} attachments\n* {nbComments} comments" : "* Creado en {created}\n* Se modificó por última vez el {lastMod}\n* {nbAttachments} adjuntos\n* {nbComments} comentarios",
"{nbCards} cards" : "{nbCards} tarjetas",
"Due on {date}" : "Vence en {date}",
"{stack} in {board}" : "{stack} en {board}",
"Click to expand description" : "Pulse para expandir la descripción",
"Click to expand comment" : "Pulse para expandir el comentario",
"Click to expand description" : "Haga clic para expandir la descripción",
"Click to expand comment" : "Haga clic para expandir el comentario",
"Create card" : "Crear tarjeta",
"Create a new card" : "Crear una nueva tarjeta",
"Create a new card" : "Crear una tarjeta nueva",
"Card title" : "Título de la tarjeta",
"Creating the new card …" : "Creando una nueva tarjeta …",
"Creating the new card …" : "Creando una tarjeta nueva …",
"Card \"{card}\" was added to \"{board}\"" : "La tarjeta \"{card}\" fue añadida a \"{board}\"",
"Open card" : "Abrir tarjeta",
"Close" : "Cerrar",
@@ -381,7 +402,8 @@
"Something went wrong" : "Algo ha ido mal",
"Failed to upload {name}" : "Error al subir {name}",
"Maximum file size of {size} exceeded" : "Tamaño máximo de archivo de {size} excedido",
"Due date" : "Fecha de fin",
"Assigned users" : "Usuarios asignados",
"Due date" : "Fecha de vencimiento",
"Error creating the share" : "Error creando el recurso compartido",
"Share with a Deck card" : "Compartir con una tarjeta de Deck",
"Share {file} with a Deck card" : "Compartir {file} con una tarjeta de Deck",

View File

@@ -33,6 +33,7 @@ OC.L10N.register(
"Tags" : "Etiquetas",
"Activity" : "Actividad",
"Undo" : "Deshacer",
"Transfer" : "Transferencia",
"Can edit" : "Puede editar",
"Can share" : "Puede compartir",
"Owner" : "Dueño",
@@ -58,6 +59,7 @@ OC.L10N.register(
"Search" : "Buscar",
"Archived boards" : "Tableros archivados",
"Shared with you" : "Compartido con usted",
"Cancel edit" : "Cancelar edición",
"Board details" : "Detalles del tablero",
"Edit board" : "Editar el tablero",
"Unarchive board" : "Desarchivar tablero",

View File

@@ -31,6 +31,7 @@
"Tags" : "Etiquetas",
"Activity" : "Actividad",
"Undo" : "Deshacer",
"Transfer" : "Transferencia",
"Can edit" : "Puede editar",
"Can share" : "Puede compartir",
"Owner" : "Dueño",
@@ -56,6 +57,7 @@
"Search" : "Buscar",
"Archived boards" : "Tableros archivados",
"Shared with you" : "Compartido con usted",
"Cancel edit" : "Cancelar edición",
"Board details" : "Detalles del tablero",
"Edit board" : "Editar el tablero",
"Unarchive board" : "Desarchivar tablero",

View File

@@ -274,6 +274,7 @@ OC.L10N.register(
"{count} comments, {unread} unread" : "コメント {count} 件あり、 {unread} 件未読",
"Todo items" : "Todo項目",
"Edit card title" : "カードタイトルを編集する",
"Open link" : "リンクを開く",
"Card deleted" : "カードが削除されました",
"Edit title" : "タイトルを編集",
"Assign to me" : "自分に割り当てる",

View File

@@ -272,6 +272,7 @@
"{count} comments, {unread} unread" : "コメント {count} 件あり、 {unread} 件未読",
"Todo items" : "Todo項目",
"Edit card title" : "カードタイトルを編集する",
"Open link" : "リンクを開く",
"Card deleted" : "カードが削除されました",
"Edit title" : "タイトルを編集",
"Assign to me" : "自分に割り当てる",

View File

@@ -65,6 +65,7 @@ OC.L10N.register(
"Description" : "Apraksts",
"Select Date" : "Izvēlieties datumu",
"Later today {timeLocale}" : "Vēlāk šodien {timeLocale}",
"Set due date for later today" : "Iestatīt beigu datumu vēlāk šodienā",
"(group)" : "(grupa)",
"Open link" : "Atvērt saiti",
"seconds ago" : "pirms vairākām sekundēm",
@@ -80,6 +81,8 @@ OC.L10N.register(
"Export" : "Izgūt",
"Today" : "Šodien",
"Tomorrow" : "Rīt",
"Deck board {name}\n* Last modified on {lastMod}" : "Kavas dēlis {name}\n* Pēdējoreiz izmainīts {lastMod}",
"* Created on {created}\n* Last modified on {lastMod}\n* {nbAttachments} attachments\n* {nbComments} comments" : "* Izveidots {created}\n* Pēdējoreiz izmainīts {lastMod}\n* {nbAttachments} pielikumi\n* {nbComments} piebildes",
"Close" : "Aizvērt",
"Due date" : "Izpildes datums",
"Share" : "Koplietot",

View File

@@ -63,6 +63,7 @@
"Description" : "Apraksts",
"Select Date" : "Izvēlieties datumu",
"Later today {timeLocale}" : "Vēlāk šodien {timeLocale}",
"Set due date for later today" : "Iestatīt beigu datumu vēlāk šodienā",
"(group)" : "(grupa)",
"Open link" : "Atvērt saiti",
"seconds ago" : "pirms vairākām sekundēm",
@@ -78,6 +79,8 @@
"Export" : "Izgūt",
"Today" : "Šodien",
"Tomorrow" : "Rīt",
"Deck board {name}\n* Last modified on {lastMod}" : "Kavas dēlis {name}\n* Pēdējoreiz izmainīts {lastMod}",
"* Created on {created}\n* Last modified on {lastMod}\n* {nbAttachments} attachments\n* {nbComments} comments" : "* Izveidots {created}\n* Pēdējoreiz izmainīts {lastMod}\n* {nbAttachments} pielikumi\n* {nbComments} piebildes",
"Close" : "Aizvērt",
"Due date" : "Izpildes datums",
"Share" : "Koplietot",

View File

@@ -266,6 +266,7 @@ OC.L10N.register(
"{count} comments, {unread} unread" : "Komentarze: {count}, nieprzeczytane: {unread}",
"Todo items" : "Do zrobienia",
"Edit card title" : "Edytuj nazwę karty",
"Open link" : "Otwórz link",
"Card deleted" : "Karta usunięta",
"Edit title" : "Edytuj tytuł",
"Assign to me" : "Przydziel do mnie",
@@ -312,6 +313,7 @@ OC.L10N.register(
"Clone cards" : "Klonuj karty",
"Advanced options" : "Opcje zaawansowane",
"Clone" : "Klonuj",
"Export {boardTitle}" : "Eksportuj {boardTitle}",
"Export" : "Eksportuj",
"Loading filtered view" : "Wczytywanie przefiltrowanego widoku",
"Today" : "Dzisiaj",

View File

@@ -264,6 +264,7 @@
"{count} comments, {unread} unread" : "Komentarze: {count}, nieprzeczytane: {unread}",
"Todo items" : "Do zrobienia",
"Edit card title" : "Edytuj nazwę karty",
"Open link" : "Otwórz link",
"Card deleted" : "Karta usunięta",
"Edit title" : "Edytuj tytuł",
"Assign to me" : "Przydziel do mnie",
@@ -310,6 +311,7 @@
"Clone cards" : "Klonuj karty",
"Advanced options" : "Opcje zaawansowane",
"Clone" : "Klonuj",
"Export {boardTitle}" : "Eksportuj {boardTitle}",
"Export" : "Eksportuj",
"Loading filtered view" : "Wczytywanie przefiltrowanego widoku",
"Today" : "Dzisiaj",

View File

@@ -274,6 +274,7 @@ OC.L10N.register(
"{count} comments, {unread} unread" : "{count} комментариев, {unread} непрочитано",
"Todo items" : "Элементы списка задач",
"Edit card title" : "Изменить заголовок карточки",
"Open link" : "Открыть ссылку",
"Card deleted" : "Карточка удалена",
"Edit title" : "Редактировать заголовок",
"Assign to me" : "Назначить себе",

View File

@@ -272,6 +272,7 @@
"{count} comments, {unread} unread" : "{count} комментариев, {unread} непрочитано",
"Todo items" : "Элементы списка задач",
"Edit card title" : "Изменить заголовок карточки",
"Open link" : "Открыть ссылку",
"Card deleted" : "Карточка удалена",
"Edit title" : "Редактировать заголовок",
"Assign to me" : "Назначить себе",

View File

@@ -124,6 +124,7 @@ OC.L10N.register(
"This comment has more than %s characters.\nAdded as an attachment to the card with name %s.\nAccessible on URL: %s." : "Овај коментар има више од %s карактера.\nДодат је као прилог картици под именом %s.\nДоступно је на URL адреси: %s.",
"Attachments" : "Прилози",
"File" : "Фајл",
"date" : "датум",
"Card not found" : "Картица није нађена",
"Path is already shared with this card" : "Путања се већ дели са овом картицом",
"Invalid date, date format must be YYYY-MM-DD" : "Неисправан датум, формат датума мора бити ГГГГ-ММ-ДД",
@@ -239,6 +240,7 @@ OC.L10N.register(
"Modified" : "Измењен",
"Created" : "Направљен",
"The title cannot be empty." : "Наслов не може бити празан.",
"Cannot close unsaved card!" : "Не може да се затвори несачувана картица!",
"Open in sidebar view" : "Отвори у бочном прегледу",
"Open in bigger view" : "Отвори на већем приказу",
"Comments" : "Коментари",
@@ -253,6 +255,7 @@ OC.L10N.register(
"Reply" : "Одговори",
"Update" : "Ажурирај",
"Write a description …" : "Напишите опис ...",
"Could not save description" : "Не може да се сачува опис",
"Description" : "Опис",
"(Unsaved)" : "(несачуван)",
"(Saving…)" : "(чувам…)",

View File

@@ -122,6 +122,7 @@
"This comment has more than %s characters.\nAdded as an attachment to the card with name %s.\nAccessible on URL: %s." : "Овај коментар има више од %s карактера.\nДодат је као прилог картици под именом %s.\nДоступно је на URL адреси: %s.",
"Attachments" : "Прилози",
"File" : "Фајл",
"date" : "датум",
"Card not found" : "Картица није нађена",
"Path is already shared with this card" : "Путања се већ дели са овом картицом",
"Invalid date, date format must be YYYY-MM-DD" : "Неисправан датум, формат датума мора бити ГГГГ-ММ-ДД",
@@ -237,6 +238,7 @@
"Modified" : "Измењен",
"Created" : "Направљен",
"The title cannot be empty." : "Наслов не може бити празан.",
"Cannot close unsaved card!" : "Не може да се затвори несачувана картица!",
"Open in sidebar view" : "Отвори у бочном прегледу",
"Open in bigger view" : "Отвори на већем приказу",
"Comments" : "Коментари",
@@ -251,6 +253,7 @@
"Reply" : "Одговори",
"Update" : "Ажурирај",
"Write a description …" : "Напишите опис ...",
"Could not save description" : "Не може да се сачува опис",
"Description" : "Опис",
"(Unsaved)" : "(несачуван)",
"(Saving…)" : "(чувам…)",

View File

@@ -240,6 +240,7 @@ OC.L10N.register(
"Modified" : "Değiştirilme",
"Created" : "Oluşturulma",
"The title cannot be empty." : "Başlık boş olamaz.",
"Cannot close unsaved card!" : "Kaydedilmemiş bir kart kapatılamaz!",
"Open in sidebar view" : "Kenar çubuğu görünümünde aç",
"Open in bigger view" : "Daha büyük görünümde aç",
"Comments" : "Yorumlar",
@@ -254,6 +255,7 @@ OC.L10N.register(
"Reply" : "Yanıtla",
"Update" : "Güncelle",
"Write a description …" : "Bir açıklama yazın …",
"Could not save description" : "Açıklama kaydedilemedi",
"Description" : "Açıklama",
"(Unsaved)" : "(Kaydedilmemiş)",
"(Saving…)" : "(Kaydediliyor…)",

View File

@@ -238,6 +238,7 @@
"Modified" : "Değiştirilme",
"Created" : "Oluşturulma",
"The title cannot be empty." : "Başlık boş olamaz.",
"Cannot close unsaved card!" : "Kaydedilmemiş bir kart kapatılamaz!",
"Open in sidebar view" : "Kenar çubuğu görünümünde aç",
"Open in bigger view" : "Daha büyük görünümde aç",
"Comments" : "Yorumlar",
@@ -252,6 +253,7 @@
"Reply" : "Yanıtla",
"Update" : "Güncelle",
"Write a description …" : "Bir açıklama yazın …",
"Could not save description" : "Açıklama kaydedilemedi",
"Description" : "Açıklama",
"(Unsaved)" : "(Kaydedilmemiş)",
"(Saving…)" : "(Kaydediliyor…)",

View File

@@ -48,8 +48,30 @@ OC.L10N.register(
"You have updated the due date of card {card} to {after}" : "Ви оновили дату завершення картки {card} на {after}",
"{user} has updated the due date of card {card} to {after}" : "{user} оновив(-ла) дату завершення картки {card} на {after}",
"You have added the tag {label} to card {card} in list {stack} on board {board}" : "Ви додали мітку {label} до картки {card} в списку {board}",
"{user} has added the tag {label} to card {card} in list {stack} on board {board}" : "{user} додав тег {label} до карти {card} у списку {stack} на борту {board}",
"You have removed the tag {label} from card {card} in list {stack} on board {board}" : "Ви видалили тег {label} з карти {card} у списку {stack} на борту {board}",
"{user} has removed the tag {label} from card {card} in list {stack} on board {board}" : "{user} видалив тег {label} з карти {card} у списку {stack} на борту {board}",
"You have assigned {assigneduser} to card {card} on board {board}" : "Ви призначили {assigneduser} на картку {card} на борту {board}",
"{user} has assigned {assigneduser} to card {card} on board {board}" : "{user} призначив {assigneduser} на картку {card} на дошці {board}",
"You have unassigned {assigneduser} from card {card} on board {board}" : "Ви скасували призначення {assigneduser} з карти {card} на борту {board}",
"{user} has unassigned {assigneduser} from card {card} on board {board}" : "{user} скасував призначення {assigneduser} з карти {card} на дошці {board}",
"You have moved the card {card} from list {stackBefore} to {stack}" : "Ви перемістили картку {card} зі списку {stackBefore} до {stack}",
"{user} has moved the card {card} from list {stackBefore} to {stack}" : "{user} перемістив картку {card} зі списку {stackBefore} до {stack}",
"You have added the attachment {attachment} to card {card}" : "Ви додали вкладення {attachment} до картки {card}",
"{user} has added the attachment {attachment} to card {card}" : "{user} додав вкладення {attachment} до картки {card}",
"You have updated the attachment {attachment} on card {card}" : "Ви оновили вкладення {attachment} на картці {card}",
"{user} has updated the attachment {attachment} on card {card}" : " {user}оновив вкладення {attachment} на картці {card}",
"You have deleted the attachment {attachment} from card {card}" : "Ви видалили вкладення {attachment} з картки {card}",
"{user} has deleted the attachment {attachment} from card {card}" : "{user} видалив вкладення {attachment} з картки {card}",
"You have restored the attachment {attachment} to card {card}" : "Ви відновили вкладення {attachment} до картки {card}",
"{user} has restored the attachment {attachment} to card {card}" : "{user} відновив вкладення {attachment} до картки {card}",
"You have commented on card {card}" : "Ви залишили коментар до картки {card}",
"{user} has commented on card {card}" : "{user} прокоментував картку {card}",
"Deck" : "Колода",
"Changes in the <strong>Deck app</strong>" : "Зміни у застосунку <strong>Колода</strong>",
"A <strong>board, list or card</strong> was changed" : "Змінено <strong>таблицю, список або картку</strong>",
"A <strong>comment</strong> was created on a card" : "Створено <strong>коментар</strong> на картці",
"A <strong>card description</strong> has been changed" : "Змінено <strong>опис картки</strong>",
"The file was uploaded" : "Файл завантажено",
"The uploaded file exceeds the upload_max_filesize directive in php.ini" : "Файл для завантаження перевищує параметр upload_max_filesize у php.ini",
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Розмір завантаженого файлу перевищує значення MAX_FILE_SIZE, яке було зазначено у HTML формі",
@@ -59,30 +81,66 @@ OC.L10N.register(
"Could not write file to disk" : "Неможливо записати файл на диск",
"A PHP extension stopped the file upload" : "Розширення PHP призупинило завантаження файлу",
"No file uploaded or file size exceeds maximum of %s" : "Немає завантажених файлів або розмір файлу перевищує максимум %s",
"Invalid file type. Only JSON files are allowed." : "Неправильний тип файлу. Допускаються тільки файли у форматі JSON.",
"Invalid JSON data" : "Неправильні дані JSON",
"Failed to import board" : "Не вдалося імпортувати дошку",
"Cards due today" : "Картки повинні бути оплачені сьогодні",
"Cards due tomorrow" : "Картки на завтра",
"Upcoming cards" : "Очікують на виконання",
"Load more" : "Більше",
"Welcome to Nextcloud Deck!" : "Ласкаво просимо до колоди Nextcloud!",
"The card \"%s\" on \"%s\" has been assigned to you by %s." : "Картка \"%s\" на \"%s\" була призначена вам %s.",
"{user} has assigned the card {deck-card} on {deck-board} to you." : "{user} призначив вам карту {deck-card} на {deck-board}.",
"The card \"%s\" on \"%s\" has reached its due date." : "Термін дії картки \"%s\" на \"%s\" закінчився.",
"The card {deck-card} on {deck-board} has reached its due date." : "Термін дії карти {deck-card} на {deck-board} закінчився.",
"%s has mentioned you in a comment on \"%s\"." : "%s згадав вас у коментарі до \"%s\".",
"{user} has mentioned you in a comment on {deck-card}." : "{user} згадав вас у коментарі до {deck-card}.",
"The board \"%s\" has been shared with you by %s." : "Дошку \"%s\" з вами поділився %s.",
"{user} has shared {deck-board} with you." : "{user} поділився з вами {deck-board}.",
"Deck board" : "Дошка Deck",
"Owned by %1$s" : "Належить %1$s",
"Deck boards, cards and comments" : "Дошки колод, карти та коментарі",
"From %1$s, in %2$s/%3$s, owned by %4$s" : "З %1$s, в %2$s/%3$s, у власності %4$s",
"Create a new deck card" : "Створіть нову карту колоди",
"Card comments" : "Коментарі до картки",
"%s on %s" : "%s на %s",
"Deck boards and cards" : "Колода та карти",
"No data was provided to create an attachment." : "Для створення вкладення не було надано жодних даних.",
"Finished" : "Завершено",
"To review" : "На перегляд",
"Action needed" : "Потребує дій",
"Later" : "Пізніше",
"copy" : "копіювати",
"Read more inside" : "Читайте більше всередині",
"Custom lists - click to rename!" : "Користувацькі списки - натисніть, щоб перейменувати!",
"To Do" : "Зробити",
"In Progress" : "В процесі",
"Done" : "Готово",
"1. Open to learn more about boards and cards" : "1. Відкриті, щоб дізнатися більше про дошки та картки",
"2. Drag cards left and right, up and down" : "2. Перетягування карток вліво і вправо, вгору і вниз",
"3. Apply rich formatting and link content" : "3. Застосовуйте багате форматування та посилання на вміст",
"4. Share, comment and collaborate!" : "4. Діліться, коментуйте та співпрацюйте!",
"Create your first card!" : "Створіть свою першу листівку!",
"This comment has more than %s characters.\nAdded as an attachment to the card with name %s.\nAccessible on URL: %s." : "Цей коментар містить більше %s символів.\nДодано як вкладення до картки з іменем %s.\nДоступний за URL: %s.",
"Attachments" : "Вкладення",
"File" : "Файл",
"date" : "дата",
"Card not found" : "Картку не знайдено",
"Path is already shared with this card" : "Шлях вже є спільним з цією карткою",
"Invalid date, date format must be YYYY-MM-DD" : "Недійсна дата, формат дати має бути РРРР-ММ-ДД",
"Personal planning and team project organization" : "Особисте планування та організація командних проектів",
"Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deck - це інструмент організації в стилі канбан, призначений для особистого планування та організації проектів для команд, інтегрованих з Nextcloud.\n\n\n- 📥 Додавайте свої завдання на картки та впорядковуйте їх\n- 📄 Записуйте додаткові нотатки в Markdown\n- 🔖 Призначайте мітки для ще кращої організації\n- 👥 Діліться з командою, друзями чи родиною\n- Прикріплюйте файли та вбудовуйте їх в опис Markdown\n- 💬 Обговорюйте зі своєю командою за допомогою коментарів\n- ⚡ Відстежуйте зміни в потоці активностей\n- 🚀 Організуйте свій проект",
"Add board" : "Додати дошку",
"Card details" : "Деталі картки",
"Select the board to link to a project" : "Виберіть дошку для прив'зки до проєкту",
"Search by board title" : "Шукати за назвою дошки",
"Select board" : "Вибрати дошку",
"Move/copy card" : "Картка переміщення/копіювання",
"Select a board" : "Вибрати дошку",
"No lists available" : "Списки відсутні",
"Select a list" : "Виберіть список",
"Move card" : "Пересунути картку",
"Copy card" : "Копіювальна картка",
"Select the card to link to a project" : "Виберіть картку для прив'язки до проєкту",
"Link to card" : "Прив'язати до картки",
"Select a card" : "Вибрати картку",
@@ -103,19 +161,27 @@ OC.L10N.register(
"Filter by tag" : "Відібрати за мітками",
"Filter by assigned user" : "Відібрати за призначеним користувачем",
"Unassigned" : "Скасовано призначення",
"Filter by status" : "Фільтр за статусом",
"Open and completed" : "Відкрито та завершено",
"Open" : "Відкрити",
"Completed" : "Виконано",
"Filter by due date" : "Відібрати за датою завершення",
"Overdue" : "Протерміновано",
"Next 24 hours" : "Наступні 24 години",
"Next 7 days" : "Наступні 7 днів",
"Next 30 days" : "Наступні 30 днів",
"No due date" : "Без дати завершення",
"Clear filter" : "Очистити фільтр",
"View Modes" : "Режими перегляду",
"Toggle View Modes" : "Перемикання режимів перегляду",
"Hide archived cards" : "Приховати архівні картки",
"Show archived cards" : "Показати архівні картки",
"Toggle compact mode" : "Перемкнути компактний вигляд",
"Hide card cover images" : "Приховати зображення обкладинок карток",
"Show card cover images" : "Показати зображення обкладинки картки",
"Open details" : "Показати деталі",
"Details" : "Деталі",
"Currently present people" : "Наразі присутні люди",
"Loading board" : "Завантаження дошки",
"Board not found" : "Дошку не знайдено",
"Create a new list to add cards to this board" : "Створіть список щоб додати картки на цю дошку",
@@ -126,35 +192,62 @@ OC.L10N.register(
"Deleted lists" : "Вилучені списки",
"Undo" : "Скасувати",
"Deleted cards" : "Вилучені картки",
"Failed to create share with {displayName}" : "Не вдалося створити спільний доступ з {displayName}",
"Are you sure you want to transfer the board {title} to {user}?" : "Ви впевнені, що хочете перенести дошку {title} користувачеві {user}?",
"Transfer the board." : "Перенесіть дошку.",
"Transfer" : "Передати",
"The board has been transferred to {user}" : "Дошка була передана {user}",
"Failed to transfer the board to {user}" : "Не вдалося передати дошку користувачеві {user}",
"Share board with a user, group or team …" : "Спільний доступ до дошки з користувачем, групою або командою ...",
"Searching for users, groups and teams …" : "Пошук користувачів, груп і команд ...",
"No participants found" : "Учасників не знайдено",
"Board owner" : "Власник дошки",
"(Group)" : "(група)",
"(Team)" : "(Команда)",
"Can edit" : "Може редагувати",
"Can share" : "Can share",
"Can manage" : "Може керувати",
"Owner" : "Власник",
"Delete" : "Вилучити",
"List deleted" : "Список видалено",
"Edit list title" : "Редагувати заголовок списку",
"Archive all cards" : "Архівувати всі картки",
"Unarchive all cards" : "Розархівувати всі картки",
"Delete list" : "Вилучити список",
"Archive all cards in this list" : "Архівуйте всі картки в цьому списку",
"Unarchive all cards in this list" : "Розархівувати всі картки в цьому списку",
"Add a new card" : "Додати нову картку",
"Card name" : "Назва картки",
"title and color value must be provided" : "потрібно зазначити назву та колір",
"Edit" : "Редагувати",
"Add a new tag" : "Додати нову мітку",
"Board name" : "Назва дошки",
"Members" : "Учасники",
"Assign to users/groups/team" : "Призначити користувачам/групам/команді",
"Assign a user to this card…" : "Призначити користувачеві цю картку",
"Select a user to assign to this card…" : "Виберіть користувача, якого слід призначити на цю картку...",
"File to share" : "Виберіть файл для надання доступу",
"Invalid path selected" : "Вибрано неправильний шлях",
"Upload new files" : "Додати файл",
"Share from Files" : "Відкрити Файли",
"Pending share" : "Очікувана акція",
"Add this attachment" : "Долучити вкладення",
"Show in Files" : "Показати в Файлах",
"Download" : "Звантажити",
"Remove attachment" : "Зніміть вкладення",
"Delete Attachment" : "Забрати вкладення",
"Restore Attachment" : "Відновити вкладення",
"Modified" : "Змінено",
"Created" : "Створено",
"The title cannot be empty." : "Заголовок не може бути порожнім.",
"Cannot close unsaved card!" : "Неможливо закрити незбережену картку!",
"Open in sidebar view" : "Відкрити у вигляді бічної панелі",
"Open in bigger view" : "Відкрити в більшому розмірі",
"Comments" : "Коментарі",
"Failed to load comments" : "Не вдалося завантажити коментарі",
"No comments yet. Begin the discussion!" : "Коментарів немає, почніть обговорення!",
"The comment cannot be empty." : "Коментар не може бути порожнім.",
"The comment cannot be longer than 1000 characters." : "Коментар не може бути довшим за 1000 символів.",
"Save" : "Зберегти",
"Created:" : "Створено:",
"In reply to" : "У відповідь",
@@ -162,6 +255,7 @@ OC.L10N.register(
"Reply" : "Відповісти",
"Update" : "Оновлення",
"Write a description …" : "Додайте опис ...",
"Could not save description" : "Не вдалося зберегти опис",
"Description" : "Опис",
"(Unsaved)" : "(Не збережено)",
"(Saving…)" : "(Зберігання...)",
@@ -171,73 +265,150 @@ OC.L10N.register(
"Add Attachment" : "Долучити вкладення",
"Choose attachment" : "Вибрати вкладення",
"Select Date" : "Вкажіть дату",
"Later today {timeLocale}" : "Пізніше сьогодні - {timeLocale}",
"Set due date for later today" : "Встановіть термін сплати на сьогоднішній день",
"Tomorrow {timeLocale}" : "Завтра - {timeLocale}",
"Set due date for tomorrow" : "Встановіть дедлайн на завтра",
"This weekend {timeLocale}" : "На цих вихідних - {timeLocale}",
"Set due date for this weekend" : "Встановіть термін виконання на ці вихідні",
"Next week {timeLocale}" : "Наступного тижня - {timeLocale}",
"Set due date for next week" : "Встановіть термін виконання на наступний тиждень",
"Assign a due date to this card…" : "Призначте цій картці термін оплати...",
"Set a due date" : "Встановити дату завершення",
"Add due date" : "Додати термін сплати",
"Choose a date" : "Виберіть дату",
"Remove due date" : "Вилучити до",
"Mark as done" : "Позначити як виконане",
"Due at:" : "На часі:",
"Not done" : "Ще не все.",
"Unarchive card" : "Розархівувати картку",
"Archive card" : "Архівувати картку",
"Assign a tag to this card…" : "Додати мітку до цієї картки",
"Select or create a tag…" : "Виберіть або створіть тег...",
"Create a new tag:" : "Створіть новий тег:",
"(group)" : "(група)",
"{count} comments, {unread} unread" : "{count} коментарів, {unread} непрочитаних",
"Todo items" : "Пункти завдань",
"Edit card title" : "Редагувати заголовок картки",
"Open link" : "Відкрити посилання",
"Card deleted" : "Картку видалено",
"Edit title" : "Редагувати",
"Assign to me" : "Призначити мені",
"Unassign myself" : "Зняти з себе повноваження.",
"Mark as not done" : "Позначити як не виконано",
"Delete card" : "Вилучити картку",
"seconds ago" : "секунд тому",
"Keyboard shortcuts" : "Скорочення",
"Boost your productivity using Deck with keyboard shortcuts." : "Підвищуйте свою продуктивність, використовуючи Deck за допомогою комбінацій клавіш.",
"Board actions" : "Дії правління",
"Keyboard shortcut" : "Сполучення клавіш",
"Action" : "Дія ",
"Shift" : "Shift",
"Scroll" : "Прокрутка",
"Scroll sideways" : "Прокрутіть вбік",
"Navigate between cards" : "Перехід між картками",
"Esc" : "Esc",
"Close card details" : "Закрити дані картки",
"Ctrl" : "Ctrl",
"Search" : "Пошук",
"Show card filters" : "Показати фільтри карток",
"Clear card filters" : "Очистити фільтри карток",
"Show help dialog" : "Показати діалогове вікно довідки",
"Card actions" : "Дії з карткою",
"The following actions can be triggered on the currently highlighted card" : "На поточній виділеній картці можна виконати такі дії",
"Enter" : "Ввід",
"Space" : "Простір",
"Open card details" : "Відкрити реквізити картки",
"Edit the card title" : "Відредагуйте назву картки",
"Assign yourself to the current card" : "Приєднайте себе до поточної картки",
"Archive/unarchive the current card" : "Архівувати/розархівувати поточну картку",
"Mark card as completed/not completed" : "Позначте картку як завершену/не завершену",
"Open card menu" : "Відкрити меню картки",
"All boards" : "Усі дошки",
"Archived boards" : "Архівні дошки",
"Shared with you" : "Вам надано доступ",
"Deck settings" : "Налаштування колоди",
"Use bigger card view" : "Режим перегляду зі збільшеними картками",
"Show card ID badge" : "Покажіть бейдж з ідентифікаційною карткою",
"Show boards in calendar/tasks" : "Показувати дошки в календарі та завданнях",
"Limit board creation to some groups" : "Обмежити створення дошки для деяких груп",
"Users outside of those groups will not be able to create their own boards, but will still be able to work on boards that have been shared with them." : "Користувачі поза цими групами не зможуть створювати власні дошки, але зможуть працювати на дошках, до яких їм надано спільний доступ.",
"Cancel edit" : "Скасувати редагування",
"Save board" : "Зберегти дошку",
"Board {0} deleted" : "Дошку {0} вилучено",
"All cards" : "Всі карти",
"Only assigned cards" : "Тільки призначені картки",
"No reminder" : "Відсутні нагадування",
"An error occurred" : "Виникла помилка",
"Are you sure you want to delete the board {title}? This will delete all the data of this board including archived cards." : "Ви впевнені, що хочете вилучити дошку {title}? Це призведе до видалення всіх даних цієї дошки, включно архівні картки.",
"Delete the board?" : "Вилучити дошку?",
"Exporting board..." : "Експортна дошка...",
"Board details" : "Деталі дошки",
"Edit board" : "Редагувати дошку",
"Clone board" : "Копіювати дошку",
"Unarchive board" : "Розархівувати дошку",
"Archive board" : "Архівувати дошку",
"Export board" : "Дошка експорту",
"Turn on due date reminders" : "Нагадування про термін виконання",
"Turn off due date reminders" : "Вимкнути нагадування про терміни виконання",
"Due date reminders" : "Нагадування про терміни виконання",
"Assigned cards" : "Призначені картки",
"No notifications" : "Немає сповіщень",
"Delete board" : "Вилучити дошку",
"Importing board..." : "Імпортна дошка...",
"Board imported successfully" : "Плату успішно імпортовано",
"Import board" : "Імпортна дошка",
"Clone {boardTitle}" : "Клон {boardTitle}",
"Clone cards" : "Копіювати картки",
"Clone assignments" : "Призначення клонів",
"Clone labels" : "Етикетки клонів",
"Clone due dates" : "Клонувати дві дати",
"Advanced options" : "Розширені налаштування",
"Move all cards to the first list" : "Перемістіть усі картки до першого списку",
"Restore archived cards" : "Відновлення заархівованих карток",
"Clone" : "Копіювати",
"Export {boardTitle}" : "Експорт {boardTitle}",
"Export as JSON" : "Експорт як JSON",
"Export as CSV" : "Експорт у CSV",
"Note: Only the JSON format is supported for importing back into the Deck app." : "Примітка: Для імпорту в додаток Deck підтримується лише формат JSON.",
"Export" : "Експортувати",
"Loading filtered view" : "Завантаження відфільтрованого перегляду",
"Today" : "Сьогодні",
"Tomorrow" : "Завтра",
"No due" : "Без призначеної дати",
"Search for {searchQuery} in all boards" : "Шукати {searchQuery} на всіх дошках оголошень",
"No results found" : "Не знайдено жодного результату",
"Deck board {name}\n* Last modified on {lastMod}" : "Колода {name}\n* Востаннє змінено на {lastMod}",
"* Created on {created}\n* Last modified on {lastMod}\n* {nbAttachments} attachments\n* {nbComments} comments" : "* Створено на {created}\n* Востаннє змінено на {lastMod}\n* {nbAttachments} вкладення\n* {nbComments} коментарі",
"{nbCards} cards" : "{nbCards} картки",
"Due on {date}" : "До {date}",
"{stack} in {board}" : "{stack} в {board}",
"Click to expand description" : "Натисніть, щоб розгорнути опис",
"Click to expand comment" : "Натисніть, щоб розгорнути коментар",
"Create card" : "Створити картку",
"Create a new card" : "Створити нову картку",
"Card title" : "Заголовок картки",
"Creating the new card …" : "Створення нової картки ...",
"Card \"{card}\" was added to \"{board}\"" : "Картку \"{card}\" додано до \"{board}\"",
"Open card" : "Відкрити картку",
"Close" : "Закрити",
"No upcoming cards" : "Немає майбутніх завдань",
"upcoming cards today" : "найближчі картки на сьогодні",
"upcoming cards tomorrow" : "найближчі картки завтра",
"upcoming cards" : "очікують на виконання",
"New card" : "Нова картка",
"Link to a board" : "Прив'язати до дошки",
"Link to a card" : "Прив'язати до картки",
"Create a card" : "Створити картку",
"Message from {author} in {conversationName}" : "Повідомлення від {author} у {conversationName}",
"Something went wrong" : "От халепа!",
"Failed to upload {name}" : "Не вдалося завантажити {name}",
"Maximum file size of {size} exceeded" : "Досягнуто максимальний розмір файлу {size}",
"Assigned users" : "Призначені користувачі",
"Due date" : "Дата виконання",
"Error creating the share" : "Помилка створення спільного доступу",
"Share with a Deck card" : "Поділіться з картою з колоди",
"Share {file} with a Deck card" : "Поділіться {file} з картою колоди",
"Share" : "Спільний доступ",
"Personal" : "Особисте",
"To do" : "Заплановано",

View File

@@ -46,8 +46,30 @@
"You have updated the due date of card {card} to {after}" : "Ви оновили дату завершення картки {card} на {after}",
"{user} has updated the due date of card {card} to {after}" : "{user} оновив(-ла) дату завершення картки {card} на {after}",
"You have added the tag {label} to card {card} in list {stack} on board {board}" : "Ви додали мітку {label} до картки {card} в списку {board}",
"{user} has added the tag {label} to card {card} in list {stack} on board {board}" : "{user} додав тег {label} до карти {card} у списку {stack} на борту {board}",
"You have removed the tag {label} from card {card} in list {stack} on board {board}" : "Ви видалили тег {label} з карти {card} у списку {stack} на борту {board}",
"{user} has removed the tag {label} from card {card} in list {stack} on board {board}" : "{user} видалив тег {label} з карти {card} у списку {stack} на борту {board}",
"You have assigned {assigneduser} to card {card} on board {board}" : "Ви призначили {assigneduser} на картку {card} на борту {board}",
"{user} has assigned {assigneduser} to card {card} on board {board}" : "{user} призначив {assigneduser} на картку {card} на дошці {board}",
"You have unassigned {assigneduser} from card {card} on board {board}" : "Ви скасували призначення {assigneduser} з карти {card} на борту {board}",
"{user} has unassigned {assigneduser} from card {card} on board {board}" : "{user} скасував призначення {assigneduser} з карти {card} на дошці {board}",
"You have moved the card {card} from list {stackBefore} to {stack}" : "Ви перемістили картку {card} зі списку {stackBefore} до {stack}",
"{user} has moved the card {card} from list {stackBefore} to {stack}" : "{user} перемістив картку {card} зі списку {stackBefore} до {stack}",
"You have added the attachment {attachment} to card {card}" : "Ви додали вкладення {attachment} до картки {card}",
"{user} has added the attachment {attachment} to card {card}" : "{user} додав вкладення {attachment} до картки {card}",
"You have updated the attachment {attachment} on card {card}" : "Ви оновили вкладення {attachment} на картці {card}",
"{user} has updated the attachment {attachment} on card {card}" : " {user}оновив вкладення {attachment} на картці {card}",
"You have deleted the attachment {attachment} from card {card}" : "Ви видалили вкладення {attachment} з картки {card}",
"{user} has deleted the attachment {attachment} from card {card}" : "{user} видалив вкладення {attachment} з картки {card}",
"You have restored the attachment {attachment} to card {card}" : "Ви відновили вкладення {attachment} до картки {card}",
"{user} has restored the attachment {attachment} to card {card}" : "{user} відновив вкладення {attachment} до картки {card}",
"You have commented on card {card}" : "Ви залишили коментар до картки {card}",
"{user} has commented on card {card}" : "{user} прокоментував картку {card}",
"Deck" : "Колода",
"Changes in the <strong>Deck app</strong>" : "Зміни у застосунку <strong>Колода</strong>",
"A <strong>board, list or card</strong> was changed" : "Змінено <strong>таблицю, список або картку</strong>",
"A <strong>comment</strong> was created on a card" : "Створено <strong>коментар</strong> на картці",
"A <strong>card description</strong> has been changed" : "Змінено <strong>опис картки</strong>",
"The file was uploaded" : "Файл завантажено",
"The uploaded file exceeds the upload_max_filesize directive in php.ini" : "Файл для завантаження перевищує параметр upload_max_filesize у php.ini",
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Розмір завантаженого файлу перевищує значення MAX_FILE_SIZE, яке було зазначено у HTML формі",
@@ -57,30 +79,66 @@
"Could not write file to disk" : "Неможливо записати файл на диск",
"A PHP extension stopped the file upload" : "Розширення PHP призупинило завантаження файлу",
"No file uploaded or file size exceeds maximum of %s" : "Немає завантажених файлів або розмір файлу перевищує максимум %s",
"Invalid file type. Only JSON files are allowed." : "Неправильний тип файлу. Допускаються тільки файли у форматі JSON.",
"Invalid JSON data" : "Неправильні дані JSON",
"Failed to import board" : "Не вдалося імпортувати дошку",
"Cards due today" : "Картки повинні бути оплачені сьогодні",
"Cards due tomorrow" : "Картки на завтра",
"Upcoming cards" : "Очікують на виконання",
"Load more" : "Більше",
"Welcome to Nextcloud Deck!" : "Ласкаво просимо до колоди Nextcloud!",
"The card \"%s\" on \"%s\" has been assigned to you by %s." : "Картка \"%s\" на \"%s\" була призначена вам %s.",
"{user} has assigned the card {deck-card} on {deck-board} to you." : "{user} призначив вам карту {deck-card} на {deck-board}.",
"The card \"%s\" on \"%s\" has reached its due date." : "Термін дії картки \"%s\" на \"%s\" закінчився.",
"The card {deck-card} on {deck-board} has reached its due date." : "Термін дії карти {deck-card} на {deck-board} закінчився.",
"%s has mentioned you in a comment on \"%s\"." : "%s згадав вас у коментарі до \"%s\".",
"{user} has mentioned you in a comment on {deck-card}." : "{user} згадав вас у коментарі до {deck-card}.",
"The board \"%s\" has been shared with you by %s." : "Дошку \"%s\" з вами поділився %s.",
"{user} has shared {deck-board} with you." : "{user} поділився з вами {deck-board}.",
"Deck board" : "Дошка Deck",
"Owned by %1$s" : "Належить %1$s",
"Deck boards, cards and comments" : "Дошки колод, карти та коментарі",
"From %1$s, in %2$s/%3$s, owned by %4$s" : "З %1$s, в %2$s/%3$s, у власності %4$s",
"Create a new deck card" : "Створіть нову карту колоди",
"Card comments" : "Коментарі до картки",
"%s on %s" : "%s на %s",
"Deck boards and cards" : "Колода та карти",
"No data was provided to create an attachment." : "Для створення вкладення не було надано жодних даних.",
"Finished" : "Завершено",
"To review" : "На перегляд",
"Action needed" : "Потребує дій",
"Later" : "Пізніше",
"copy" : "копіювати",
"Read more inside" : "Читайте більше всередині",
"Custom lists - click to rename!" : "Користувацькі списки - натисніть, щоб перейменувати!",
"To Do" : "Зробити",
"In Progress" : "В процесі",
"Done" : "Готово",
"1. Open to learn more about boards and cards" : "1. Відкриті, щоб дізнатися більше про дошки та картки",
"2. Drag cards left and right, up and down" : "2. Перетягування карток вліво і вправо, вгору і вниз",
"3. Apply rich formatting and link content" : "3. Застосовуйте багате форматування та посилання на вміст",
"4. Share, comment and collaborate!" : "4. Діліться, коментуйте та співпрацюйте!",
"Create your first card!" : "Створіть свою першу листівку!",
"This comment has more than %s characters.\nAdded as an attachment to the card with name %s.\nAccessible on URL: %s." : "Цей коментар містить більше %s символів.\nДодано як вкладення до картки з іменем %s.\nДоступний за URL: %s.",
"Attachments" : "Вкладення",
"File" : "Файл",
"date" : "дата",
"Card not found" : "Картку не знайдено",
"Path is already shared with this card" : "Шлях вже є спільним з цією карткою",
"Invalid date, date format must be YYYY-MM-DD" : "Недійсна дата, формат дати має бути РРРР-ММ-ДД",
"Personal planning and team project organization" : "Особисте планування та організація командних проектів",
"Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deck - це інструмент організації в стилі канбан, призначений для особистого планування та організації проектів для команд, інтегрованих з Nextcloud.\n\n\n- 📥 Додавайте свої завдання на картки та впорядковуйте їх\n- 📄 Записуйте додаткові нотатки в Markdown\n- 🔖 Призначайте мітки для ще кращої організації\n- 👥 Діліться з командою, друзями чи родиною\n- Прикріплюйте файли та вбудовуйте їх в опис Markdown\n- 💬 Обговорюйте зі своєю командою за допомогою коментарів\n- ⚡ Відстежуйте зміни в потоці активностей\n- 🚀 Організуйте свій проект",
"Add board" : "Додати дошку",
"Card details" : "Деталі картки",
"Select the board to link to a project" : "Виберіть дошку для прив'зки до проєкту",
"Search by board title" : "Шукати за назвою дошки",
"Select board" : "Вибрати дошку",
"Move/copy card" : "Картка переміщення/копіювання",
"Select a board" : "Вибрати дошку",
"No lists available" : "Списки відсутні",
"Select a list" : "Виберіть список",
"Move card" : "Пересунути картку",
"Copy card" : "Копіювальна картка",
"Select the card to link to a project" : "Виберіть картку для прив'язки до проєкту",
"Link to card" : "Прив'язати до картки",
"Select a card" : "Вибрати картку",
@@ -101,19 +159,27 @@
"Filter by tag" : "Відібрати за мітками",
"Filter by assigned user" : "Відібрати за призначеним користувачем",
"Unassigned" : "Скасовано призначення",
"Filter by status" : "Фільтр за статусом",
"Open and completed" : "Відкрито та завершено",
"Open" : "Відкрити",
"Completed" : "Виконано",
"Filter by due date" : "Відібрати за датою завершення",
"Overdue" : "Протерміновано",
"Next 24 hours" : "Наступні 24 години",
"Next 7 days" : "Наступні 7 днів",
"Next 30 days" : "Наступні 30 днів",
"No due date" : "Без дати завершення",
"Clear filter" : "Очистити фільтр",
"View Modes" : "Режими перегляду",
"Toggle View Modes" : "Перемикання режимів перегляду",
"Hide archived cards" : "Приховати архівні картки",
"Show archived cards" : "Показати архівні картки",
"Toggle compact mode" : "Перемкнути компактний вигляд",
"Hide card cover images" : "Приховати зображення обкладинок карток",
"Show card cover images" : "Показати зображення обкладинки картки",
"Open details" : "Показати деталі",
"Details" : "Деталі",
"Currently present people" : "Наразі присутні люди",
"Loading board" : "Завантаження дошки",
"Board not found" : "Дошку не знайдено",
"Create a new list to add cards to this board" : "Створіть список щоб додати картки на цю дошку",
@@ -124,35 +190,62 @@
"Deleted lists" : "Вилучені списки",
"Undo" : "Скасувати",
"Deleted cards" : "Вилучені картки",
"Failed to create share with {displayName}" : "Не вдалося створити спільний доступ з {displayName}",
"Are you sure you want to transfer the board {title} to {user}?" : "Ви впевнені, що хочете перенести дошку {title} користувачеві {user}?",
"Transfer the board." : "Перенесіть дошку.",
"Transfer" : "Передати",
"The board has been transferred to {user}" : "Дошка була передана {user}",
"Failed to transfer the board to {user}" : "Не вдалося передати дошку користувачеві {user}",
"Share board with a user, group or team …" : "Спільний доступ до дошки з користувачем, групою або командою ...",
"Searching for users, groups and teams …" : "Пошук користувачів, груп і команд ...",
"No participants found" : "Учасників не знайдено",
"Board owner" : "Власник дошки",
"(Group)" : "(група)",
"(Team)" : "(Команда)",
"Can edit" : "Може редагувати",
"Can share" : "Can share",
"Can manage" : "Може керувати",
"Owner" : "Власник",
"Delete" : "Вилучити",
"List deleted" : "Список видалено",
"Edit list title" : "Редагувати заголовок списку",
"Archive all cards" : "Архівувати всі картки",
"Unarchive all cards" : "Розархівувати всі картки",
"Delete list" : "Вилучити список",
"Archive all cards in this list" : "Архівуйте всі картки в цьому списку",
"Unarchive all cards in this list" : "Розархівувати всі картки в цьому списку",
"Add a new card" : "Додати нову картку",
"Card name" : "Назва картки",
"title and color value must be provided" : "потрібно зазначити назву та колір",
"Edit" : "Редагувати",
"Add a new tag" : "Додати нову мітку",
"Board name" : "Назва дошки",
"Members" : "Учасники",
"Assign to users/groups/team" : "Призначити користувачам/групам/команді",
"Assign a user to this card…" : "Призначити користувачеві цю картку",
"Select a user to assign to this card…" : "Виберіть користувача, якого слід призначити на цю картку...",
"File to share" : "Виберіть файл для надання доступу",
"Invalid path selected" : "Вибрано неправильний шлях",
"Upload new files" : "Додати файл",
"Share from Files" : "Відкрити Файли",
"Pending share" : "Очікувана акція",
"Add this attachment" : "Долучити вкладення",
"Show in Files" : "Показати в Файлах",
"Download" : "Звантажити",
"Remove attachment" : "Зніміть вкладення",
"Delete Attachment" : "Забрати вкладення",
"Restore Attachment" : "Відновити вкладення",
"Modified" : "Змінено",
"Created" : "Створено",
"The title cannot be empty." : "Заголовок не може бути порожнім.",
"Cannot close unsaved card!" : "Неможливо закрити незбережену картку!",
"Open in sidebar view" : "Відкрити у вигляді бічної панелі",
"Open in bigger view" : "Відкрити в більшому розмірі",
"Comments" : "Коментарі",
"Failed to load comments" : "Не вдалося завантажити коментарі",
"No comments yet. Begin the discussion!" : "Коментарів немає, почніть обговорення!",
"The comment cannot be empty." : "Коментар не може бути порожнім.",
"The comment cannot be longer than 1000 characters." : "Коментар не може бути довшим за 1000 символів.",
"Save" : "Зберегти",
"Created:" : "Створено:",
"In reply to" : "У відповідь",
@@ -160,6 +253,7 @@
"Reply" : "Відповісти",
"Update" : "Оновлення",
"Write a description …" : "Додайте опис ...",
"Could not save description" : "Не вдалося зберегти опис",
"Description" : "Опис",
"(Unsaved)" : "(Не збережено)",
"(Saving…)" : "(Зберігання...)",
@@ -169,73 +263,150 @@
"Add Attachment" : "Долучити вкладення",
"Choose attachment" : "Вибрати вкладення",
"Select Date" : "Вкажіть дату",
"Later today {timeLocale}" : "Пізніше сьогодні - {timeLocale}",
"Set due date for later today" : "Встановіть термін сплати на сьогоднішній день",
"Tomorrow {timeLocale}" : "Завтра - {timeLocale}",
"Set due date for tomorrow" : "Встановіть дедлайн на завтра",
"This weekend {timeLocale}" : "На цих вихідних - {timeLocale}",
"Set due date for this weekend" : "Встановіть термін виконання на ці вихідні",
"Next week {timeLocale}" : "Наступного тижня - {timeLocale}",
"Set due date for next week" : "Встановіть термін виконання на наступний тиждень",
"Assign a due date to this card…" : "Призначте цій картці термін оплати...",
"Set a due date" : "Встановити дату завершення",
"Add due date" : "Додати термін сплати",
"Choose a date" : "Виберіть дату",
"Remove due date" : "Вилучити до",
"Mark as done" : "Позначити як виконане",
"Due at:" : "На часі:",
"Not done" : "Ще не все.",
"Unarchive card" : "Розархівувати картку",
"Archive card" : "Архівувати картку",
"Assign a tag to this card…" : "Додати мітку до цієї картки",
"Select or create a tag…" : "Виберіть або створіть тег...",
"Create a new tag:" : "Створіть новий тег:",
"(group)" : "(група)",
"{count} comments, {unread} unread" : "{count} коментарів, {unread} непрочитаних",
"Todo items" : "Пункти завдань",
"Edit card title" : "Редагувати заголовок картки",
"Open link" : "Відкрити посилання",
"Card deleted" : "Картку видалено",
"Edit title" : "Редагувати",
"Assign to me" : "Призначити мені",
"Unassign myself" : "Зняти з себе повноваження.",
"Mark as not done" : "Позначити як не виконано",
"Delete card" : "Вилучити картку",
"seconds ago" : "секунд тому",
"Keyboard shortcuts" : "Скорочення",
"Boost your productivity using Deck with keyboard shortcuts." : "Підвищуйте свою продуктивність, використовуючи Deck за допомогою комбінацій клавіш.",
"Board actions" : "Дії правління",
"Keyboard shortcut" : "Сполучення клавіш",
"Action" : "Дія ",
"Shift" : "Shift",
"Scroll" : "Прокрутка",
"Scroll sideways" : "Прокрутіть вбік",
"Navigate between cards" : "Перехід між картками",
"Esc" : "Esc",
"Close card details" : "Закрити дані картки",
"Ctrl" : "Ctrl",
"Search" : "Пошук",
"Show card filters" : "Показати фільтри карток",
"Clear card filters" : "Очистити фільтри карток",
"Show help dialog" : "Показати діалогове вікно довідки",
"Card actions" : "Дії з карткою",
"The following actions can be triggered on the currently highlighted card" : "На поточній виділеній картці можна виконати такі дії",
"Enter" : "Ввід",
"Space" : "Простір",
"Open card details" : "Відкрити реквізити картки",
"Edit the card title" : "Відредагуйте назву картки",
"Assign yourself to the current card" : "Приєднайте себе до поточної картки",
"Archive/unarchive the current card" : "Архівувати/розархівувати поточну картку",
"Mark card as completed/not completed" : "Позначте картку як завершену/не завершену",
"Open card menu" : "Відкрити меню картки",
"All boards" : "Усі дошки",
"Archived boards" : "Архівні дошки",
"Shared with you" : "Вам надано доступ",
"Deck settings" : "Налаштування колоди",
"Use bigger card view" : "Режим перегляду зі збільшеними картками",
"Show card ID badge" : "Покажіть бейдж з ідентифікаційною карткою",
"Show boards in calendar/tasks" : "Показувати дошки в календарі та завданнях",
"Limit board creation to some groups" : "Обмежити створення дошки для деяких груп",
"Users outside of those groups will not be able to create their own boards, but will still be able to work on boards that have been shared with them." : "Користувачі поза цими групами не зможуть створювати власні дошки, але зможуть працювати на дошках, до яких їм надано спільний доступ.",
"Cancel edit" : "Скасувати редагування",
"Save board" : "Зберегти дошку",
"Board {0} deleted" : "Дошку {0} вилучено",
"All cards" : "Всі карти",
"Only assigned cards" : "Тільки призначені картки",
"No reminder" : "Відсутні нагадування",
"An error occurred" : "Виникла помилка",
"Are you sure you want to delete the board {title}? This will delete all the data of this board including archived cards." : "Ви впевнені, що хочете вилучити дошку {title}? Це призведе до видалення всіх даних цієї дошки, включно архівні картки.",
"Delete the board?" : "Вилучити дошку?",
"Exporting board..." : "Експортна дошка...",
"Board details" : "Деталі дошки",
"Edit board" : "Редагувати дошку",
"Clone board" : "Копіювати дошку",
"Unarchive board" : "Розархівувати дошку",
"Archive board" : "Архівувати дошку",
"Export board" : "Дошка експорту",
"Turn on due date reminders" : "Нагадування про термін виконання",
"Turn off due date reminders" : "Вимкнути нагадування про терміни виконання",
"Due date reminders" : "Нагадування про терміни виконання",
"Assigned cards" : "Призначені картки",
"No notifications" : "Немає сповіщень",
"Delete board" : "Вилучити дошку",
"Importing board..." : "Імпортна дошка...",
"Board imported successfully" : "Плату успішно імпортовано",
"Import board" : "Імпортна дошка",
"Clone {boardTitle}" : "Клон {boardTitle}",
"Clone cards" : "Копіювати картки",
"Clone assignments" : "Призначення клонів",
"Clone labels" : "Етикетки клонів",
"Clone due dates" : "Клонувати дві дати",
"Advanced options" : "Розширені налаштування",
"Move all cards to the first list" : "Перемістіть усі картки до першого списку",
"Restore archived cards" : "Відновлення заархівованих карток",
"Clone" : "Копіювати",
"Export {boardTitle}" : "Експорт {boardTitle}",
"Export as JSON" : "Експорт як JSON",
"Export as CSV" : "Експорт у CSV",
"Note: Only the JSON format is supported for importing back into the Deck app." : "Примітка: Для імпорту в додаток Deck підтримується лише формат JSON.",
"Export" : "Експортувати",
"Loading filtered view" : "Завантаження відфільтрованого перегляду",
"Today" : "Сьогодні",
"Tomorrow" : "Завтра",
"No due" : "Без призначеної дати",
"Search for {searchQuery} in all boards" : "Шукати {searchQuery} на всіх дошках оголошень",
"No results found" : "Не знайдено жодного результату",
"Deck board {name}\n* Last modified on {lastMod}" : "Колода {name}\n* Востаннє змінено на {lastMod}",
"* Created on {created}\n* Last modified on {lastMod}\n* {nbAttachments} attachments\n* {nbComments} comments" : "* Створено на {created}\n* Востаннє змінено на {lastMod}\n* {nbAttachments} вкладення\n* {nbComments} коментарі",
"{nbCards} cards" : "{nbCards} картки",
"Due on {date}" : "До {date}",
"{stack} in {board}" : "{stack} в {board}",
"Click to expand description" : "Натисніть, щоб розгорнути опис",
"Click to expand comment" : "Натисніть, щоб розгорнути коментар",
"Create card" : "Створити картку",
"Create a new card" : "Створити нову картку",
"Card title" : "Заголовок картки",
"Creating the new card …" : "Створення нової картки ...",
"Card \"{card}\" was added to \"{board}\"" : "Картку \"{card}\" додано до \"{board}\"",
"Open card" : "Відкрити картку",
"Close" : "Закрити",
"No upcoming cards" : "Немає майбутніх завдань",
"upcoming cards today" : "найближчі картки на сьогодні",
"upcoming cards tomorrow" : "найближчі картки завтра",
"upcoming cards" : "очікують на виконання",
"New card" : "Нова картка",
"Link to a board" : "Прив'язати до дошки",
"Link to a card" : "Прив'язати до картки",
"Create a card" : "Створити картку",
"Message from {author} in {conversationName}" : "Повідомлення від {author} у {conversationName}",
"Something went wrong" : "От халепа!",
"Failed to upload {name}" : "Не вдалося завантажити {name}",
"Maximum file size of {size} exceeded" : "Досягнуто максимальний розмір файлу {size}",
"Assigned users" : "Призначені користувачі",
"Due date" : "Дата виконання",
"Error creating the share" : "Помилка створення спільного доступу",
"Share with a Deck card" : "Поділіться з картою з колоди",
"Share {file} with a Deck card" : "Поділіться {file} з картою колоди",
"Share" : "Спільний доступ",
"Personal" : "Особисте",
"To do" : "Заплановано",

View File

@@ -20,12 +20,12 @@ OC.L10N.register(
"Card not found" : "Karta topilmadi",
"Add board" : "Doska qo'shing",
"Move card" : "Kartani ko'chirish",
"Cancel" : "Cancel",
"Cancel" : "Bekor qilish",
"Add card" : "Karta qo'shing",
"Archived cards" : "Arxivlangan kartalar",
"Add list" : "Roʻyxat qoʻshish",
"Unassigned" : "Tayinlanmagan",
"Open" : "Open",
"Open" : "Ochish",
"Overdue" : "Muddati o'tgan",
"Next 7 days" : "Keyingi 7 kun",
"Next 30 days" : "Keyingi 30 kun",
@@ -37,13 +37,13 @@ OC.L10N.register(
"Undo" : "Bekor qilish",
"Can edit" : "Can edit",
"Owner" : "Owner",
"Delete" : "Delete",
"Delete" : "O'chirish",
"Delete list" : "Roʻyxatni oʻchirish",
"Edit" : "Tahrirlash",
"Download" : "Download",
"Download" : "Yuklab olish",
"Modified" : "Modified",
"Comments" : "Comments",
"Save" : "Save",
"Save" : "Saqlash",
"In reply to" : "ga javoban",
"Reply" : "Javob bering",
"Update" : "Update",
@@ -55,7 +55,7 @@ OC.L10N.register(
"Edit title" : "Sarlavhani tahrirlash",
"Delete card" : "Kartani o'chirish",
"seconds ago" : "seconds ago",
"Search" : "Search",
"Search" : "Qidirish",
"Archived boards" : "Arxivlangan taxtalar",
"Shared with you" : "Shared with you",
"No reminder" : "Eslatma yo'q",

View File

@@ -18,12 +18,12 @@
"Card not found" : "Karta topilmadi",
"Add board" : "Doska qo'shing",
"Move card" : "Kartani ko'chirish",
"Cancel" : "Cancel",
"Cancel" : "Bekor qilish",
"Add card" : "Karta qo'shing",
"Archived cards" : "Arxivlangan kartalar",
"Add list" : "Roʻyxat qoʻshish",
"Unassigned" : "Tayinlanmagan",
"Open" : "Open",
"Open" : "Ochish",
"Overdue" : "Muddati o'tgan",
"Next 7 days" : "Keyingi 7 kun",
"Next 30 days" : "Keyingi 30 kun",
@@ -35,13 +35,13 @@
"Undo" : "Bekor qilish",
"Can edit" : "Can edit",
"Owner" : "Owner",
"Delete" : "Delete",
"Delete" : "O'chirish",
"Delete list" : "Roʻyxatni oʻchirish",
"Edit" : "Tahrirlash",
"Download" : "Download",
"Download" : "Yuklab olish",
"Modified" : "Modified",
"Comments" : "Comments",
"Save" : "Save",
"Save" : "Saqlash",
"In reply to" : "ga javoban",
"Reply" : "Javob bering",
"Update" : "Update",
@@ -53,7 +53,7 @@
"Edit title" : "Sarlavhani tahrirlash",
"Delete card" : "Kartani o'chirish",
"seconds ago" : "seconds ago",
"Search" : "Search",
"Search" : "Qidirish",
"Archived boards" : "Arxivlangan taxtalar",
"Shared with you" : "Shared with you",
"No reminder" : "Eslatma yo'q",

View File

@@ -0,0 +1,67 @@
<?php
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Deck\Command;
use OCP\IConfig;
use OCP\IUserManager;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
class CalendarToggle extends Command {
private IUserManager $userManager;
private IConfig $config;
public function __construct(IUserManager $userManager, IConfig $config) {
parent::__construct();
$this->userManager = $userManager;
$this->config = $config;
}
protected function configure() {
$this
->setName('deck:calendar-toggle')
->setDescription('Enable or disable Deck calendar/tasks integration for all existing users. Users can still change their own setting afterwards. Only affects users that already exist at the time of execution.')
->addOption(
'on',
null,
InputOption::VALUE_NONE,
'Enable calendar/tasks integration for all existing users (users can opt-out later)'
)
->addOption(
'off',
null,
InputOption::VALUE_NONE,
'Disable calendar/tasks integration for all existing users (users can opt-in later)'
);
}
protected function execute(InputInterface $input, OutputInterface $output): int {
$enable = $input->getOption('on');
$disable = $input->getOption('off');
if ($enable && $disable) {
$output->writeln('<error>Cannot use --on and --off together.</error>');
return 1;
}
if (!$enable && !$disable) {
$output->writeln('<error>Please specify either --on or --off.</error>');
return 1;
}
$value = $enable ? 'yes' : '';
$users = $this->userManager->search('');
$count = 0;
foreach ($users as $user) {
$uid = $user->getUID();
$this->config->setUserValue($uid, 'deck', 'calendar', $value);
$output->writeln("Set calendar integration to '" . ($enable ? 'on' : 'off') . "' for user: $uid");
$count++;
}
$output->writeln("Done. Updated $count existing users.");
return 0;
}
}

View File

@@ -65,11 +65,11 @@ class CardController extends Controller {
$card = $this->cardService->create($title, $stackId, $type, $order, $this->userId, $description, $duedate);
foreach ($labels as $label) {
$this->assignLabel($card->id, $label);
$this->assignLabel($card->getId(), $label);
}
foreach ($users as $user) {
$this->assignmentService->assignUser($card->id, $user['id'], $user['type']);
$this->assignmentService->assignUser($card->getId(), $user['id'], $user['type']);
}
return $card;

View File

@@ -45,8 +45,7 @@ class SessionMapper extends QBMapper {
$qb->select('id', 'board_id', 'last_contact', 'user_id', 'token')
->from($this->getTableName())
->where($qb->expr()->eq('board_id', $qb->createNamedParameter($boardId)))
->andWhere($qb->expr()->gt('last_contact', $qb->createNamedParameter(time() - SessionService::SESSION_VALID_TIME)))
->executeQuery();
->andWhere($qb->expr()->gt('last_contact', $qb->createNamedParameter(time() - SessionService::SESSION_VALID_TIME)));
return $this->findEntities($qb);
}

View File

@@ -320,14 +320,14 @@ class BoardService {
return $board;
}
private function applyPermissions($boardId, $edit, $share, $manage) {
private function applyPermissions($boardId, $edit, $share, $manage, $oldAcl = null) {
try {
$this->permissionService->checkPermission($this->boardMapper, $boardId, Acl::PERMISSION_MANAGE);
} catch (NoPermissionException $e) {
$acls = $this->aclMapper->findAll($boardId);
$edit = $this->permissionService->userCan($acls, Acl::PERMISSION_EDIT, $this->userId) && $edit;
$share = $this->permissionService->userCan($acls, Acl::PERMISSION_SHARE, $this->userId) && $share;
$manage = $this->permissionService->userCan($acls, Acl::PERMISSION_MANAGE, $this->userId) && $manage;
$edit = $this->permissionService->userCan($acls, Acl::PERMISSION_EDIT, $this->userId) ? $edit : $oldAcl?->getPermissionEdit() ?? false;
$share = $this->permissionService->userCan($acls, Acl::PERMISSION_SHARE, $this->userId) ? $share : $oldAcl?->getPermissionShare() ?? false;
$manage = $this->permissionService->userCan($acls, Acl::PERMISSION_MANAGE, $this->userId) ? $manage : $oldAcl?->getPermissionManage() ?? false;
}
return [$edit, $share, $manage];
}
@@ -417,7 +417,7 @@ class BoardService {
/** @var Acl $acl */
$acl = $this->aclMapper->find($id);
[$edit, $share, $manage] = $this->applyPermissions($acl->getBoardId(), $edit, $share, $manage);
[$edit, $share, $manage] = $this->applyPermissions($acl->getBoardId(), $edit, $share, $manage, $acl);
$acl->setPermissionEdit($edit);
$acl->setPermissionShare($share);
$acl->setPermissionManage($manage);
@@ -439,7 +439,7 @@ class BoardService {
* @throws NotFoundExceptionInterface
*/
public function deleteAcl(int $id): ?Acl {
$this->permissionService->checkPermission($this->aclMapper, $id, Acl::PERMISSION_SHARE);
$this->permissionService->checkPermission($this->aclMapper, $id, Acl::PERMISSION_MANAGE);
/** @var Acl $acl */
$acl = $this->aclMapper->find($id);
$this->boardMapper->mapAcl($acl);
@@ -621,7 +621,9 @@ class BoardService {
if ($fullDetails) {
$this->enrichWithStacks($board);
$this->enrichWithLabels($board);
if ($board->getLabels() === null) {
$this->enrichWithLabels($board);
}
$this->enrichWithUsers($board);
$this->enrichWithBoardSettings($board);
$this->enrichWithActiveSessions($board);

View File

@@ -356,7 +356,7 @@ class CardService {
if ($resetDuedateNotification) {
$this->notificationHelper->markDuedateAsRead($card);
}
$this->changeHelper->cardChanged($card->getId(), true);
$this->changeHelper->cardChanged($card->getId());
$this->eventDispatcher->dispatchTyped(new CardUpdatedEvent($card, $changes->getBefore()));
@@ -418,11 +418,12 @@ class CardService {
if ($card->getArchived()) {
throw new StatusException('Operation not allowed. This card is archived.');
}
$changes = new ChangeSet($card);
$card->setTitle($title);
$this->changeHelper->cardChanged($card->getId(), false);
$update = $this->cardMapper->update($card);
$this->eventDispatcher->dispatchTyped(new CardUpdatedEvent($card));
$this->eventDispatcher->dispatchTyped(new CardUpdatedEvent($card, $changes->getBefore()));
return $update;
}
@@ -441,7 +442,6 @@ class CardService {
public function reorder($id, $stackId, $order) {
$this->cardServiceValidator->check(compact('id', 'stackId', 'order'));
$this->permissionService->checkPermission($this->cardMapper, $id, Acl::PERMISSION_EDIT);
$this->permissionService->checkPermission($this->stackMapper, $stackId, Acl::PERMISSION_EDIT);
@@ -459,30 +459,30 @@ class CardService {
$changes->setAfter($card);
$this->activityManager->triggerUpdateEvents(ActivityManager::DECK_OBJECT_CARD, $changes, ActivityManager::SUBJECT_CARD_UPDATE);
$cards = $this->cardMapper->findAll($stackId);
$cardsToReorder = $this->cardMapper->findAll($stackId);
$result = [];
$i = 0;
foreach ($cards as $card) {
if ($card->getArchived()) {
foreach ($cardsToReorder as $cardToReorder) {
if ($cardToReorder->getArchived()) {
throw new StatusException('Operation not allowed. This card is archived.');
}
if ($card->id === $id) {
$card->setOrder($order);
$card->setLastModified(time());
if ($cardToReorder->id === $id) {
$cardToReorder->setOrder($order);
$cardToReorder->setLastModified(time());
}
if ($i === $order) {
$i++;
}
if ($card->id !== $id) {
$card->setOrder($i++);
if ($cardToReorder->id !== $id) {
$cardToReorder->setOrder($i++);
}
$this->cardMapper->update($card);
$result[$card->getOrder()] = $card;
$this->cardMapper->update($cardToReorder);
$result[$cardToReorder->getOrder()] = $cardToReorder;
}
$this->changeHelper->cardChanged($id, false);
$this->eventDispatcher->dispatchTyped(new CardUpdatedEvent($card));
$this->eventDispatcher->dispatchTyped(new CardUpdatedEvent($card, $changes->getBefore()));
return array_values($result);
}
@@ -499,19 +499,19 @@ class CardService {
public function archive($id) {
$this->cardServiceValidator->check(compact('id'));
$this->permissionService->checkPermission($this->cardMapper, $id, Acl::PERMISSION_EDIT);
if ($this->boardService->isArchived($this->cardMapper, $id)) {
throw new StatusException('Operation not allowed. This board is archived.');
}
$card = $this->cardMapper->find($id);
$changes = new ChangeSet($card);
$card->setArchived(true);
$newCard = $this->cardMapper->update($card);
$this->notificationHelper->markDuedateAsRead($card);
$this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_CARD, $newCard, ActivityManager::SUBJECT_CARD_UPDATE_ARCHIVE);
$this->changeHelper->cardChanged($id, false);
$this->eventDispatcher->dispatchTyped(new CardUpdatedEvent($card));
$this->eventDispatcher->dispatchTyped(new CardUpdatedEvent($card, $changes->getBefore()));
return $newCard;
}
@@ -534,12 +534,13 @@ class CardService {
throw new StatusException('Operation not allowed. This board is archived.');
}
$card = $this->cardMapper->find($id);
$changes = new ChangeSet($card);
$card->setArchived(false);
$newCard = $this->cardMapper->update($card);
$this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_CARD, $newCard, ActivityManager::SUBJECT_CARD_UPDATE_UNARCHIVE);
$this->changeHelper->cardChanged($id, false);
$this->eventDispatcher->dispatchTyped(new CardUpdatedEvent($card));
$this->eventDispatcher->dispatchTyped(new CardUpdatedEvent($card, $changes->getBefore()));
return $newCard;
}
@@ -559,13 +560,14 @@ class CardService {
throw new StatusException('Operation not allowed. This board is archived.');
}
$card = $this->cardMapper->find($id);
$changes = new ChangeSet($card);
$card->setDone(new \DateTime());
$newCard = $this->cardMapper->update($card);
$this->notificationHelper->markDuedateAsRead($card);
$this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_CARD, $newCard, ActivityManager::SUBJECT_CARD_UPDATE_DONE);
$this->changeHelper->cardChanged($id, false);
$this->eventDispatcher->dispatchTyped(new CardUpdatedEvent($card));
$this->eventDispatcher->dispatchTyped(new CardUpdatedEvent($card, $changes->getBefore()));
return $newCard;
}
@@ -585,12 +587,13 @@ class CardService {
throw new StatusException('Operation not allowed. This board is archived.');
}
$card = $this->cardMapper->find($id);
$changes = new ChangeSet($card);
$card->setDone(null);
$newCard = $this->cardMapper->update($card);
$this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_CARD, $newCard, ActivityManager::SUBJECT_CARD_UPDATE_UNDONE);
$this->changeHelper->cardChanged($id, false);
$this->eventDispatcher->dispatchTyped(new CardUpdatedEvent($card));
$this->eventDispatcher->dispatchTyped(new CardUpdatedEvent($card, $changes->getBefore()));
return $newCard;
}
@@ -652,9 +655,6 @@ class CardService {
throw new StatusException('Operation not allowed. This card is archived.');
}
$label = $this->labelMapper->find($labelId);
if ($label->getBoardId() !== $this->cardMapper->findBoardId($card->getId())) {
throw new StatusException('Operation not allowed. Label does not exist.');
}
$this->cardMapper->removeLabel($cardId, $labelId);
$this->changeHelper->cardChanged($cardId);
$this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_CARD, $card, ActivityManager::SUBJECT_LABEL_UNASSING, ['label' => $label]);

View File

@@ -214,7 +214,7 @@ class PermissionService {
}
try {
$board = $this->boardMapper->find($boardId);
$board = $this->getBoard($boardId);
} catch (DoesNotExistException $e) {
return [];
} catch (MultipleObjectsReturnedException $e) {
@@ -227,7 +227,7 @@ class PermissionService {
} else {
$users[$board->getOwner()] = new User($board->getOwner(), $this->userManager);
}
$acls = $this->aclMapper->findAll($boardId);
$acls = $board->getAcl();
/** @var Acl $acl */
foreach ($acls as $acl) {
if ($acl->getType() === Acl::PERMISSION_TYPE_USER) {

12751
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -31,22 +31,19 @@
},
"dependencies": {
"@babel/polyfill": "^7.12.1",
"@babel/runtime": "^7.27.0",
"@babel/runtime": "^7.27.1",
"@nextcloud/auth": "^2.4.0",
"@nextcloud/axios": "^2.5.1",
"@nextcloud/capabilities": "^1.2.0",
"@nextcloud/dialogs": "^7.0.0-rc.1",
"@nextcloud/dialogs": "^6.0.1",
"@nextcloud/event-bus": "^3.3.2",
"@nextcloud/files": "^3.10.1",
"@nextcloud/initial-state": "^2.2.0",
"@nextcloud/l10n": "^3.1.0",
"@nextcloud/moment": "^1.3.2",
"@nextcloud/moment": "^1.3.4",
"@nextcloud/notify_push": "^1.3.0",
"@nextcloud/router": "^3.0.1",
"@nextcloud/vue": "^9.0.0-rc.3",
"@vue/compiler-sfc": "^3.5.13",
"@vue/vue3-jest": "^29.2.6",
"@vueuse/core": "^13.1.0",
"@nextcloud/vue": "^8.27.0",
"blueimp-md5": "^2.19.0",
"chroma-js": "^3.1.2",
"dompurify": "^3.2.5",
@@ -57,14 +54,16 @@
"moment": "^2.30.1",
"p-queue": "^8.0.1",
"url-search-params-polyfill": "^8.2.5",
"v3-infinite-loading": "^1.3.2",
"vue": "^3.5.13",
"vue": "^2.7.15",
"vue-at": "^2.5.1",
"vue-click-outside": "^1.1.0",
"vue-easymde": "^2.0.0",
"vue-infinite-loading": "^2.4.5",
"vue-material-design-icons": "^5.3.1",
"vue-router": "^4.5.0",
"vue3-smooth-dnd": "^0.0.6",
"vuex": "^4.1.0"
"vue-router": "^3.6.5",
"vue-smooth-dnd": "^0.8.1",
"vuex": "^3.6.2",
"vuex-router-sync": "^5.0.0"
},
"browserslist": [
"extends @nextcloud/browserslist-config"
@@ -76,18 +75,20 @@
"devDependencies": {
"@nextcloud/babel-config": "^1.2.0",
"@nextcloud/browserslist-config": "^3.0.1",
"@nextcloud/cypress": "^1.0.0-beta.13",
"@nextcloud/cypress": "^1.0.0-beta.15",
"@nextcloud/eslint-config": "^8.4.2",
"@nextcloud/stylelint-config": "^3.0.1",
"@nextcloud/webpack-vue-config": "github:nextcloud-libraries/webpack-vue-config#vue3",
"@relative-ci/agent": "^4.2.14",
"@nextcloud/webpack-vue-config": "^6.3.0",
"@relative-ci/agent": "^4.3.1",
"@vue/test-utils": "^2.4.6",
"@vue/vue2-jest": "^29.2.6",
"cypress": "^13.17.0",
"eslint-plugin-cypress": "^3.6.0",
"eslint-webpack-plugin": "^5.0.1",
"jest": "^29.7.0",
"jest-serializer-vue": "^3.1.0",
"stylelint-webpack-plugin": "^5.0.1"
"stylelint-webpack-plugin": "^5.0.1",
"vue-template-compiler": "^2.7.16"
},
"jest": {
"moduleFileExtensions": [

View File

@@ -1,51 +1,15 @@
<!--
- SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
- SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
- SPDX-License-Identifier: AGPL-3.0-or-later
-->
<script>
import { NcAppContent, NcContent, NcModal } from '@nextcloud/vue'
import CardMoveDialog from './CardMoveDialog.vue'
import AppNavigation from './components/navigation/AppNavigation.vue'
import KeyboardShortcuts from './components/KeyboardShortcuts.vue'
import { BoardApi } from './services/BoardApi.js'
const boardApi = new BoardApi()
export default {
name: 'App',
components: {
NcContent,
AppNavigation,
NcAppContent,
KeyboardShortcuts,
CardMoveDialog,
NcModal,
},
provide() {
return {
boardApi,
}
},
computed: {
cardDetailsInModal() {
return this.$store.getters.config('cardDetailsInModal')
},
},
methods: {
hideModal() {
this.$router.push({ name: 'board' })
},
},
}
</script>
<template>
<NcContent app-name="deck">
<NcContent app-name="deck" :class="{ 'nav-hidden': !navShown, 'sidebar-hidden': !sidebarRouterView }">
<AppNavigation />
<NcAppContent :allow-swipe-navigation="false">
<router-view />
</NcAppContent>
<div v-if="$route.params.id || $route.params.cardId">
<NcModal v-if="cardDetailsInModal && $route.params.cardId"
:name="t('deck', 'Card details')"
@@ -57,10 +21,179 @@ export default {
<router-view name="sidebar" />
</div>
</NcModal>
<router-view name="sidebar" :visible="!cardDetailsInModal || !$route.params.cardId" />
</div>
<KeyboardShortcuts />
<CardMoveDialog />
</NcContent>
</template>
<script>
import { mapState } from 'vuex'
import AppNavigation from './components/navigation/AppNavigation.vue'
import KeyboardShortcuts from './components/KeyboardShortcuts.vue'
import { NcModal, NcContent, NcAppContent, isMobile } from '@nextcloud/vue'
import { BoardApi } from './services/BoardApi.js'
import { emit, subscribe } from '@nextcloud/event-bus'
import { loadState } from '@nextcloud/initial-state'
import CardMoveDialog from './CardMoveDialog.vue'
const boardApi = new BoardApi()
export default {
name: 'App',
components: {
CardMoveDialog,
AppNavigation,
NcModal,
NcContent,
NcAppContent,
KeyboardShortcuts,
},
mixins: [isMobile],
provide() {
return {
boardApi,
}
},
data() {
return {
addButton: {
icon: 'icon-add',
classes: [],
text: t('deck', 'Add board'),
edit: {
text: t('deck', 'Add board'),
action: () => {
},
reset: () => {
},
},
action: () => {
this.addButton.classes.push('editing')
},
},
}
},
computed: {
...mapState({
navShown: state => state.navShown,
sidebarShownState: state => state.sidebarShown,
currentBoard: state => state.currentBoard,
}),
// TODO: properly handle sidebar showing for route subview and board sidebar
sidebarRouterView() {
// console.log(this.$route)
return this.$route.name === 'card' || this.$route.name === 'board.details'
},
sidebarShown() {
return this.sidebarRouterView || this.sidebarShownState
},
cardDetailsInModal: {
get() {
return this.$store.getters.config('cardDetailsInModal')
},
set(newValue) {
this.$store.dispatch('setConfig', { cardDetailsInModal: newValue })
},
},
},
created() {
const initialState = loadState('deck', 'initialBoards', null)
if (initialState !== null) {
this.$store.dispatch('loadBoards')
}
this.$store.dispatch('loadSharees')
},
mounted() {
// Set navigation to initial state and update in case it gets toggled
emit('toggle-navigation', { open: !this.isMobile && this.navShown, _initial: true })
this.$nextTick(() => {
subscribe('navigation-toggled', (navState) => {
this.$store.dispatch('toggleNav', navState.open)
})
})
},
methods: {
hideModal() {
this.$router.push({ name: 'board' })
},
},
}
</script>
<style lang="scss" scoped>
#content-vue {
#app-content {
transition: margin-left 100ms ease;
position: relative;
overflow-x: hidden;
align-items: stretch;
}
#app-sidebar {
transition: max-width 100ms ease;
}
&.nav-hidden {
#app-content {
margin-left: 0;
}
}
&.sidebar-hidden {
#app-sidebar {
max-width: 0;
min-width: 0;
}
}
}
</style>
<style lang="scss">
@import '../css/print';
.icon-activity {
background-image: url(../img/activity-dark.svg);
body[data-theme-dark] & {
background-image: url(../img/activity.svg);
}
}
.avatardiv.circles {
background: var(--color-primary-element);
}
.icon-circles {
background-image: url(../img/circles-dark.svg);
opacity: 1;
background-size: 20px;
background-position: center center;
}
.icon-circles-white, .icon-circles.icon-white {
background-image: url(../img/circles.svg);
opacity: 1;
background-size: 20px;
background-position: center center;
}
.icon-colorpicker {
background-image: url('../img/color_picker.svg');
}
.v-select {
width: 100%;
}
.modal__card {
width: 100%;
min-width: 100%;
height: calc(100% - 20px);
overflow: hidden;
}
</style>

View File

@@ -22,10 +22,10 @@
label="title" />
</div>
<template #actions>
<NcButton :disabled="!isBoardAndStackChoosen" variant="secondary" @click="moveCard">
<NcButton :disabled="!isBoardAndStackChoosen" type="secondary" @click="moveCard">
{{ t('deck', 'Move card') }}
</NcButton>
<NcButton :disabled="!isBoardAndStackChoosen" variant="primary" @click="cloneCard">
<NcButton :disabled="!isBoardAndStackChoosen" type="primary" @click="cloneCard">
{{ t('deck', 'Copy card') }}
</NcButton>
</template>
@@ -72,7 +72,7 @@ export default {
mounted() {
subscribe('deck:card:show-move-dialog', this.openModal)
},
unmounted() {
destroyed() {
unsubscribe('deck:card:show-move-dialog', this.openModal)
},
methods: {

View File

@@ -10,15 +10,9 @@
:key="activity.activity_id"
:activity="activity" />
<InfiniteLoading :identifier="objectId" @infinite="infiniteHandler" @change="changeObject">
<template #spinner>
<div class="icon-loading" />
</template>
<template #no-more>
<div />
</template>
<template #no-results>
<div />
</template>
<div slot="spinner" class="icon-loading" />
<div slot="no-more" />
<div slot="no-results" />
</InfiniteLoading>
</div>
</template>
@@ -27,7 +21,7 @@
import axios from '@nextcloud/axios'
import { generateOcsUrl } from '@nextcloud/router'
import ActivityEntry from './ActivityEntry.vue'
// import InfiniteLoading from 'v3-infinite-loading'
import InfiniteLoading from 'vue-infinite-loading'
const ACTIVITY_FETCH_LIMIT = 50
@@ -35,6 +29,7 @@ export default {
name: 'ActivityList',
components: {
ActivityEntry,
InfiniteLoading,
},
props: {
filter: {

View File

@@ -84,7 +84,7 @@
:title="t('deck', 'Apply filter')"
:aria-label="t('deck', 'Apply filter')"
class="filter-button"
:variant="isFilterActive ? 'primary' : 'tertiary'">
:type="isFilterActive ? 'primary' : 'tertiary'">
<template #icon>
<FilterIcon v-if="isFilterActive" :size="20" decorative />
<FilterOffIcon v-else :size="20" decorative />
@@ -231,16 +231,12 @@
</NcActionButton>
<NcActionButton v-if="compactMode"
@click="toggleCompactMode">
<template #icon>
<ArrowExpandVerticalIcon :size="20" decorative />
</template>
<ArrowExpandVerticalIcon slot="icon" :size="20" decorative />
{{ t('deck', 'Toggle compact mode') }}
</NcActionButton>
<NcActionButton v-else
@click="toggleCompactMode">
<template #icon>
<ArrowCollapseVerticalIcon :size="20" decorative />
</template>
<ArrowCollapseVerticalIcon slot="icon" :size="20" decorative />
{{ t('deck', 'Toggle compact mode') }}
</NcActionButton>
<NcActionButton @click="toggleShowCardCover">
@@ -267,10 +263,10 @@ import { mapState, mapGetters } from 'vuex'
import { subscribe, unsubscribe } from '@nextcloud/event-bus'
import { NcActions, NcActionButton, NcAvatar, NcButton, NcPopover, NcModal } from '@nextcloud/vue'
import labelStyle from '../mixins/labelStyle.js'
import ArchiveIcon from 'vue-material-design-icons/Archive.vue'
import ImageIcon from 'vue-material-design-icons/ImageMultiple.vue'
import FilterIcon from 'vue-material-design-icons/Filter.vue'
import FilterOffIcon from 'vue-material-design-icons/FilterOff.vue'
import ArchiveIcon from 'vue-material-design-icons/ArchiveOutline.vue'
import ImageIcon from 'vue-material-design-icons/ImageMultipleOutline.vue'
import FilterIcon from 'vue-material-design-icons/FilterOutline.vue'
import FilterOffIcon from 'vue-material-design-icons/FilterOffOutline.vue'
import TableColumnPlusAfter from 'vue-material-design-icons/TableColumnPlusAfter.vue'
import ArrowCollapseVerticalIcon from 'vue-material-design-icons/ArrowCollapseVertical.vue'
import ArrowExpandVerticalIcon from 'vue-material-design-icons/ArrowExpandVertical.vue'
@@ -278,7 +274,6 @@ import SessionList from './SessionList.vue'
import { isNotifyPushEnabled } from '../sessions.js'
import CreateNewCardCustomPicker from '../views/CreateNewCardCustomPicker.vue'
import { getCurrentUser } from '@nextcloud/auth'
import { onClickOutside } from '@vueuse/core'
export default {
name: 'Controls',
@@ -364,11 +359,6 @@ export default {
}
},
},
created() {
onClickOutside(() => {
this.hideAddStack()
})
},
beforeMount() {
subscribe('deck:board:show-new-card', this.clickShowAddCardModel)
subscribe('deck:board:toggle-filter-popover', this.triggerOpenFilters)
@@ -376,7 +366,7 @@ export default {
subscribe('deck:board:toggle-filter-by-me', this.triggerFilterByMe)
},
beforeUnmount() {
beforeDestroy() {
unsubscribe('deck:board:show-new-card', this.clickShowAddCardModel)
unsubscribe('deck:board:toggle-filter-popover', this.triggerOpenFilters)
unsubscribe('deck:board:clear-filter', this.triggerClearFilter)
@@ -518,6 +508,20 @@ export default {
#stack-add form {
display: flex;
#new-stack-input-main {
margin-right: 8px;
}
.icon-confirm {
border: 2px solid var(--color-border-maxcontrast) !important;
border-left: none !important;
}
&:focus-within, &:focus, &:focus-visible,
&:hover {
.icon-confirm {
border-color: var(--color-main-text) !important;
}
}
}
}

View File

@@ -6,6 +6,7 @@
<!-- :style="{top:cardTop, left:cardLeft}" -->
<div v-if="card && selector"
ref="shortcutModal"
v-click-outside="close"
class="keyboard-shortcuts__modal"
tabindex="0"
@keydown.esc="close">
@@ -17,7 +18,6 @@
</template>
<script>
import DueDateSelector from './card/DueDateSelector.vue'
import { onClickOutside } from '@vueuse/core'
import { emit, subscribe, unsubscribe } from '@nextcloud/event-bus'
import { mapState } from 'vuex'
import TagSelector from './card/TagSelector.vue'
@@ -50,9 +50,8 @@ export default {
subscribe('deck:card:show-assignment-selector', this.handleShowAssignemnt)
subscribe('deck:card:show-due-date-selector', this.handleShowDueDate)
subscribe('deck:card:show-label-selector', this.handleShowLabel)
onClickOutside(this.close)
},
unmounted() {
destroyed() {
document.removeEventListener('keydown', this.onKeydown)
unsubscribe('deck:card:show-assignment-selector', this.handleShowAssignemnt)
unsubscribe('deck:card:show-due-date-selector', this.handleShowDueDate)

View File

@@ -29,12 +29,12 @@
{{ t('deck', 'Create a new list to add cards to this board') }}
<form @submit.prevent="addNewStack()">
<NcTextField ref="newStackInput"
v-model="newStackTitle"
:disable="loading"
:value.sync="newStackTitle"
:placeholder="t('deck', 'List name')"
type="text" />
<NcButton variant="secondary"
type="submit"
<NcButton type="secondary"
native-type="submit"
:disabled="loading"
:title="t('deck', 'Add list')">
<template #icon>
@@ -63,10 +63,7 @@
data-click-closes-sidebar="true"
data-dragscroll-enabled
class="stack-draggable-wrapper">
<Stack :stack="stack"
:dragging="draggingStack"
data-click-closes-sidebar="true"
@open-card="openCard" />
<Stack :stack="stack" :dragging="draggingStack" data-click-closes-sidebar="true" />
</Draggable>
</Container>
</div>
@@ -85,7 +82,7 @@
</template>
<script>
import { Container, Draggable } from 'vue3-smooth-dnd'
import { Container, Draggable } from 'vue-smooth-dnd'
import { mapState, mapGetters } from 'vuex'
import Controls from '../Controls.vue'
import DeckIcon from '../icons/DeckIcon.vue'
@@ -168,14 +165,14 @@ export default {
created() {
this.session = createSession(this.id)
this.fetchData()
this.$root.$on('open-card', (cardId) => {
this.localModal = cardId
})
},
beforeUnmount() {
beforeDestroy() {
this.session.close()
},
methods: {
openCard(cardId) {
},
async fetchData() {
this.loading = true
try {
@@ -256,8 +253,8 @@ export default {
</script>
<style lang="scss" scoped>
@use '../../css/animations';
@use '../../css/variables';
@import '../../css/animations';
@import '../../css/variables';
form {
text-align: center;
@@ -285,7 +282,7 @@ export default {
}
.board {
padding-left: variables.$board-spacing;
padding-left: $board-spacing;
position: relative;
max-height: calc(100% - var(--default-clickable-area));
overflow: hidden;
@@ -316,8 +313,8 @@ export default {
display: flex;
flex-direction: column;
// Margin left instead of padidng to avoid jumps on dropping a card
margin-left: variables.$stack-spacing;
padding-right: variables.$stack-spacing;
margin-left: $stack-spacing;
padding-right: $stack-spacing;
overflow-x: hidden;
overflow-y: auto;
padding-top: 15px;

View File

@@ -56,9 +56,9 @@ import DeletedTabSidebar from './DeletedTabSidebar.vue'
import TimelineTabSidebar from './TimelineTabSidebar.vue'
import { NcAppSidebar, NcAppSidebarTab } from '@nextcloud/vue'
import ActivityIcon from 'vue-material-design-icons/LightningBolt.vue'
import SharingIcon from 'vue-material-design-icons/ShareVariant.vue'
import TagsIcon from 'vue-material-design-icons/TagMultiple.vue'
import TrashIcon from 'vue-material-design-icons/Delete.vue'
import SharingIcon from 'vue-material-design-icons/ShareVariantOutline.vue'
import TagsIcon from 'vue-material-design-icons/TagMultipleOutline.vue'
import TrashIcon from 'vue-material-design-icons/DeleteOutline.vue'
const capabilities = window.OC.getCapabilities()
export default {

View File

@@ -94,7 +94,7 @@
non-drag-area-selector=".dragDisabled"
:drag-handle-selector="dragHandleSelector"
data-dragscroll-enabled
:should-accept-drop="() => canEdit"
@should-accept-drop="canEdit"
@drag-start="draggingCard = true"
@drag-end="draggingCard = false"
@drop="($event) => onDropCard(stack.id, $event)">
@@ -102,10 +102,7 @@
<transition :appear="animate && !card.animated && (card.animated=true)"
:appear-class="'zoom-appear-class'"
:appear-active-class="'zoom-appear-active-class'">
<CardItem :id="card.id"
ref="card"
:dragging="draggingCard"
@open-card="openCard" />
<CardItem :id="card.id" ref="card" :dragging="draggingCard" />
</transition>
</Draggable>
</Container>
@@ -139,8 +136,8 @@
<script>
import ClickOutside from 'vue-click-outside'
import { mapGetters, mapState } from 'vuex'
import { Container, Draggable } from 'vue3-smooth-dnd'
import ArchiveIcon from 'vue-material-design-icons/Archive.vue'
import { Container, Draggable } from 'vue-smooth-dnd'
import ArchiveIcon from 'vue-material-design-icons/ArchiveOutline.vue'
import CardPlusOutline from 'vue-material-design-icons/CardPlusOutline.vue'
import { NcActions, NcActionButton, NcModal } from '@nextcloud/vue'
import { showError, showUndo } from '@nextcloud/dialogs'
@@ -174,9 +171,6 @@ export default {
default: undefined,
},
},
emits: [
'open-card',
],
data() {
return {
editing: false,
@@ -239,9 +233,6 @@ export default {
},
methods: {
openCard(cardId) {
this.$emit('open-card', cardId)
},
stopCardCreation(e) {
// For some reason the submit event triggers a MouseEvent that is bubbling to the outside
// so we have to ignore it
@@ -371,10 +362,10 @@ export default {
@use 'sass:math';
@use './../../css/variables';
@import './../../css/variables';
.stack {
width: variables.$stack-width + variables.$stack-spacing * 3;
width: $stack-width + $stack-spacing * 3;
}
.stack__header {
@@ -382,8 +373,8 @@ export default {
position: sticky;
top: 0;
z-index: 100;
padding-left: variables.$card-spacing;
padding-right: variables.$card-spacing;
padding-left: $card-spacing;
padding-right: $card-spacing;
margin: 6px;
margin-top: 0;
cursor: grab;
@@ -427,7 +418,7 @@ export default {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: calc(variables.$stack-width - 60px);
max-width: calc($stack-width - 60px);
border-radius: 3px;
padding: 4px 4px;
font-size: var(--default-font-size);
@@ -468,8 +459,8 @@ export default {
form {
display: flex;
margin-left: variables.$stack-spacing;
margin-right: variables.$stack-spacing;
margin-left: $stack-spacing;
margin-right: $stack-spacing;
width: 100%;
border: 2px solid var(--color-border-maxcontrast);
border-radius: var(--border-radius-large);

View File

@@ -44,7 +44,7 @@
<script>
import { defineComponent } from 'vue'
import { NcAvatar, NcSelect } from '@nextcloud/vue'
import AccountMultiple from 'vue-material-design-icons/AccountMultiple.vue'
import AccountMultiple from 'vue-material-design-icons/AccountMultipleOutline.vue'
export default defineComponent({
name: 'AssignmentSelector',

View File

@@ -3,16 +3,16 @@
- SPDX-License-Identifier: AGPL-3.0-or-later
-->
<!-- eslint-disable vue/no-v-model-argument -->
<template>
<NcAppSidebar v-if="currentBoard && currentCard"
ref="cardSidebar"
v-model:name-editable="isEditingTitle"
:active="tabId"
:name="displayTitle"
:subname="subtitle"
:subtitle="subtitleTooltip"
@update:name="value => titleEditing = value"
:name-editable.sync="isEditingTitle"
@update:name="(value) => titleEditing = value"
@update:active="(value) => activeTabId = value"
@dismiss-editing="titleEditing = currentCard.title"
@submit-name="handleSubmitTitle"
@opened="focusHeader"
@@ -25,71 +25,39 @@
{{ t('deck', 'Open in bigger view') }}
</NcActionButton>
<NcActionButton v-if="canEdit && !isCurrentUserAssigned"
icon="icon-user"
:close-after-click="true"
@click="assignCardToMe()">
{{ t('deck', 'Assign to me') }}
</NcActionButton>
<NcActionButton v-if="canEdit && isCurrentUserAssigned"
icon="icon-user"
:close-after-click="true"
@click="unassignCardFromMe()">
{{ t('deck', 'Unassign myself') }}
</NcActionButton>
<NcActionButton v-if="canEdit"
icon="icon-checkmark"
:close-after-click="true"
@click="changeCardDoneStatus()">
{{ currentCard.done ? t('deck', 'Mark as not done') : t('deck', 'Mark as done') }}
</NcActionButton>
<NcActionButton v-if="canEdit"
icon="icon-external"
:close-after-click="true"
@click="openCardMoveDialog">
{{ t('deck', 'Move/copy card') }}
</NcActionButton>
<NcActionButton v-for="action in cardActions"
:key="action.label"
:close-after-click="true"
:icon="action.icon"
@click="action.callback(cardRichObject)">
{{ action.label }}
</NcActionButton>
<NcActionButton v-if="canEditBoard" :close-after-click="true" @click="archiveUnarchiveCard()">
<template #icon>
<ArchiveIcon :size="20" decorative />
</template>
{{ currentCard.archived ? t('deck', 'Unarchive card') : t('deck', 'Archive card') }}
</NcActionButton>
<NcActionButton v-if="canEdit"
icon="icon-delete"
:close-after-click="true"
@click="deleteCard()">
{{ t('deck', 'Delete card') }}
</NcActionButton>
<CardMenuEntries :card="currentCard" :hide-details-entry="true" />
</template>
<template #description>
<NcReferenceList v-if="currentCard.referenceData" :text="currentCard.title" :interactive="false" />
<NcReferenceList v-if="currentCard.referenceData"
:text="currentCard.title"
:interactive="false" />
</template>
<NcAppSidebarTab id="details" :order="0" :name="t('deck', 'Details')">
<NcAppSidebarTab id="details"
:order="0"
:name="t('deck', 'Details')">
<CardSidebarTabDetails :card="currentCard" />
<template #icon>
<HomeIcon :size="20" />
<HomeIcon v-if="activeTabId === 'details'" :size="20" />
<HomeOutlineIcon v-else :size="20" />
</template>
</NcAppSidebarTab>
<NcAppSidebarTab id="attachments" :order="1" :name="t('deck', 'Attachments')">
<NcAppSidebarTab id="attachments"
:order="1"
:name="t('deck', 'Attachments')">
<template #icon>
<AttachmentIcon :size="20" />
</template>
<CardSidebarTabAttachments :card="currentCard" />
</NcAppSidebarTab>
<NcAppSidebarTab id="comments" :order="2" :name="t('deck', 'Comments')">
<NcAppSidebarTab id="comments"
:order="2"
:name="t('deck', 'Comments')">
<template #icon>
<CommentIcon :size="20" />
<CommentIcon v-if="activeTabId === 'comments'" :size="20" />
<CommentOutlineIcon v-else :size="20" />
</template>
<CardSidebarTabComments :card="currentCard" :tab-query="tabQuery" />
</NcAppSidebarTab>
@@ -108,7 +76,7 @@
<script>
import { NcActionButton, NcAppSidebar, NcAppSidebarTab } from '@nextcloud/vue'
import { NcReferenceList } from '@nextcloud/vue/components/NcRichText'
import { NcReferenceList } from '@nextcloud/vue/dist/Components/NcRichText.js'
import { getCapabilities } from '@nextcloud/capabilities'
import { mapState, mapGetters } from 'vuex'
import CardSidebarTabDetails from './CardSidebarTabDetails.vue'
@@ -119,18 +87,14 @@ import relativeDate from '../../mixins/relativeDate.js'
import moment from '@nextcloud/moment'
import AttachmentIcon from 'vue-material-design-icons/Paperclip.vue'
import HomeIcon from 'vue-material-design-icons/Home.vue'
import HomeOutlineIcon from 'vue-material-design-icons/HomeOutline.vue'
import CommentIcon from 'vue-material-design-icons/Comment.vue'
import CommentOutlineIcon from 'vue-material-design-icons/CommentOutline.vue'
import ActivityIcon from 'vue-material-design-icons/LightningBolt.vue'
import { showError, showWarning, showUndo } from '@nextcloud/dialogs'
import { showError, showWarning } from '@nextcloud/dialogs'
import { getLocale } from '@nextcloud/l10n'
import { emit } from '@nextcloud/event-bus'
import ArchiveIcon from 'vue-material-design-icons/Archive.vue'
import { getCurrentUser } from '@nextcloud/auth'
import { generateUrl } from '@nextcloud/router'
import '@nextcloud/dialogs/style.css'
import CardMenuEntries from '../cards/CardMenuEntries.vue'
const capabilities = getCapabilities()
@@ -148,8 +112,10 @@ export default {
ActivityIcon,
AttachmentIcon,
CommentIcon,
CommentOutlineIcon,
HomeIcon,
ArchiveIcon,
HomeOutlineIcon,
CardMenuEntries,
},
mixins: [relativeDate],
props: {
@@ -174,6 +140,7 @@ export default {
titleEditing: '',
hasActivity: capabilities && capabilities.activity,
locale: getLocale(),
activeTabId: this.tabId || 'details',
}
},
computed: {
@@ -181,17 +148,8 @@ export default {
isFullApp: (state) => state.isFullApp,
currentBoard: (state) => state.currentBoard,
hasCardSaveError: (state) => state.hasCardSaveError,
showArchived: (state) => state.showArchived,
}),
...mapGetters([
'canEdit',
'assignables',
'cardActions',
'stackById',
'isArchived',
'boards',
'boardById',
]),
...mapGetters(['canEdit', 'assignables', 'cardActions', 'stackById']),
currentCard() {
return this.$store.getters.cardById(this.id)
},
@@ -218,31 +176,6 @@ export default {
return reference ? reference.openGraphObject.name : this.currentCard.title
},
},
canEdit() {
return !this.currentCard.archived
},
canEditBoard() {
if (this.currentBoard) {
return this.$store.getters.canEdit
}
const board = this.$store.getters.boards.find((item) => item.id === this.currentCard.boardId)
return !!board?.permissions?.PERMISSION_EDIT
},
isCurrentUserAssigned() {
return this.currentCard.assignedUsers.find((item) => item.type === 0 && item.participant.uid === getCurrentUser()?.uid)
},
boardId() {
return this.card?.boardId ? this.currentCard.boardId : Number(this.$route.params.id)
},
cardRichObject() {
return {
id: '' + this.currentCard.id,
name: this.currentCard.title,
boardname: this.boardById(this.boardId)?.title,
stackname: this.stackById(this.currentCard.stackId)?.title,
link: window.location.protocol + '//' + window.location.host + generateUrl('/apps/deck/') + `card/${this.currentCard.id}`,
}
},
},
watch: {
currentCard() {
@@ -291,46 +224,12 @@ export default {
formatDate(timestamp) {
return moment.unix(timestamp).locale(this.locale).format('LLLL')
},
deleteCard() {
this.$store.dispatch('deleteCard', this.currentCard)
const undoCard = { ...this.currentCard, deletedAt: 0 }
showUndo(t('deck', 'Card deleted'), () => this.$store.dispatch('cardUndoDelete', undoCard))
if (this.$router.currentRoute.name === 'card') {
this.$router.push({ name: 'board' })
}
},
changeCardDoneStatus() {
this.$store.dispatch('changeCardDoneStatus', { ...this.currentCard, done: !this.currentCard.done })
},
archiveUnarchiveCard() {
this.$store.dispatch('archiveUnarchiveCard', { ...this.currentCard, archived: !this.currentCard.archived })
},
assignCardToMe() {
this.$store.dispatch('assignCardToUser', {
card: this.currentCard,
assignee: {
userId: getCurrentUser()?.uid,
type: 0,
},
})
},
unassignCardFromMe() {
this.$store.dispatch('removeUserFromCard', {
card: this.currentCard,
assignee: {
userId: getCurrentUser()?.uid,
type: 0,
},
})
},
openCardMoveDialog() {
emit('deck:card:show-move-dialog', this.currentCard)
},
},
}
</script>
<style lang="scss">
section.app-sidebar__tab--active {
min-height: auto;
display: flex;
@@ -382,7 +281,6 @@ section.app-sidebar__tab--active {
z-index: 100;
background-color: var(--color-main-background);
}
.app-sidebar-tabs__nav {
position: sticky;
top: 87px;
@@ -395,10 +293,10 @@ section.app-sidebar__tab--active {
overflow: initial;
}
#emptycontent,
.emptycontent {
#emptycontent, .emptycontent {
margin-top: 88px;
}
}
}
</style>

View File

@@ -23,11 +23,11 @@
:key="comment.id"
:comment="comment"
@doReload="loadComments" />
<!-- <InfiniteLoading :identifier="card.id" @infinite="infiniteHandler">
<InfiniteLoading :identifier="card.id" @infinite="infiniteHandler">
<div slot="spinner" class="icon-loading" />
<div slot="no-more" />
<div slot="no-results" />
</InfiniteLoading> -->
</InfiniteLoading>
</ul>
<div v-else-if="isLoading" class="icon icon-loading" />
<div v-else class="emptycontent">
@@ -42,7 +42,7 @@ import { mapState, mapGetters } from 'vuex'
import { NcAvatar } from '@nextcloud/vue'
import CommentItem from './CommentItem.vue'
import CommentForm from './CommentForm.vue'
// import InfiniteLoading from 'v3-infinite-loading'
import InfiniteLoading from 'vue-infinite-loading'
import { getCurrentUser } from '@nextcloud/auth'
export default {
@@ -51,7 +51,7 @@ export default {
NcAvatar,
CommentItem,
CommentForm,
// InfiniteLoading,
InfiniteLoading,
},
props: {
card: {

View File

@@ -2,13 +2,8 @@
- SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
- SPDX-License-Identifier: AGPL-3.0-or-later
-->
<template>
<div>
THIS HAS AT
</div>
</template>
<!-- <template>
<template>
<div class="comment-form">
<form @submit.prevent="submit">
<At ref="at"
@@ -196,4 +191,4 @@ export default {
.atwho-li--avatar {
margin-right: 10px;
}
</style> -->
</style>

View File

@@ -82,7 +82,7 @@ import CommentForm from './CommentForm.vue'
import { getCurrentUser } from '@nextcloud/auth'
import md5 from 'blueimp-md5'
import relativeDate from '../../mixins/relativeDate.js'
import ReplyIcon from 'vue-material-design-icons/Reply.vue'
import ReplyIcon from 'vue-material-design-icons/ReplyOutline.vue'
import moment from 'moment'
const AtMention = {

View File

@@ -175,7 +175,7 @@ export default {
mounted() {
this.setupEditor()
},
async beforeUnmount() {
async beforeDestroy() {
await this.destroyEditor()
},
methods: {

View File

@@ -4,12 +4,8 @@
-->
<template>
<CardDetailEntry :label="t('deck', 'Assign a due date to this card…')" data-test="due-date-selector">
<template v-if="!card.done" #icon>
<Calendar :size="20" />
</template>
<template v-else #icon>
<CalendarCheck :size="20" />
</template>
<Calendar v-if="!card.done" slot="icon" :size="20" />
<CalendarCheck v-else slot="icon" :size="20" />
<template v-if="!card.done && !card.archived">
<NcDateTimePickerNative v-if="duedate"
id="card-duedate-picker"
@@ -19,7 +15,7 @@
type="datetime-local" />
<NcActions v-if="canEdit"
:menu-title="!duedate ? t('deck', 'Add due date') : null"
variant="tertiary"
type="tertiary"
data-cy-due-date-actions>
<template v-if="!duedate" #icon>
<Plus :size="20" />
@@ -52,7 +48,7 @@
</NcActions>
<NcButton v-if="!card.done"
variant="secondary"
type="secondary"
class="completed-button"
@click="changeCardDoneStatus()">
<template #icon>
@@ -73,14 +69,14 @@
</div>
<div class="due-actions">
<NcButton v-if="!card.archived"
variant="tertiary"
type="tertiary"
:name="t('deck', 'Not done')"
@click="changeCardDoneStatus()">
<template #icon>
<ClearIcon :size="20" />
</template>
</NcButton>
<NcButton variant="secondary" @click="archiveUnarchiveCard()">
<NcButton type="secondary" @click="archiveUnarchiveCard()">
<template #icon>
<ArchiveIcon :size="20" />
</template>
@@ -103,10 +99,10 @@ import {
import readableDate from '../../mixins/readableDate.js'
import { getDayNamesMin, getFirstDay, getMonthNamesShort } from '@nextcloud/l10n'
import moment from '@nextcloud/moment'
import ArchiveIcon from 'vue-material-design-icons/Archive.vue'
import ArchiveIcon from 'vue-material-design-icons/ArchiveOutline.vue'
import Plus from 'vue-material-design-icons/Plus.vue'
import Calendar from 'vue-material-design-icons/Calendar.vue'
import CalendarCheck from 'vue-material-design-icons/CalendarCheck.vue'
import Calendar from 'vue-material-design-icons/CalendarOutline.vue'
import CalendarCheck from 'vue-material-design-icons/CalendarCheckOutline.vue'
import CheckIcon from 'vue-material-design-icons/Check.vue'
import ClearIcon from 'vue-material-design-icons/Close.vue'
import CardDetailEntry from './CardDetailEntry.vue'

View File

@@ -7,7 +7,7 @@
<div class="selector-wrapper--icon">
<TagMultiple :size="20" />
</div>
<NcSelect v-model="assignedLabels"
<NcSelect :value="assignedLabels"
class="selector-wrapper--selector"
:multiple="true"
:disabled="disabled"
@@ -44,7 +44,7 @@
<script>
import { NcSelect } from '@nextcloud/vue'
import Color from '../../mixins/color.js'
import TagMultiple from 'vue-material-design-icons/TagMultiple.vue'
import TagMultiple from 'vue-material-design-icons/TagMultipleOutline.vue'
export default {
name: 'TagSelector',

View File

@@ -70,7 +70,7 @@
<script>
import { NcAvatar, NcPopover } from '@nextcloud/vue'
import { generateUrl } from '@nextcloud/router'
import AccountMultiple from 'vue-material-design-icons/AccountMultiple.vue'
import AccountMultiple from 'vue-material-design-icons/AccountMultipleOutline.vue'
export default {
name: 'AvatarList',

View File

@@ -49,8 +49,8 @@ import CardId from './badges/CardId.vue'
import TextIcon from 'vue-material-design-icons/Text.vue'
import AttachmentIcon from 'vue-material-design-icons/Paperclip.vue'
import CheckmarkIcon from 'vue-material-design-icons/CheckboxMarked.vue'
import CommentIcon from 'vue-material-design-icons/Comment.vue'
import CommentUnreadIcon from 'vue-material-design-icons/CommentAccount.vue'
import CommentIcon from 'vue-material-design-icons/CommentOutline.vue'
import CommentUnreadIcon from 'vue-material-design-icons/CommentAccountOutline.vue'
import DueDate from './badges/DueDate.vue'
export default {

View File

@@ -72,7 +72,7 @@ export default {
</script>
<style lang="scss" scoped>
@use '../../css/variables';
@import '../../css/variables';
.card-cover {
height: 90px;

View File

@@ -88,7 +88,6 @@ import CardMenu from './CardMenu.vue'
import CardCover from './CardCover.vue'
import DueDate from './badges/DueDate.vue'
import { getCurrentUser } from '@nextcloud/auth'
import { emit } from '@nextcloud/event-bus'
const TITLE_EDITING_STATE = {
OFF: 0,
@@ -121,7 +120,6 @@ export default {
default: false,
},
},
emits: ['open-card'],
data() {
return {
highlight: false,
@@ -228,9 +226,8 @@ export default {
this.$router.push({ name: 'card', params: { id: boardId, cardId: this.card.id } }).catch(() => {})
return
}
emit('open-card', {
cardId: this.card.id,
})
this.$root.$emit('open-card', this.card.id)
},
triggerEditTitle() {
this.editingTitle = TITLE_EDITING_STATE.PENDING
@@ -321,8 +318,8 @@ export default {
</script>
<style lang="scss" scoped>
@use './../../css/animations';
@use './../../css/variables';
@import './../../css/animations';
@import './../../css/variables';
@mixin dark-card {
border: 2px solid var(--color-border-dark);
@@ -334,8 +331,8 @@ export default {
border-radius: var(--border-radius-large);
font-size: 100%;
background-color: var(--color-main-background);
margin-bottom: variables.$card-spacing;
padding: var(--default-grid-baseline) variables.$card-padding;
margin-bottom: $card-spacing;
padding: var(--default-grid-baseline) $card-padding;
border: 2px solid var(--color-border-dark);
width: 100%;
display: flex;
@@ -473,7 +470,7 @@ export default {
width: 32px;
}
&.has-labels {
padding-bottom: variables.$card-padding;
padding-bottom: $card-padding;
}
.labels {
height: 6px;

View File

@@ -6,190 +6,40 @@
<template>
<div v-if="card" class="card-menu" @click.stop.prevent>
<NcButton v-if="card.referenceData"
variant="tertiary"
:title="t('deck', 'Open link')"
type="tertiary"
:title="t('deck','Open link')"
@click="openLink">
<template #icon>
<LinkIcon :size="20" />
</template>
</NcButton>
<NcActions>
<NcActionButton v-if="!hideDetailsEntry" :close-after-click="true" @click="openCard">
<template #icon>
<CardBulletedIcon icon :size="20" decorative />
</template>
{{ t('deck', 'Card details') }}
</NcActionButton>
<NcActionButton v-if="canEdit" :close-after-click="true" @click="editTitle">
<template #icon>
<PencilIcon :size="20" decorative />
</template>
{{ t('deck', 'Edit title') }}
</NcActionButton>
<NcActionButton v-if="canEdit && !isCurrentUserAssigned"
icon="icon-user"
:close-after-click="true"
@click="assignCardToMe()">
{{ t('deck', 'Assign to me') }}
</NcActionButton>
<NcActionButton v-if="canEdit && isCurrentUserAssigned"
icon="icon-user"
:close-after-click="true"
@click="unassignCardFromMe()">
{{ t('deck', 'Unassign myself') }}
</NcActionButton>
<NcActionButton v-if="canEdit"
icon="icon-checkmark"
:close-after-click="true"
@click="changeCardDoneStatus()">
{{ card.done ? t('deck', 'Mark as not done') : t('deck', 'Mark as done') }}
</NcActionButton>
<NcActionButton v-if="canEdit"
icon="icon-external"
:close-after-click="true"
@click="openCardMoveDialog">
{{ t('deck', 'Move/copy card') }}
</NcActionButton>
<NcActionButton v-for="action in cardActions"
:key="action.label"
:close-after-click="true"
:icon="action.icon"
@click="action.callback(cardRichObject)">
{{ action.label }}
</NcActionButton>
<NcActionButton v-if="canEditBoard" :close-after-click="true" @click="archiveUnarchiveCard()">
<template #icon>
<ArchiveIcon :size="20" decorative />
</template>
{{ card.archived ? t('deck', 'Unarchive card') : t('deck', 'Archive card') }}
</NcActionButton>
<NcActionButton v-if="canEdit"
icon="icon-delete"
:close-after-click="true"
@click="deleteCard()">
{{ t('deck', 'Delete card') }}
</NcActionButton>
<CardMenuEntries :card="card" @edit-title="editTitle" />
</NcActions>
</div>
</template>
<script>
import { NcActions, NcButton, NcActionButton } from '@nextcloud/vue'
import { NcActions, NcButton } from '@nextcloud/vue'
import LinkIcon from 'vue-material-design-icons/Link.vue'
import ArchiveIcon from 'vue-material-design-icons/Archive.vue'
import { getCurrentUser } from '@nextcloud/auth'
import CardBulletedIcon from 'vue-material-design-icons/CardBulleted.vue'
import PencilIcon from 'vue-material-design-icons/Pencil.vue'
import { mapGetters, mapState } from 'vuex'
import { showUndo } from '@nextcloud/dialogs'
import { generateUrl } from '@nextcloud/router'
import '@nextcloud/dialogs/style.css'
import { emit } from '@nextcloud/event-bus'
import CardMenuEntries from './CardMenuEntries.vue'
export default {
name: 'CardMenu',
components: { NcActions, NcButton, LinkIcon, NcActionButton, PencilIcon, CardBulletedIcon, ArchiveIcon },
components: { NcActions, NcButton, LinkIcon, CardMenuEntries },
props: {
card: {
type: Object,
default: null,
},
hideDetailsEntry: {
type: Boolean,
default: false,
},
},
emits: ['edit-title'],
computed: {
...mapGetters([
'isArchived',
'boards',
'cardActions',
'stackById',
'boardById',
]),
...mapState({
showArchived: state => state.showArchived,
currentBoard: state => state.currentBoard,
}),
canEdit() {
return !this.card.archived
},
canEditBoard() {
if (this.currentBoard) {
return this.$store.getters.canEdit
}
const board = this.$store.getters.boards.find((item) => item.id === this.card.boardId)
return !!board?.permissions?.PERMISSION_EDIT
},
isCurrentUserAssigned() {
return this.card.assignedUsers.find((item) => item.type === 0 && item.participant.uid === getCurrentUser()?.uid)
},
boardId() {
return this.card?.boardId ? this.card.boardId : Number(this.$route.params.id)
},
cardRichObject() {
return {
id: '' + this.card.id,
name: this.card.title,
boardname: this.boardById(this.boardId)?.title,
stackname: this.stackById(this.card.stackId)?.title,
link: window.location.protocol + '//' + window.location.host + generateUrl('/apps/deck/') + `card/${this.card.id}`,
}
},
},
methods: {
openLink() {
window.open(this.card?.referenceData?.openGraphObject?.link)
return false
},
openCard() {
const boardId = this.card?.boardId ? this.card.boardId : this.$route?.params.id ?? this.currentBoard.id
if (this.$router) {
this.$router?.push({ name: 'card', params: { id: boardId, cardId: this.card.id } }).catch(() => { })
return
}
this.$root.$emit('open-card', this.card.id)
},
editTitle() {
this.$emit('edit-title', this.card.id)
},
deleteCard() {
this.$store.dispatch('deleteCard', this.card)
const undoCard = { ...this.card, deletedAt: 0 }
showUndo(t('deck', 'Card deleted'), () => this.$store.dispatch('cardUndoDelete', undoCard))
if (this.$router.currentRoute.name === 'card') {
this.$router.push({ name: 'board' })
}
},
changeCardDoneStatus() {
this.$store.dispatch('changeCardDoneStatus', { ...this.card, done: !this.card.done })
},
archiveUnarchiveCard() {
this.$store.dispatch('archiveUnarchiveCard', { ...this.card, archived: !this.card.archived })
},
assignCardToMe() {
this.$store.dispatch('assignCardToUser', {
card: this.card,
assignee: {
userId: getCurrentUser()?.uid,
type: 0,
},
})
},
unassignCardFromMe() {
this.$store.dispatch('removeUserFromCard', {
card: this.card,
assignee: {
userId: getCurrentUser()?.uid,
type: 0,
},
})
},
openCardMoveDialog() {
emit('deck:card:show-move-dialog', this.card)
editTitle(id) {
this.$emit('edit-title', id)
},
},
}

View File

@@ -0,0 +1,187 @@
<!--
- SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
- SPDX-License-Identifier: AGPL-3.0-or-later
-->
<template>
<div>
<NcActionButton v-if="!hideDetailsEntry" :close-after-click="true" @click="openCard">
<CardBulletedIcon slot="icon" :size="20" decorative />
{{ t('deck', 'Card details') }}
</NcActionButton>
<NcActionButton v-if="canEdit" :close-after-click="true" @click="editTitle">
<template #icon>
<PencilIcon :size="20" decorative />
</template>
{{ t('deck', 'Edit title') }}
</NcActionButton>
<NcActionButton v-if="canEdit && !isCurrentUserAssigned"
icon="icon-user"
:close-after-click="true"
@click="assignCardToMe()">
{{ t('deck', 'Assign to me') }}
</NcActionButton>
<NcActionButton v-if="canEdit && isCurrentUserAssigned"
icon="icon-user"
:close-after-click="true"
@click="unassignCardFromMe()">
{{ t('deck', 'Unassign myself') }}
</NcActionButton>
<NcActionButton v-if="canEdit"
icon="icon-checkmark"
:close-after-click="true"
@click="changeCardDoneStatus()">
{{ card.done ? t('deck', 'Mark as not done') : t('deck', 'Mark as done') }}
</NcActionButton>
<NcActionButton v-if="canEdit"
icon="icon-external"
:close-after-click="true"
@click="openCardMoveDialog">
{{ t('deck', 'Move/copy card') }}
</NcActionButton>
<NcActionButton v-for="action in cardActions"
:key="action.label"
:close-after-click="true"
:icon="action.icon"
@click="action.callback(cardRichObject)">
{{ action.label }}
</NcActionButton>
<NcActionButton v-if="canEditBoard" :close-after-click="true" @click="archiveUnarchiveCard()">
<template #icon>
<ArchiveIcon :size="20" decorative />
</template>
{{ card.archived ? t('deck', 'Unarchive card') : t('deck', 'Archive card') }}
</NcActionButton>
<NcActionButton v-if="canEdit"
icon="icon-delete"
:close-after-click="true"
@click="deleteCard()">
{{ t('deck', 'Delete card') }}
</NcActionButton>
</div>
</template>
<script>
import { NcActionButton } from '@nextcloud/vue'
import { mapGetters, mapState } from 'vuex'
import ArchiveIcon from 'vue-material-design-icons/ArchiveOutline.vue'
import CardBulletedIcon from 'vue-material-design-icons/CardBulletedOutline.vue'
import PencilIcon from 'vue-material-design-icons/PencilOutline.vue'
import { generateUrl } from '@nextcloud/router'
import { getCurrentUser } from '@nextcloud/auth'
import { showUndo } from '@nextcloud/dialogs'
import '@nextcloud/dialogs/style.css'
import { emit } from '@nextcloud/event-bus'
export default {
name: 'CardMenuEntries',
components: { NcActionButton, ArchiveIcon, CardBulletedIcon, PencilIcon },
props: {
card: {
type: Object,
default: null,
},
hideDetailsEntry: {
type: Boolean,
default: false,
},
},
emits: ['edit-title'],
data() {
return {
modalShow: false,
selectedBoard: '',
selectedStack: '',
stacksFromBoard: [],
}
},
computed: {
...mapGetters([
'isArchived',
'boards',
'cardActions',
'stackById',
'boardById',
]),
...mapState({
showArchived: state => state.showArchived,
currentBoard: state => state.currentBoard,
}),
canEdit() {
return !this.card.archived
},
canEditBoard() {
if (this.currentBoard) {
return this.$store.getters.canEdit
}
const board = this.$store.getters.boards.find((item) => item.id === this.card.boardId)
return !!board?.permissions?.PERMISSION_EDIT
},
isCurrentUserAssigned() {
return this.card.assignedUsers.find((item) => item.type === 0 && item.participant.uid === getCurrentUser()?.uid)
},
boardId() {
return this.card?.boardId ? this.card.boardId : Number(this.$route.params.id)
},
cardRichObject() {
return {
id: '' + this.card.id,
name: this.card.title,
boardname: this.boardById(this.boardId)?.title,
stackname: this.stackById(this.card.stackId)?.title,
link: window.location.protocol + '//' + window.location.host + generateUrl('/apps/deck/') + `card/${this.card.id}`,
}
},
},
methods: {
openCard() {
const boardId = this.card?.boardId ? this.card.boardId : this.$route?.params.id ?? this.currentBoard.id
if (this.$router) {
this.$router?.push({ name: 'card', params: { id: boardId, cardId: this.card.id } }).catch(() => {})
return
}
this.$root.$emit('open-card', this.card.id)
},
editTitle() {
this.$emit('edit-title', this.card.id)
},
deleteCard() {
this.$store.dispatch('deleteCard', this.card)
const undoCard = { ...this.card, deletedAt: 0 }
showUndo(t('deck', 'Card deleted'), () => this.$store.dispatch('cardUndoDelete', undoCard))
if (this.$router.currentRoute.name === 'card') {
this.$router.push({ name: 'board' })
}
},
changeCardDoneStatus() {
this.$store.dispatch('changeCardDoneStatus', { ...this.card, done: !this.card.done })
},
archiveUnarchiveCard() {
this.$store.dispatch('archiveUnarchiveCard', { ...this.card, archived: !this.card.archived })
},
assignCardToMe() {
this.$store.dispatch('assignCardToUser', {
card: this.card,
assignee: {
userId: getCurrentUser()?.uid,
type: 0,
},
})
},
unassignCardFromMe() {
this.$store.dispatch('removeUserFromCard', {
card: this.card,
assignee: {
userId: getCurrentUser()?.uid,
type: 0,
},
})
},
openCardMoveDialog() {
emit('deck:card:show-move-dialog', this.card)
},
},
}
</script>

View File

@@ -151,13 +151,16 @@
</template>
<script>
import { NcModal } from '@nextcloud/vue'
import { NcModal, Tooltip } from '@nextcloud/vue'
export default {
name: 'HelpModal',
components: {
NcModal,
},
directives: {
Tooltip,
},
}
</script>

View File

@@ -10,7 +10,8 @@
:exact="true"
to="/">
<template #icon>
<CalendarIcon :size="20" />
<CalendarIcon v-if="$route.path === '/'" :size="20" />
<CalendarOutlineIcon v-else :size="20" />
</template>
</NcAppNavigationItem>
<AppNavigationBoardCategory id="deck-navigation-all"
@@ -29,7 +30,8 @@
:text="t('deck', 'Archived boards')"
:boards="archivedBoards">
<template #icon>
<ArchiveIcon :size="20" decorative />
<ArchiveIcon v-if="$route.path === '/board/archived'" :size="20" decorative />
<ArchiveOutlineIcon v-else :size="20" decorative />
</template>
</AppNavigationBoardCategory>
<AppNavigationBoardCategory id="deck-navigation-shared"
@@ -112,9 +114,11 @@ import { loadState } from '@nextcloud/initial-state'
import { generateOcsUrl } from '@nextcloud/router'
import { getCurrentUser } from '@nextcloud/auth'
import ArchiveIcon from 'vue-material-design-icons/Archive.vue'
import ArchiveOutlineIcon from 'vue-material-design-icons/ArchiveOutline.vue'
import CalendarIcon from 'vue-material-design-icons/Calendar.vue'
import CalendarOutlineIcon from 'vue-material-design-icons/CalendarOutline.vue'
import DeckIcon from './../icons/DeckIcon.vue'
import ShareVariantIcon from 'vue-material-design-icons/Share.vue'
import ShareVariantIcon from 'vue-material-design-icons/ShareOutline.vue'
import HelpModal from './../modals/HelpModal.vue'
import { subscribe } from '@nextcloud/event-bus'
import AppNavigationImportBoard from './AppNavigationImportBoard.vue'
@@ -133,7 +137,9 @@ export default {
NcSelect,
NcAppNavigationItem,
ArchiveIcon,
ArchiveOutlineIcon,
CalendarIcon,
CalendarOutlineIcon,
DeckIcon,
ShareVariantIcon,
HelpModal,

View File

@@ -13,12 +13,12 @@
</NcColorPicker>
<form @submit.prevent.stop="createBoard">
<NcTextField ref="inputField"
v-model="value"
:disable="loading"
:value.sync="value"
:placeholder="t('deck', 'Board name')"
type="text"
required />
<NcButton variant="tertiary"
<NcButton type="tertiary"
:disabled="loading"
:title="t('deck', 'Cancel edit')"
@click.stop.prevent="cancelEdit">
@@ -26,8 +26,8 @@
<CloseIcon :size="20" />
</template>
</NcButton>
<NcButton variant="tertiary"
type="submit"
<NcButton type="tertiary"
native-type="submit"
:disabled="loading"
:title="t('deck', 'Save board')">
<template #icon>
@@ -77,7 +77,6 @@ export default {
})
},
async createBoard(e) {
alert('createBoard called')
this.loading = true
const title = this.value.trim()
await this.$store.dispatch('createBoard', {
@@ -89,7 +88,6 @@ export default {
this.color = randomColor()
},
cancelEdit(e) {
alert('cancelEdit called')
this.editing = false
this.color = randomColor()
},

View File

@@ -25,7 +25,7 @@
<AccountIcon v-if="board.acl.length > 0" />
</template>
<template v-if="!deleted" #actions>
<template v-if="!deleted" slot="actions">
<template v-if="!isDueSubmenuActive">
<NcActionButton icon="icon-info"
:close-after-click="true"
@@ -129,17 +129,17 @@
:placeholder="t('deck', 'Board name')"
type="text"
required />
<NcButton variant="tertiary"
<NcButton type="tertiary"
:disabled="loading"
type="submit"
native-type="submit"
:title="t('deck', 'Cancel edit')"
@click.stop.prevent="cancelEdit">
<template #icon>
<CloseIcon :size="20" />
</template>
</NcButton>
<NcButton variant="tertiary"
type="submit"
<NcButton type="tertiary"
native-type="submit"
:disabled="loading"
:title="t('deck', 'Save board')">
<template #icon>
@@ -152,11 +152,11 @@
</template>
<script>
import { NcAppNavigationIconBullet, NcAppNavigationItem, NcColorPicker, NcButton, NcTextField, NcActionButton, NcLoadingIcon } from '@nextcloud/vue'
import { NcAppNavigationIconBullet, NcAppNavigationItem, NcColorPicker, NcButton, NcTextField, NcActionButton } from '@nextcloud/vue'
import ClickOutside from 'vue-click-outside'
import ArchiveIcon from 'vue-material-design-icons/Archive.vue'
import ArchiveIcon from 'vue-material-design-icons/ArchiveOutline.vue'
import CloneIcon from 'vue-material-design-icons/ContentDuplicate.vue'
import AccountIcon from 'vue-material-design-icons/Account.vue'
import AccountIcon from 'vue-material-design-icons/AccountOutline.vue'
import CloseIcon from 'vue-material-design-icons/Close.vue'
import CheckIcon from 'vue-material-design-icons/Check.vue'
@@ -186,7 +186,6 @@ export default {
CheckIcon,
BoardCloneModal,
BoardExportModal,
NcLoadingIcon,
},
directives: {
ClickOutside,

View File

@@ -31,6 +31,10 @@ export default {
type: String,
default: '',
},
id: {
type: String,
required: true,
},
text: {
type: String,
required: true,

View File

@@ -5,16 +5,16 @@
<template>
<NcDialog :name="t('deck', 'Clone {boardTitle}', {boardTitle: boardTitle})" :show="true" @close="close(false)">
<div class="modal__content">
<NcCheckboxRadioSwitch v-model="withCards">
<NcCheckboxRadioSwitch :checked.sync="withCards">
{{ t('deck', 'Clone cards') }}
</NcCheckboxRadioSwitch>
<NcCheckboxRadioSwitch v-if="withCards" v-model="withAssignments">
<NcCheckboxRadioSwitch v-if="withCards" :checked.sync="withAssignments">
{{ t('deck', 'Clone assignments') }}
</NcCheckboxRadioSwitch>
<NcCheckboxRadioSwitch v-if="withCards" v-model="withLabels">
<NcCheckboxRadioSwitch v-if="withCards" :checked.sync="withLabels">
{{ t('deck', 'Clone labels') }}
</NcCheckboxRadioSwitch>
<NcCheckboxRadioSwitch v-if="withCards" v-model="withDueDate">
<NcCheckboxRadioSwitch v-if="withCards" :checked.sync="withDueDate">
{{ t('deck', 'Clone due dates') }}
</NcCheckboxRadioSwitch>
<div v-if="withCards" class="accordion" :class="{ 'is-open': accordionOpen }">
@@ -25,10 +25,10 @@
{{ t('deck', 'Advanced options') }}
</div>
<div v-if="accordionOpen" class="accordion__content">
<NcCheckboxRadioSwitch v-if="withCards" v-model="moveCardsToLeftStack">
<NcCheckboxRadioSwitch v-if="withCards" :checked.sync="moveCardsToLeftStack">
{{ t('deck', 'Move all cards to the first list') }}
</NcCheckboxRadioSwitch>
<NcCheckboxRadioSwitch v-if="withCards" v-model="restoreArchivedCards">
<NcCheckboxRadioSwitch v-if="withCards" :checked.sync="restoreArchivedCards">
{{ t('deck', 'Restore archived cards') }}
</NcCheckboxRadioSwitch>
</div>
@@ -39,7 +39,7 @@
<NcButton @click="cancel">
{{ t('deck', 'Cancel') }}
</NcButton>
<NcButton variant="primary" @click="save">
<NcButton type="primary" @click="save">
{{ t('deck', 'Clone') }}
</NcButton>
</template>

View File

@@ -5,13 +5,13 @@
<template>
<NcDialog :name="t('deck', 'Export {boardTitle}', {boardTitle: boardTitle})" @update:open="close">
<div class="modal__content">
<NcCheckboxRadioSwitch v-model="exportFormat"
<NcCheckboxRadioSwitch :checked.sync="exportFormat"
value="json"
type="radio"
name="board_export_format">
{{ t('deck', 'Export as JSON') }}
</NcCheckboxRadioSwitch>
<NcCheckboxRadioSwitch v-model="exportFormat"
<NcCheckboxRadioSwitch :checked.sync="exportFormat"
value="csv"
type="radio"
name="board_export_format">
@@ -27,7 +27,7 @@
<NcButton @click="close">
{{ t('deck', 'Cancel') }}
</NcButton>
<NcButton variant="primary" @click="exportBoard">
<NcButton type="primary" @click="exportBoard">
{{ t('deck', 'Export') }}
</NcButton>
</template>

View File

@@ -145,7 +145,7 @@ export default {
</script>
<style lang="scss" scoped>
@use './../../css/variables';
@import './../../css/variables';
.overview-wrapper {
position: relative;
@@ -162,16 +162,16 @@ export default {
overflow-x: scroll;
display: flex;
align-items: stretch;
padding-left: variables.$board-spacing;
padding-right: variables.$board-spacing;
padding-left: $board-spacing;
padding-right: $board-spacing;
.dashboard-column {
display: flex;
flex-direction: column;
min-width: variables.$stack-width;
width: variables.$stack-width;
margin-left: variables.$stack-spacing;
margin-right: variables.$stack-spacing;
min-width: $stack-width;
width: $stack-width;
margin-left: $stack-spacing;
margin-right: $stack-spacing;
h3 {
font-size: var(--default-font-size);

View File

@@ -4,7 +4,7 @@
-->
<template>
<div v-if="searchQuery !== ''" class="global-search">
<div v-if="searchQuery!==''" class="global-search">
<h2>
<NcRichText :text="t('deck', 'Search for {searchQuery} in all boards')" :arguments="queryStringArgs" />
<div v-if="loading" class="icon-loading-small" />
@@ -19,13 +19,13 @@
:key="card.id"
:standalone="true" />
<Placeholder v-if="loading" />
<!-- <InfiniteLoading :identifier="searchQuery" @infinite="infiniteHandler">
<InfiniteLoading :identifier="searchQuery" @infinite="infiniteHandler">
<div slot="spinner" />
<div slot="no-more" />
<div slot="no-results">
{{ t('deck', 'No results found') }}
</div>
</InfiniteLoading> -->
</InfiniteLoading>
</div>
<div v-else>
<p>{{ t('deck', 'No results found') }}</p>
@@ -39,7 +39,7 @@ import CardItem from '../cards/CardItem.vue'
import { mapState } from 'vuex'
import axios from '@nextcloud/axios'
import { generateOcsUrl } from '@nextcloud/router'
// import InfiniteLoading from 'v3-infinite-loading'
import InfiniteLoading from 'vue-infinite-loading'
import Placeholder from './Placeholder.vue'
import { NcActions, NcActionButton, NcRichText } from '@nextcloud/vue'
@@ -70,14 +70,7 @@ function search({ query, cursor }) {
export default {
name: 'GlobalSearchResults',
components: {
CardItem,
// InfiniteLoading,
NcRichText,
Placeholder,
NcActions,
NcActionButton,
},
components: { CardItem, InfiniteLoading, NcRichText, Placeholder, NcActions, NcActionButton },
data() {
return {
results: [],
@@ -162,11 +155,11 @@ export default {
</script>
<style lang="scss" scoped>
@use '../../css/variables';
@import '../../css/variables';
.global-search {
width: 100%;
padding: variables.$board-spacing + variables.$stack-spacing;
padding: $board-spacing + $stack-spacing;
padding-bottom: 0;
overflow: hidden;
min-height: 35vh;
@@ -182,7 +175,6 @@ export default {
top: 10px;
right: 10px;
}
.search-wrapper {
overflow: scroll;
height: 100%;
@@ -190,14 +182,13 @@ export default {
padding: 10px;
}
h2>div {
h2 > div {
display: inline-block;
&.icon-loading-small {
margin-right: 20px;
}
}
h2:deep(span) {
background-color: var(--color-background-dark);
padding: 3px;
@@ -208,14 +199,13 @@ export default {
display: flex;
flex-wrap: wrap;
&>div {
& > div {
flex-grow: 0;
}
}
&:deep(.card) {
width: variables.$stack-width;
margin-right: variables.$stack-spacing;
width: $stack-width;
margin-right: $stack-spacing;
}
}
</style>

View File

@@ -58,18 +58,18 @@ export default {
</script>
<style lang="scss" scoped>
@use '../../css/variables';
@import '../../css/variables';
$clickable-area: var(--default-clickable-area);
.card--placeholder {
width: variables.$stack-width;
margin-right: variables.$stack-spacing;
padding: variables.$card-padding;
width: $stack-width;
margin-right: $stack-spacing;
padding: $card-padding;
transition: box-shadow 0.1s ease-in-out;
box-shadow: 0 0 2px 0 var(--color-box-shadow);
border-radius: var(--border-radius-large);
font-size: 100%;
margin-bottom: variables.$card-spacing;
margin-bottom: $card-spacing;
height: 100px;
}

View File

@@ -3,34 +3,38 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import Vue from 'vue'
import './../css/collections.css'
import FileSharingPicker from './views/FileSharingPicker.js'
import { buildSelector } from './helpers/selector.js'
import './shared-init.js'
export function initCollections() {
window.addEventListener('DOMContentLoaded', () => {
if (OCA.Sharing && OCA.Sharing.ShareSearch) {
OCA.Sharing.ShareSearch.addNewResult(FileSharingPicker)
}
Vue.prototype.t = t
Vue.prototype.n = n
Vue.prototype.OC = OC
window.OCP.Collaboration.registerType('deck', {
action: () => {
const BoardSelector = () => import('./BoardSelector.vue')
return buildSelector(BoardSelector)
},
typeString: t('deck', 'Link to a board'),
typeIconClass: 'icon-deck',
})
window.addEventListener('DOMContentLoaded', () => {
if (OCA.Sharing && OCA.Sharing.ShareSearch) {
OCA.Sharing.ShareSearch.addNewResult(FileSharingPicker)
}
window.OCP.Collaboration.registerType('deck-card', {
action: () => {
const CardSelector = () => import('./CardSelector.vue')
return buildSelector(CardSelector)
},
typeString: t('deck', 'Link to a card'),
typeIconClass: 'icon-deck',
})
window.OCP.Collaboration.registerType('deck', {
action: () => {
const BoardSelector = () => import('./BoardSelector.vue')
return buildSelector(BoardSelector)
},
typeString: t('deck', 'Link to a board'),
typeIconClass: 'icon-deck',
})
}
window.OCP.Collaboration.registerType('deck-card', {
action: () => {
const CardSelector = () => import('./CardSelector.vue')
return buildSelector(CardSelector)
},
typeString: t('deck', 'Link to a card'),
typeIconClass: 'icon-deck',
})
})

View File

@@ -3,7 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import { registerWidget, registerCustomPickerElement, NcCustomPickerRenderResult } from '@nextcloud/vue'
import { registerWidget, registerCustomPickerElement, NcCustomPickerRenderResult } from '@nextcloud/vue/dist/Functions/registerReference.js'
import { translate, translatePlural } from '@nextcloud/l10n'
import './shared-init.js'

View File

@@ -2,10 +2,11 @@
* SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import { createApp } from 'vue'
import Vue from 'vue'
import App from './App.vue'
import router from './router.js'
import store from './store/main.js'
import { sync } from 'vuex-router-sync'
import { translate, translatePlural } from '@nextcloud/l10n'
import { showError } from '@nextcloud/dialogs'
import { subscribe } from '@nextcloud/event-bus'
@@ -13,33 +14,27 @@ import ClickOutside from 'vue-click-outside'
import './shared-init.js'
import './models/index.js'
import './sessions.js'
import { initCollections } from './init-collections.js'
// the server snap.js conflicts with vertical scrolling so we disable it
document.body.setAttribute('data-snap-ignore', 'true')
const app = createApp(App)
sync(store, router)
app.config.globalProperties.t = translate
app.config.globalProperties.n = translatePlural
app.config.globalProperties.OC = OC
Vue.prototype.t = translate
Vue.prototype.n = translatePlural
initCollections({ t, n, OC })
Vue.directive('click-outside', ClickOutside)
app.directive('click-outside', ClickOutside)
app.directive('focus', {
mounted(el) {
Vue.directive('focus', {
inserted(el) {
el.focus()
},
})
app.config.errorHandler = (err, vm, info) => {
Vue.config.errorHandler = (err, vm, info) => {
if (err.response && err.response.data.message) {
const errorMessage = translate('deck', 'Something went wrong')
showError(
`${errorMessage}: ${err.response.data.status} ${err.response.data.message}`,
)
const errorMessage = t('deck', 'Something went wrong')
showError(`${errorMessage}: ${err.response.data.status} ${err.response.data.message}`)
}
console.error(err)
}
@@ -52,14 +47,16 @@ window.addEventListener('DOMContentLoaded', () => {
window.OCA.Files = {}
}
// register unused client for the sidebar to have access to its parser methods
Object.assign(
window.OCA.Files,
{ App: { fileList: { filesClient: OC.Files.getClient() } } },
window.OCA.Files,
)
Object.assign(window.OCA.Files, { App: { fileList: { filesClient: OC.Files.getClient() } } }, window.OCA.Files)
})
app.mixin({
/* eslint-disable-next-line no-new */
new Vue({
el: '#content',
// eslint-disable-next-line vue/match-component-file-name
name: 'Deck',
router,
store,
data() {
return {
time: Date.now(),
@@ -78,7 +75,7 @@ app.mixin({
this.time = Date.now()
}, 1000)
},
beforeUnmount() {
beforeDestroy() {
clearInterval(this.interval)
},
methods: {
@@ -89,12 +86,9 @@ app.mixin({
this.$store.commit('setSearchQuery', '')
},
},
render: h => h(App),
})
app.use(router)
app.use(store)
app.mount('#content')
if (!window.OCA.Deck) {
window.OCA.Deck = {}
}

View File

@@ -26,8 +26,7 @@ export default {
return
}
this.uploadQueue[file.name] = { name: file.name, progress: 0 }
this.$set(this.uploadQueue, file.name, { name: file.name, progress: 0 })
const bodyFormData = new FormData()
bodyFormData.append('cardId', this.cardId)
bodyFormData.append('type', type)
@@ -40,7 +39,7 @@ export default {
onUploadProgress: (e) => {
const percentCompleted = Math.round((e.loaded * 100) / e.total)
console.debug(percentCompleted)
this.uploadQueue[file.name].progress = percentCompleted
this.$set(this.uploadQueue[file.name], 'progress', percentCompleted)
},
})
} catch (err) {
@@ -51,7 +50,7 @@ export default {
showError(err.response.data ? err.response.data.message : 'Failed to upload file')
}
}
delete this.uploadQueue[file.name]
this.$delete(this.uploadQueue, file.name)
})
},

View File

@@ -3,7 +3,8 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import { createRouter, createWebHistory } from 'vue-router'
import Vue from 'vue'
import Router from 'vue-router'
import { generateUrl, getRootUrl } from '@nextcloud/router'
import { BOARD_FILTERS } from './store/main.js'
import Boards from './components/boards/Boards.vue'
@@ -13,14 +14,17 @@ import BoardSidebar from './components/board/BoardSidebar.vue'
import CardSidebar from './components/card/CardSidebar.vue'
import Overview from './components/overview/Overview.vue'
Vue.use(Router)
// We apply a dynamic base URL depending on the URL used in the browser
const baseUrl = generateUrl('/apps/deck/')
const webRootWithIndexPHP = getRootUrl() + '/index.php'
const doesURLContainIndexPHP = window.location.pathname.startsWith(webRootWithIndexPHP)
const currentBaseUrl = doesURLContainIndexPHP ? baseUrl : baseUrl.replace('/index.php/', '/')
const router = createRouter({
history: createWebHistory(currentBaseUrl),
const router = new Router({
mode: 'history',
base: currentBaseUrl,
linkActiveClass: 'active',
routes: [
{

View File

@@ -4,6 +4,7 @@
*/
import { AttachmentApi } from './../services/AttachmentApi.js'
import Vue from 'vue'
const apiClient = new AttachmentApi()
@@ -23,20 +24,20 @@ export default {
mutations: {
createAttachment(state, { cardId, attachment }) {
if (typeof state.attachments[cardId] === 'undefined') {
state.attachments[cardId] = [attachment]
Vue.set(state.attachments, cardId, [attachment])
} else {
state.attachments[cardId].push(attachment)
}
},
createAttachments(state, { cardId, attachments }) {
state.attachments[cardId] = attachments
Vue.set(state.attachments, cardId, attachments)
},
updateAttachment(state, { cardId, attachment }) {
const existingIndex = state.attachments[attachment.cardId].findIndex(a => a.id === attachment.id && a.type === attachment.type)
if (existingIndex !== -1) {
state.attachments[cardId][existingIndex] = attachment
Vue.set(state.attachments[cardId], existingIndex, attachment)
}
},

View File

@@ -5,6 +5,7 @@
import { CardApi } from './../services/CardApi.js'
import moment from 'moment'
import Vue from 'vue'
const apiClient = new CardApi()
@@ -189,7 +190,7 @@ export default {
const existingIndex = state.cards.findIndex(_card => _card.id === card.id)
if (existingIndex !== -1) {
const existingCard = state.cards.find(_card => _card.id === card.id)
state.cards[existingIndex] = { ...existingCard, ...card }
Vue.set(state.cards, existingIndex, Object.assign({}, existingCard, card))
} else {
state.cards.push(card)
}
@@ -203,15 +204,15 @@ export default {
updateCard(state, card) {
const existingIndex = state.cards.findIndex(_card => _card.id === card.id)
if (existingIndex !== -1) {
state.cards[existingIndex] = { ...state.cards[existingIndex], ...card }
Vue.set(state.cards, existingIndex, Object.assign({}, state.cards[existingIndex], card))
}
},
updateCardsReorder(state, cards) {
for (const newCard of cards) {
const existingIndex = state.cards.findIndex(_card => _card.id === newCard.id)
if (existingIndex !== -1) {
state.cards[existingIndex].order = newCard.order
state.cards[existingIndex].stackId = newCard.stackId
Vue.set(state.cards[existingIndex], 'order', newCard.order)
Vue.set(state.cards[existingIndex], 'stackId', newCard.stackId)
}
}
},
@@ -233,26 +234,26 @@ export default {
updateCardProperty(state, { card, property }) {
const existingIndex = state.cards.findIndex(_card => _card.id === card.id)
if (existingIndex !== -1) {
state.cards[existingIndex][property] = card[property]
state.cards[existingIndex].lastModifiedBy = Date.now() / 1000
Vue.set(state.cards[existingIndex], property, card[property])
Vue.set(state.cards[existingIndex], 'lastModified', Date.now() / 1000)
}
},
cardSetAttachmentCount(state, { cardId, count }) {
const existingIndex = state.cards.findIndex(_card => _card.id === cardId)
if (existingIndex !== -1) {
state.cards[existingIndex].attachmentCount = count
Vue.set(state.cards[existingIndex], 'attachmentCount', count)
}
},
cardIncreaseAttachmentCount(state, cardId) {
const existingIndex = state.cards.findIndex(_card => _card.id === cardId)
if (existingIndex !== -1) {
state.cards[existingIndex].attachmentCount = state.cards[existingIndex].attachmentCount + 1
Vue.set(state.cards[existingIndex], 'attachmentCount', state.cards[existingIndex].attachmentCount + 1)
}
},
cardDecreaseAttachmentCount(state, cardId) {
const existingIndex = state.cards.findIndex(_card => _card.id === cardId)
if (existingIndex !== -1) {
state.cards[existingIndex].attachmentCount = state.cards[existingIndex].attachmentCount - 1
Vue.set(state.cards[existingIndex], 'attachmentCount', state.cards[existingIndex].attachmentCount - 1)
}
},
addNewCard(state, card) {

View File

@@ -4,6 +4,7 @@
*/
import { CommentApi } from '../services/CommentApi.js'
import Vue from 'vue'
const apiClient = new CommentApi()
@@ -33,10 +34,10 @@ export default {
},
addComments(state, { comments, cardId }) {
if (state.comments[cardId] === undefined) {
state.comments[cardId] = {
hasMore: comments.length >= 0,
Vue.set(state.comments, cardId, {
hasMore: comments.length > 0,
comments: [...comments],
}
})
} else {
const newComments = comments.filter((comment) => {
return state.comments[cardId].comments.findIndex((item) => item.id === comment.id) === -1
@@ -58,11 +59,11 @@ export default {
},
markCommentsAsRead(state, cardId) {
state.comments[cardId].comments.forEach(_comment => {
_comment.isUnread = false
Vue.set(_comment, 'isUnread', false)
})
},
setReplyTo(state, comment) {
state.replyTo = comment
Vue.set(state, 'replyTo', comment)
},
},
actions: {

View File

@@ -6,7 +6,8 @@
import 'url-search-params-polyfill'
import { loadState } from '@nextcloud/initial-state'
import { createStore } from 'vuex'
import Vue from 'vue'
import Vuex from 'vuex'
import axios from '@nextcloud/axios'
import { generateOcsUrl, generateUrl } from '@nextcloud/router'
import { BoardApi } from '../services/BoardApi.js'
@@ -17,6 +18,7 @@ import comment from './comment.js'
import trashbin from './trashbin.js'
import attachment from './attachment.js'
import overview from './overview.js'
Vue.use(Vuex)
const apiClient = new BoardApi()
const debug = process.env.NODE_ENV !== 'production'
@@ -27,7 +29,7 @@ export const BOARD_FILTERS = {
SHARED: 'shared',
}
const store = createStore({
export default new Vuex.Store({
modules: {
actions,
stack,
@@ -128,10 +130,10 @@ const store = createStore({
},
mutations: {
setFullApp(state, isFullApp) {
state.isFullApp = isFullApp
Vue.set(state, 'isFullApp', isFullApp)
},
setHasCardSaveError(state, hasCardSaveError) {
state.hasCardSaveError = hasCardSaveError
Vue.set(state, 'hasCardSaveError', hasCardSaveError)
},
SET_CONFIG(state, { key, value }) {
const [scope, id, configKey] = key.split(':', 3)
@@ -143,11 +145,11 @@ const store = createStore({
})
if (indexExisting > -1) {
state.boards[indexExisting].settings[configKey] = value
Vue.set(state.boards[indexExisting].settings, configKey, value)
}
break
default:
state.config[key] = value
Vue.set(state.config, key, value)
}
},
setSearchQuery(state, searchQuery) {
@@ -160,7 +162,7 @@ const store = createStore({
Object.keys(filter).forEach((key) => {
switch (key) {
case 'due':
state.filter[key] = filter.due
Vue.set(state.filter, key, filter.due)
break
default:
filter[key].forEach((item) => {
@@ -187,7 +189,7 @@ const store = createStore({
})
if (indexExisting > -1) {
state.boards[indexExisting] = board
Vue.set(state.boards, indexExisting, board)
} else {
state.boards.push(board)
}
@@ -199,7 +201,7 @@ const store = createStore({
})
if (indexExisting > -1) {
state.boards[indexExisting] = board
Vue.set(state.boards, indexExisting, board)
} else {
state.boards.push(board)
}
@@ -232,7 +234,7 @@ const store = createStore({
state.boards = boards
},
setSharees(state, shareesUsersAndGroups) {
state.sharees = shareesUsersAndGroups.exact.users
Vue.set(state, 'sharees', shareesUsersAndGroups.exact.users)
state.sharees.push(...shareesUsersAndGroups.exact.groups)
state.sharees.push(...shareesUsersAndGroups.exact.circles)
@@ -282,7 +284,7 @@ const store = createStore({
updateAclFromCurrentBoard(state, acl) {
for (const acl_ in state.currentBoard.acl) {
if (state.currentBoard.acl[acl_].participant.uid === acl.participant.uid) {
state.currentBoard.acl[acl_] = acl
Vue.set(state.currentBoard.acl, acl_, acl)
break
}
}
@@ -298,7 +300,7 @@ const store = createStore({
}
if (removeIndex > -1) {
state.currentBoard.acl.splice(removeIndex, 1)
Vue.delete(state.currentBoard.acl, removeIndex)
}
},
TOGGLE_SHORTCUT_LOCK(state, lock) {
@@ -529,5 +531,3 @@ const store = createStore({
},
},
})
export default store

View File

@@ -3,7 +3,10 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import Vue from 'vue'
import Vuex from 'vuex'
import { OverviewApi } from '../services/OverviewApi.js'
Vue.use(Vuex)
const apiClient = new OverviewApi()
export default {

View File

@@ -3,6 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import Vue from 'vue'
import { StackApi } from './../services/StackApi.js'
import applyOrderToArray from './../helpers/applyOrderToArray.js'
@@ -25,7 +26,7 @@ export default {
const existingIndex = state.stacks.findIndex(_stack => _stack.id === stack.id)
if (existingIndex !== -1) {
const existingStack = state.stacks.find(_stack => _stack.id === stack.id)
state.stacks[existingIndex] = { ...existingStack, ...stack }
Vue.set(state.stacks, existingIndex, Object.assign({}, existingStack, stack))
} else {
state.stacks.push(stack)
}

View File

@@ -33,7 +33,7 @@ import DeckIcon from '../components/icons/DeckIcon.vue'
import { BoardApi } from './../services/BoardApi.js'
import store from './../store/main.js'
import { NcUserBubble } from '@nextcloud/vue'
import NcUserBubble from '@nextcloud/vue/dist/Components/NcUserBubble.js'
import moment from '@nextcloud/moment'
import { generateUrl } from '@nextcloud/router'

View File

@@ -66,7 +66,7 @@
</template>
<script>
import CalendarBlankIcon from 'vue-material-design-icons/CalendarBlank.vue'
import CalendarBlankIcon from 'vue-material-design-icons/CalendarBlankOutline.vue'
import TextIcon from 'vue-material-design-icons/Text.vue'
import CardBulletedOutlineIcon from 'vue-material-design-icons/CardBulletedOutline.vue'

View File

@@ -78,7 +78,7 @@
</template>
<script>
import CalendarBlankIcon from 'vue-material-design-icons/CalendarBlank.vue'
import CalendarBlankIcon from 'vue-material-design-icons/CalendarBlankOutline.vue'
import TextIcon from 'vue-material-design-icons/Text.vue'
import CardBulletedOutlineIcon from 'vue-material-design-icons/CardBulletedOutline.vue'
import CommentProcessingOutlineIcon from 'vue-material-design-icons/CommentProcessingOutline.vue'

View File

@@ -82,7 +82,7 @@
{{ t('deck', 'Cancel') }}
</NcButton>
<NcButton :disabled="loading || !isBoardAndStackChoosen"
variant="primary"
type="primary"
@click="createCard">
{{ t('deck', 'Create card') }}
</NcButton>
@@ -212,8 +212,8 @@ export default {
},
},
beforeMount() {
this.card.title = this.title
this.card.description = this.description
this.$set(this.card, 'title', this.title)
this.$set(this.card, 'description', this.description)
this.fetchBoards()
},
mounted() {
@@ -276,10 +276,11 @@ export default {
}
},
onSelectLabel(label) {
if (!label.id) return
this.card.labels.push(label)
},
onRemoveLabel(removedLabel) {
this.card.labels = this.card.label.filter(label => label.id !== removedLabel.id)
this.card.labels = this.card.labels.filter(label => label.id !== removedLabel.id)
},
onSelectUser(user) {
this.card.assignedUsers.push(user)

View File

@@ -1 +1 @@
81091
81373

View File

@@ -1,7 +1,7 @@
{
"require-dev": {
"phpunit/phpunit": "~9",
"behat/behat": "~3.21.1",
"behat/behat": "~3.23.0",
"guzzlehttp/guzzle": "7.9.2",
"jarnaiz/behat-junit-formatter": "^1.3",
"sabre/dav": "4.7.0",

View File

@@ -475,9 +475,6 @@ class CardServiceTest extends TestCase {
$label->setBoardId(1);
$this->cardMapper->expects($this->once())->method('find')->willReturn($card);
$this->cardMapper->expects($this->once())->method('removeLabel');
$this->cardMapper->expects($this->once())
->method('findBoardId')
->willReturn(1);
$this->labelMapper->expects($this->once())
->method('find')
->willReturn($label);

View File

@@ -347,9 +347,8 @@ class PermissionServiceTest extends \Test\TestCase {
->method('__call')
->with('getOwner', [])
->willReturn('user1');
$this->aclMapper->expects($this->once())
->method('findAll')
->with(123)
$board->expects($this->any())
->method('getAcl')
->willReturn([$aclUser, $aclGroup]);
$this->boardMapper->expects($this->once())
->method('find')

View File

@@ -7,7 +7,7 @@ const isDevServer = process.env.WEBPACK_SERVE
webpackConfig.entry = {
...webpackConfig.entry,
// collections: path.join(__dirname, 'src', 'init-collections.js'),
collections: path.join(__dirname, 'src', 'init-collections.js'),
dashboard: path.join(__dirname, 'src', 'init-dashboard.js'),
calendar: path.join(__dirname, 'src', 'init-calendar.js'),
talk: path.join(__dirname, 'src', 'init-talk.js'),
@@ -22,9 +22,6 @@ if (isDevServer) {
})
)
} else {
webpackConfig.output.clean = {
keep: /\webpack-stats\.json$/,
}
webpackConfig.stats = {
context: path.resolve(__dirname, 'src'),
assets: true,
@@ -33,5 +30,7 @@ if (isDevServer) {
modules: true,
}
}
// Workaround for https://github.com/nextcloud/webpack-vue-config/pull/432 causing problems with nextcloud-vue-collections
webpackConfig.resolve.alias = {}
module.exports = webpackConfig