Compare commits
319 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3486e0f24c | ||
|
|
9519033881 | ||
|
|
fc1f3fd10a | ||
|
|
c483b042fd | ||
|
|
3d26acd0ba | ||
|
|
dd23f7b0d3 | ||
|
|
a12043357a | ||
|
|
2bd5d5532d | ||
|
|
ef72c08c11 | ||
|
|
3c3ff391a6 | ||
|
|
29361b3ee7 | ||
|
|
a421a62fb5 | ||
|
|
2392308f58 | ||
|
|
26cc02bea1 | ||
|
|
9ecdc84148 | ||
|
|
af6a099f59 | ||
|
|
b885ec4b80 | ||
|
|
e9e8e26fb5 | ||
|
|
1e2eb5ae2f | ||
|
|
d445ae7527 | ||
|
|
cef8fe8b0d | ||
|
|
98b66d0b5d | ||
|
|
81733002e5 | ||
|
|
80b729c944 | ||
|
|
c286ce3859 | ||
|
|
f31033de72 | ||
|
|
79e83e56ba | ||
|
|
09176b3ae6 | ||
|
|
ed85991683 | ||
|
|
cbf1dc790d | ||
|
|
8a1c1c4690 | ||
|
|
0c80b60c6d | ||
|
|
0f904e65f4 | ||
|
|
e1b5d6d557 | ||
|
|
eca6b1f4f0 | ||
|
|
7dfdae86bf | ||
|
|
cf491c5ad0 | ||
|
|
63cddda8de | ||
|
|
ad17f558ce | ||
|
|
4134818a85 | ||
|
|
85a7e888e7 | ||
|
|
062025873b | ||
|
|
2262cf00c7 | ||
|
|
ec022909de | ||
|
|
8de5ef1255 | ||
|
|
c6a0cfa172 | ||
|
|
5002a3df29 | ||
|
|
cac42bac12 | ||
|
|
1bef8004ac | ||
|
|
3b9efba8ab | ||
|
|
f10e1a21fe | ||
|
|
af36323e53 | ||
|
|
9c1ae577fd | ||
|
|
532516b4c4 | ||
|
|
02f3f821b5 | ||
|
|
52cd5f9881 | ||
|
|
d718aafc74 | ||
|
|
6f475b7acc | ||
|
|
ee2fc04fa1 | ||
|
|
a5217a49d3 | ||
|
|
c241ee54fe | ||
|
|
ff4ee6ced6 | ||
|
|
e72a3d34fd | ||
|
|
120b4ad981 | ||
|
|
0d35859ab1 | ||
|
|
db9e367633 | ||
|
|
2537aaa6ea | ||
|
|
e7c15b6154 | ||
|
|
9016e5020d | ||
|
|
f8d811463e | ||
|
|
b60b5d4225 | ||
|
|
e19befa2df | ||
|
|
5ca11c7515 | ||
|
|
4ec9aa3cb6 | ||
|
|
571d764209 | ||
|
|
5230a76442 | ||
|
|
284d8642f6 | ||
|
|
6b6fbab98d | ||
|
|
cc3e946880 | ||
|
|
e131aa70cf | ||
|
|
d643ea75a2 | ||
|
|
8f04c37275 | ||
|
|
5251e69830 | ||
|
|
33f24e5add | ||
|
|
1d16341d0f | ||
|
|
8220872eba | ||
|
|
73df3588e5 | ||
|
|
dbca67dec0 | ||
|
|
9fd46c2e43 | ||
|
|
9bfc39b316 | ||
|
|
e9fb6616d9 | ||
|
|
e4a4ab5912 | ||
|
|
9e7261e5d5 | ||
|
|
2af2e7c9cc | ||
|
|
2dc9eaf74e | ||
|
|
62318fedef | ||
|
|
d8c640d0a4 | ||
|
|
47f546fb12 | ||
|
|
fc0571aeda | ||
|
|
8695641c2a | ||
|
|
894e17aaef | ||
|
|
cd3b7e7fd9 | ||
|
|
ab6d12cc5f | ||
|
|
a8db7a90f1 | ||
|
|
19b4d0ac21 | ||
|
|
1dec7be713 | ||
|
|
92a0ef904f | ||
|
|
f389f834f0 | ||
|
|
c035a6be73 | ||
|
|
d1498486eb | ||
|
|
408a19ba9a | ||
|
|
9523aa9eeb | ||
|
|
3d74323be4 | ||
|
|
3d14e3f916 | ||
|
|
cce5bd8a7d | ||
|
|
62ccab6e96 | ||
|
|
9f8e7258b5 | ||
|
|
2ca00fed08 | ||
|
|
22cb32e197 | ||
|
|
e1391efbef | ||
|
|
4633ddc153 | ||
|
|
a96ccc3bfd | ||
|
|
14bcab8c8a | ||
|
|
40f0f3d194 | ||
|
|
32e5f6dd6b | ||
|
|
5f2235a91f | ||
|
|
deca12ddd3 | ||
|
|
31d6794490 | ||
|
|
90938d5f58 | ||
|
|
0c7768b36d | ||
|
|
d14c7810ee | ||
|
|
de5153337d | ||
|
|
bd405122e2 | ||
|
|
e7d6233796 | ||
|
|
25bb72c3dc | ||
|
|
487c626a73 | ||
|
|
6b0182ea70 | ||
|
|
ca6fe65580 | ||
|
|
498ed9dfff | ||
|
|
32a2a4ebf5 | ||
|
|
4bd1b70a5e | ||
|
|
71b78e8ec3 | ||
|
|
2d6fc18218 | ||
|
|
b7554a06d2 | ||
|
|
35a8fee3b3 | ||
|
|
4fe94e65ad | ||
|
|
80fa93716b | ||
|
|
0145593cba | ||
|
|
af712ddb56 | ||
|
|
f0deb93cb7 | ||
|
|
781cfc11c7 | ||
|
|
97e45ebc69 | ||
|
|
c4bc945b1e | ||
|
|
2bd12ed7b5 | ||
|
|
658d358e70 | ||
|
|
3e6a80eb37 | ||
|
|
5408d4f9c5 | ||
|
|
6e5fd9e25a | ||
|
|
9fbdafbe73 | ||
|
|
9403fb1759 | ||
|
|
691abb02d8 | ||
|
|
3bb99a9001 | ||
|
|
74e0149a6d | ||
|
|
c5d83e662c | ||
|
|
376c7c7d07 | ||
|
|
a52664e9e4 | ||
|
|
f573abe279 | ||
|
|
975af7c056 | ||
|
|
f2456d796c | ||
|
|
c7c9302109 | ||
|
|
989db4702c | ||
|
|
9de5f12f4b | ||
|
|
9338ebb561 | ||
|
|
0d9cdc5f1e | ||
|
|
f66c71ee55 | ||
|
|
d742bc097b | ||
|
|
53386a7f1a | ||
|
|
cfbc18deb9 | ||
|
|
bdf4631504 | ||
|
|
a0f93a81d2 | ||
|
|
d9b086f146 | ||
|
|
b8b3ac3516 | ||
|
|
118959795f | ||
|
|
c93aaeb9bf | ||
|
|
f42c82274f | ||
|
|
fff9c4f7a2 | ||
|
|
3eb5ccbbe2 | ||
|
|
cc61f3d4e0 | ||
|
|
209adc1e7a | ||
|
|
e26f06be8f | ||
|
|
c99b4bf4ab | ||
|
|
296e7abf14 | ||
|
|
c6ef07ceb0 | ||
|
|
4e937bd03a | ||
|
|
84943c5889 | ||
|
|
4ed71b7a63 | ||
|
|
4ab8078103 | ||
|
|
6b75a1ab1b | ||
|
|
76e3a3a25e | ||
|
|
9503de4716 | ||
|
|
3340ccec6f | ||
|
|
a90e099113 | ||
|
|
aa69495075 | ||
|
|
11eb779beb | ||
|
|
836e2b33df | ||
|
|
c63b72bf2e | ||
|
|
c20008dacc | ||
|
|
edacda1377 | ||
|
|
2f0ad2d639 | ||
|
|
745d76c74b | ||
|
|
3b7f49de55 | ||
|
|
e336bd98b2 | ||
|
|
f62e87cffa | ||
|
|
d4d716b1f5 | ||
|
|
6e89dd48bc | ||
|
|
2bbd572cb5 | ||
|
|
17543eaf94 | ||
|
|
4f4e9fa5c7 | ||
|
|
d0060604a6 | ||
|
|
9f8df2bbd4 | ||
|
|
139cca1ae8 | ||
|
|
32054adcb5 | ||
|
|
764dd1e995 | ||
|
|
b65fde069f | ||
|
|
bec68eb5c3 | ||
|
|
8dca76f9f0 | ||
|
|
13ed30e2bc | ||
|
|
a7ff79605d | ||
|
|
b5bebac3c2 | ||
|
|
756d78f78a | ||
|
|
7e55cb18b3 | ||
|
|
b834ef664a | ||
|
|
1ee0e16f9e | ||
|
|
63434d7b63 | ||
|
|
d9f993dc5b | ||
|
|
9090c13417 | ||
|
|
0630dafef9 | ||
|
|
150ab7b83a | ||
|
|
11cc569914 | ||
|
|
eaf58e0fc9 | ||
|
|
da994c5ecd | ||
|
|
cef4cc6a4d | ||
|
|
d761323887 | ||
|
|
0857270a48 | ||
|
|
df178369c0 | ||
|
|
8c3edf077d | ||
|
|
ac477a58c3 | ||
|
|
504f977739 | ||
|
|
00e813295b | ||
|
|
300d300c45 | ||
|
|
1514f9a737 | ||
|
|
f4fe271b39 | ||
|
|
1c01881eb7 | ||
|
|
af1564d8e5 | ||
|
|
35515ce157 | ||
|
|
fd62ab7a59 | ||
|
|
1557797926 | ||
|
|
90a8b479f6 | ||
|
|
c2fae6b2d7 | ||
|
|
89a3f4fc26 | ||
|
|
7aa94c74d7 | ||
|
|
33993418ac | ||
|
|
75a2d9d54c | ||
|
|
b1a3c6b237 | ||
|
|
437704abb3 | ||
|
|
0e09548e69 | ||
|
|
37834cb926 | ||
|
|
7dd3bb49f4 | ||
|
|
fdf1eaeaed | ||
|
|
4cc88c8b64 | ||
|
|
db331ecb72 | ||
|
|
c2757bec7d | ||
|
|
e074eac092 | ||
|
|
d5166c74e5 | ||
|
|
226e3c8212 | ||
|
|
a680915a89 | ||
|
|
b8ff06e5d2 | ||
|
|
5a108b64b0 | ||
|
|
00630587af | ||
|
|
b02cf925a1 | ||
|
|
aaa26575dd | ||
|
|
aebb3cef03 | ||
|
|
18a7ae3a1a | ||
|
|
6c84c67970 | ||
|
|
d449acde30 | ||
|
|
c1e700cefa | ||
|
|
30df03948c | ||
|
|
15ea081daa | ||
|
|
0f71741c46 | ||
|
|
585f0999a3 | ||
|
|
d51f645299 | ||
|
|
ebbe4eb802 | ||
|
|
d6c94f44d9 | ||
|
|
86345a6338 | ||
|
|
2c77d8a589 | ||
|
|
16cbbd4805 | ||
|
|
8aa77679c8 | ||
|
|
e6cff5bbb6 | ||
|
|
86ed24744c | ||
|
|
01ed3625dc | ||
|
|
cc9dea1f2b | ||
|
|
b16ade905c | ||
|
|
ee1bba7d99 | ||
|
|
3407097e95 | ||
|
|
47ac3e6082 | ||
|
|
75110bed47 | ||
|
|
74f0106718 | ||
|
|
958d50d9b7 | ||
|
|
5f4aa017b6 | ||
|
|
92c2a58f50 | ||
|
|
75bf0dffe6 | ||
|
|
45a10f0840 | ||
|
|
fbf3b1cd19 | ||
|
|
0cc4151929 | ||
|
|
e261ade1bb | ||
|
|
5d7e54d419 | ||
|
|
3499858295 | ||
|
|
1615e218bd | ||
|
|
9a3b859780 |
@@ -3,10 +3,6 @@ module.exports = {
|
||||
'@nextcloud',
|
||||
],
|
||||
rules: {
|
||||
'jsdoc/require-param-description': ['off'],
|
||||
'jsdoc/require-param-type': ['off'],
|
||||
'jsdoc/check-param-names': ['off'],
|
||||
'jsdoc/no-undefined-types': ['off'],
|
||||
'jsdoc/require-property-description' : ['off']
|
||||
'valid-jsdoc': ['off'],
|
||||
},
|
||||
}
|
||||
|
||||
10
.github/dependabot.yml
vendored
10
.github/dependabot.yml
vendored
@@ -39,13 +39,3 @@ updates:
|
||||
versions:
|
||||
- "< 16"
|
||||
- ">= 15.a"
|
||||
- package-ecosystem: github-actions
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: saturday
|
||||
time: "03:00"
|
||||
timezone: Europe/Paris
|
||||
open-pull-requests-limit: 10
|
||||
reviewers:
|
||||
- juliushaertl
|
||||
|
||||
25
.github/stale.yml
vendored
Normal file
25
.github/stale.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 60
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 7
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- "1. to develop"
|
||||
- "2. developing"
|
||||
- "3. to review"
|
||||
- "discussion"
|
||||
- "bounty"
|
||||
- "bug"
|
||||
- "enhancement"
|
||||
|
||||
# Limit the number of actions per hour, from 1-30. Default is 30
|
||||
limitPerRun: 30
|
||||
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: stale
|
||||
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed if no further activity occurs. Thank you
|
||||
for your contributions.
|
||||
39
.github/workflows/appbuild.yml
vendored
Normal file
39
.github/workflows/appbuild.yml
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
name: Package build
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-18.04
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [14.x]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Set up npm7
|
||||
run: npm i -g npm@7
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v1
|
||||
with:
|
||||
php-version: '7.4'
|
||||
tools: composer
|
||||
- name: install dependencies
|
||||
run: |
|
||||
wget https://github.com/ChristophWurst/krankerl/releases/download/v0.12.2/krankerl_0.12.2_amd64.deb
|
||||
sudo dpkg -i krankerl_0.12.2_amd64.deb
|
||||
- name: package
|
||||
run: |
|
||||
uname -a
|
||||
RUST_BACKTRACE=1 krankerl --version
|
||||
RUST_BACKTRACE=1 krankerl package
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Deck app tarball
|
||||
path: build/artifacts/deck.tar.gz
|
||||
46
.github/workflows/command-rebase.yml
vendored
46
.github/workflows/command-rebase.yml
vendored
@@ -1,46 +0,0 @@
|
||||
# This workflow is provided via the organization template repository
|
||||
#
|
||||
# https://github.com/nextcloud/.github
|
||||
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
||||
|
||||
name: Rebase command
|
||||
|
||||
on:
|
||||
issue_comment:
|
||||
types: created
|
||||
|
||||
jobs:
|
||||
rebase:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
# On pull requests and if the comment starts with `/rebase`
|
||||
if: github.event.issue.pull_request != '' && startsWith(github.event.comment.body, '/rebase')
|
||||
|
||||
steps:
|
||||
- name: Add reaction on start
|
||||
uses: peter-evans/create-or-update-comment@v1
|
||||
with:
|
||||
token: ${{ secrets.COMMAND_BOT_PAT }}
|
||||
repository: ${{ github.event.repository.full_name }}
|
||||
comment-id: ${{ github.event.comment.id }}
|
||||
reaction-type: "+1"
|
||||
|
||||
- name: Checkout the latest code
|
||||
uses: actions/checkout@v2.4.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.COMMAND_BOT_PAT }}
|
||||
|
||||
- name: Automatic Rebase
|
||||
uses: cirrus-actions/rebase@1.5
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.COMMAND_BOT_PAT }}
|
||||
|
||||
- name: Add reaction on failure
|
||||
uses: peter-evans/create-or-update-comment@v1
|
||||
if: failure()
|
||||
with:
|
||||
token: ${{ secrets.COMMAND_BOT_PAT }}
|
||||
repository: ${{ github.event.repository.full_name }}
|
||||
comment-id: ${{ github.event.comment.id }}
|
||||
reaction-type: "-1"
|
||||
29
.github/workflows/dependabot-approve-merge.yml
vendored
29
.github/workflows/dependabot-approve-merge.yml
vendored
@@ -1,29 +0,0 @@
|
||||
# This workflow is provided via the organization template repository
|
||||
#
|
||||
# https://github.com/nextcloud/.github
|
||||
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
||||
|
||||
name: Dependabot
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
branches:
|
||||
- master
|
||||
- stable*
|
||||
|
||||
jobs:
|
||||
auto-approve-merge:
|
||||
if: github.actor == 'dependabot[bot]'
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
# Github actions bot approve
|
||||
- uses: hmarr/auto-approve-action@v2
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# Nextcloud bot approve and merge request
|
||||
- uses: ahmadnassri/action-dependabot-auto-merge@v2
|
||||
with:
|
||||
target: patch
|
||||
github-token: ${{ secrets.DEPENDABOT_AUTOMERGE_TOKEN }}
|
||||
33
.github/workflows/fixup.yml
vendored
33
.github/workflows/fixup.yml
vendored
@@ -1,33 +0,0 @@
|
||||
# This workflow is provided via the organization template repository
|
||||
#
|
||||
# https://github.com/nextcloud/.github
|
||||
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
||||
|
||||
name: Block fixup and squash commits
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, ready_for_review, reopened, synchronize]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: fixup-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
commit-message-check:
|
||||
if: github.event.pull_request.draft == false
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
name: Block fixup and squash commits
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Run check
|
||||
uses: skjnldsv/block-fixup-merge-action@42d26e1b536ce61e5cf467d65fb76caf4aa85acf # v1
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
19
.github/workflows/integration.yml
vendored
19
.github/workflows/integration.yml
vendored
@@ -19,13 +19,13 @@ jobs:
|
||||
matrix:
|
||||
php-versions: ['7.4']
|
||||
databases: ['sqlite', 'mysql', 'pgsql']
|
||||
server-versions: ['stable23']
|
||||
server-versions: ['stable22']
|
||||
|
||||
name: php${{ matrix.php-versions }}-${{ matrix.databases }}-${{ matrix.server-versions }}
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:14
|
||||
image: postgres
|
||||
ports:
|
||||
- 4445:5432/tcp
|
||||
env:
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout server
|
||||
uses: actions/checkout@v2.4.0
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: nextcloud/server
|
||||
ref: ${{ matrix.server-versions }}
|
||||
@@ -56,23 +56,16 @@ jobs:
|
||||
git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1
|
||||
|
||||
- name: Checkout app
|
||||
uses: actions/checkout@v2.4.0
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
path: apps/${{ env.APP_NAME }}
|
||||
|
||||
- name: Checkout activity
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
with:
|
||||
repository: nextcloud/activity
|
||||
ref: ${{ matrix.server-versions }}
|
||||
path: apps/activity
|
||||
|
||||
- name: Set up php ${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@2.15.0
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
tools: phpunit
|
||||
extensions: mbstring, gd, iconv, fileinfo, intl, sqlite, pdo_sqlite, mysql, pdo_mysql, pgsql, pdo_pgsql,
|
||||
extensions: mbstring, iconv, fileinfo, intl, sqlite, pdo_sqlite, mysql, pdo_mysql, pgsql, pdo_pgsql,
|
||||
coverage: none
|
||||
|
||||
- name: Set up PHPUnit
|
||||
|
||||
24
.github/workflows/lint.yml
vendored
24
.github/workflows/lint.yml
vendored
@@ -17,9 +17,9 @@ jobs:
|
||||
|
||||
name: php${{ matrix.php-versions }} lint
|
||||
steps:
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up php${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@2.15.0
|
||||
uses: shivammathur/setup-php@v1
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
coverage: none
|
||||
@@ -31,9 +31,9 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2.4.0
|
||||
uses: actions/checkout@master
|
||||
- name: Set up php
|
||||
uses: shivammathur/setup-php@2.15.0
|
||||
uses: shivammathur/setup-php@master
|
||||
with:
|
||||
php-version: 7.4
|
||||
coverage: none
|
||||
@@ -50,9 +50,9 @@ jobs:
|
||||
node-version: [14.x]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- uses: actions/checkout@v2
|
||||
- name: Use node ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v2.4.1
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Set up npm7
|
||||
@@ -67,16 +67,16 @@ jobs:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [14.x]
|
||||
node-versions: [14.x]
|
||||
|
||||
name: stylelint node${{ matrix.node-version }}
|
||||
name: stylelint node${{ matrix.node-versions }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Set up node ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v2.4.1
|
||||
- name: Set up node ${{ matrix.node-versions }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
node-versions: ${{ matrix.node-versions }}
|
||||
|
||||
- name: Set up npm7
|
||||
run: npm i -g npm@7
|
||||
|
||||
6
.github/workflows/nightly.yml
vendored
6
.github/workflows/nightly.yml
vendored
@@ -17,15 +17,15 @@ jobs:
|
||||
node-version: [14.x]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- uses: actions/checkout@v1
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v2.4.1
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Set up npm7
|
||||
run: npm i -g npm@7
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@2.15.0
|
||||
uses: shivammathur/setup-php@v1
|
||||
with:
|
||||
php-version: '7.4'
|
||||
tools: composer
|
||||
|
||||
4
.github/workflows/nodejs.yml
vendored
4
.github/workflows/nodejs.yml
vendored
@@ -12,9 +12,9 @@ jobs:
|
||||
node-version: [14.x]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- uses: actions/checkout@v1
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v2.4.1
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Set up npm7
|
||||
|
||||
12
.github/workflows/phpunit.yml
vendored
12
.github/workflows/phpunit.yml
vendored
@@ -13,20 +13,20 @@ env:
|
||||
|
||||
jobs:
|
||||
integration:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-18.04
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
php-versions: ['7.3', '7.4']
|
||||
databases: ['sqlite', 'mysql', 'pgsql']
|
||||
server-versions: ['stable23']
|
||||
server-versions: ['stable22']
|
||||
|
||||
name: php${{ matrix.php-versions }}-${{ matrix.databases }}-${{ matrix.server-versions }}
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:14
|
||||
image: postgres
|
||||
ports:
|
||||
- 4445:5432/tcp
|
||||
env:
|
||||
@@ -44,7 +44,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout server
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: nextcloud/server
|
||||
ref: ${{ matrix.server-versions }}
|
||||
@@ -57,12 +57,12 @@ jobs:
|
||||
git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1
|
||||
|
||||
- name: Checkout app
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
path: apps/${{ env.APP_NAME }}
|
||||
|
||||
- name: Set up php ${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@2.15.0
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
tools: phpunit
|
||||
|
||||
35
.github/workflows/psalm.yml
vendored
35
.github/workflows/psalm.yml
vendored
@@ -1,35 +0,0 @@
|
||||
# This workflow is provided via the organization template repository
|
||||
#
|
||||
# https://github.com/nextcloud/.github
|
||||
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
||||
|
||||
name: Static analysis
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- main
|
||||
- stable*
|
||||
|
||||
jobs:
|
||||
static-analysis:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
name: Nextcloud
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up php
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: 7.4
|
||||
coverage: none
|
||||
|
||||
- name: Install dependencies
|
||||
run: composer i
|
||||
|
||||
- name: Run coding standards check
|
||||
run: composer run psalm
|
||||
31
.github/workflows/static-analysis.yml
vendored
Normal file
31
.github/workflows/static-analysis.yml
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
name: Static analysis
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- stable*
|
||||
|
||||
jobs:
|
||||
static-psalm-analysis:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
ocp-version: [ 'dev-stable22' ]
|
||||
name: Nextcloud ${{ matrix.ocp-version }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@master
|
||||
- name: Set up php
|
||||
uses: shivammathur/setup-php@master
|
||||
with:
|
||||
php-version: 7.4
|
||||
tools: composer:v1
|
||||
coverage: none
|
||||
- name: Install dependencies
|
||||
run: composer i
|
||||
- name: Install dependencies
|
||||
run: composer require --dev christophwurst/nextcloud:${{ matrix.ocp-version }}
|
||||
- name: Run coding standards check
|
||||
run: composer run psalm
|
||||
65
.github/workflows/update-nextcloud-ocp.yml
vendored
65
.github/workflows/update-nextcloud-ocp.yml
vendored
@@ -1,65 +0,0 @@
|
||||
# This workflow is provided via the organization template repository
|
||||
#
|
||||
# https://github.com/nextcloud/.github
|
||||
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
||||
|
||||
name: Update nextcloud/ocp
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: "5 2 * * 0"
|
||||
|
||||
jobs:
|
||||
update-nextcloud-ocp:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
branches: ["master", "stable25", "stable24", "stable23"]
|
||||
|
||||
name: update-nextcloud-ocp-${{ matrix.branches }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ matrix.branches }}
|
||||
submodules: true
|
||||
|
||||
- name: Set up php7.4
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: 7.4
|
||||
extensions: ctype,curl,dom,fileinfo,gd,intl,json,mbstring,openssl,pdo_sqlite,posix,sqlite,xml,zip
|
||||
coverage: none
|
||||
|
||||
- name: Composer install
|
||||
run: composer install
|
||||
|
||||
- name: Composer update nextcloud/ocp
|
||||
run: composer require --dev nextcloud/ocp:dev-${{ matrix.branches }}
|
||||
continue-on-error: true
|
||||
|
||||
- name: Reset checkout dirs
|
||||
run: |
|
||||
git clean -f 3rdparty
|
||||
git clean -f vendor
|
||||
git checkout 3rdparty vendor
|
||||
continue-on-error: true
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v3
|
||||
with:
|
||||
token: ${{ secrets.COMMAND_BOT_PAT }}
|
||||
commit-message: Update psalm baseline
|
||||
committer: GitHub <noreply@github.com>
|
||||
author: nextcloud-command <nextcloud-command@users.noreply.github.com>
|
||||
signoff: true
|
||||
branch: automated/noid/${{ matrix.branches }}-update-nextcloud-ocp
|
||||
title: "[${{ matrix.branches }}] Update nextcloud/ocp dependency"
|
||||
body: |
|
||||
Auto-generated update of [nextcloud/ocp](https://github.com/nextcloud-deps/ocp/) dependency
|
||||
labels: |
|
||||
dependencies
|
||||
3. to review
|
||||
@@ -1,6 +1,6 @@
|
||||
[main]
|
||||
host = https://www.transifex.com
|
||||
lang_map = sk_SK: sk, th_TH: th, ja_JP: ja, bg_BG: bg, cs_CZ: cs, fi_FI: fi, hu_HU: hu, nb_NO: nb
|
||||
lang_map = bg_BG: bg, cs_CZ: cs, fi_FI: fi, hu_HU: hu, nb_NO: nb, sk_SK: sk, th_TH: th, ja_JP: ja
|
||||
|
||||
[o:nextcloud:p:nextcloud:r:deck]
|
||||
file_filter = translationfiles/<lang>/deck.po
|
||||
|
||||
228
CHANGELOG.md
228
CHANGELOG.md
@@ -1,132 +1,124 @@
|
||||
# Changelog
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## 1.6.7
|
||||
## 1.5.8
|
||||
|
||||
### Fixed
|
||||
|
||||
- fix: Detect end of the activity responses (fix #3395) #6518
|
||||
- fix: Avoid conflicts on deck attachments folder name #5705
|
||||
|
||||
## 1.6.6
|
||||
|
||||
### Fixed
|
||||
|
||||
- Gracefully handle not found card for a share [#4570](https://github.com/nextcloud/deck/pull/4570)
|
||||
- Fix(occ): set user id for permission sevice from board service [#5073](https://github.com/nextcloud/deck/pull/5073)
|
||||
- Fix deleted card/board issues @juliushaertl [#5450](https://github.com/nextcloud/deck/pull/5450)
|
||||
- Fix small issues around delete/undo @juliushaertl [#5447](https://github.com/nextcloud/deck/pull/5447)
|
||||
|
||||
## 1.6.5
|
||||
|
||||
### Fixed
|
||||
|
||||
- minor style fixes [#4203](https://github.com/nextcloud/deck/pull/4203)
|
||||
- Add integration test for attachment handling on cards [#4177](https://github.com/nextcloud/deck/pull/4177)
|
||||
- feat: add validators to check values in services @juliushaertl [#4175](https://github.com/nextcloud/deck/pull/4175)
|
||||
- disables autocomplete on card creation @juliushaertl [#4183](https://github.com/nextcloud/deck/pull/4183)
|
||||
|
||||
## 1.6.4
|
||||
|
||||
### Fixed
|
||||
|
||||
- Cache user membership for circles [#4133](https://github.com/nextcloud/deck/pull/4133)
|
||||
- Set event link also for notifications that get emitted from activities [#4119](https://github.com/nextcloud/deck/pull/4119)
|
||||
- disable Create card button while no stack is chosen [#4020](https://github.com/nextcloud/deck/pull/4020)
|
||||
- to nextcloud/OCP package in stable23 [#4094](https://github.com/nextcloud/deck/pull/4094)
|
||||
- Use capped memory cache for board permissions [#3998](https://github.com/nextcloud/deck/pull/3998)
|
||||
- Improve CalDAV integration performance [#3996](https://github.com/nextcloud/deck/pull/3996)
|
||||
- Fetch attachment folder for the correct user during cron job [#3960](https://github.com/nextcloud/deck/pull/3960)
|
||||
- Switch to 'markdown-it-task-checkbox' for rendering of task lists [#3926](https://github.com/nextcloud/deck/pull/3926)
|
||||
- Prevent opening card and applyLabelFilter on card drag end [#3918](https://github.com/nextcloud/deck/pull/3918)
|
||||
- Fix z-index for deck sidebar [#3886](https://github.com/nextcloud/deck/pull/3886)
|
||||
- Align Duedate-delete icon properly - fixes nextcloud/deck#3791 [#3817](https://github.com/nextcloud/deck/pull/3817)
|
||||
- Increase file count after sharing [#3806](https://github.com/nextcloud/deck/pull/3806)
|
||||
- Show cards after moving into another list [#3794](https://github.com/nextcloud/deck/pull/3794)
|
||||
- Fetch full board data after cloning [#3781](https://github.com/nextcloud/deck/pull/3781)
|
||||
|
||||
|
||||
## 1.6.3
|
||||
|
||||
### Fixed
|
||||
|
||||
- Align Duedate-delete icon properly - fixes nextcloud/deck#3791 [#3816](https://github.com/nextcloud/deck/pull/3816)
|
||||
- Increase file count after sharing [#3805](https://github.com/nextcloud/deck/pull/3805)
|
||||
- Show cards after moving into another list [#3795](https://github.com/nextcloud/deck/pull/3795)
|
||||
- Fetch full board data after cloning [#3780](https://github.com/nextcloud/deck/pull/3780)
|
||||
- Handle qb mapper exception messages properly [#3770](https://github.com/nextcloud/deck/pull/3770)
|
||||
|
||||
## 1.6.2
|
||||
## 1.5.7
|
||||
|
||||
### Added
|
||||
|
||||
- Transfer ownership @juliushaertl [#3664](https://github.com/nextcloud/deck/pull/3664)
|
||||
- Transfer ownership @juliushaertl [#3665](https://github.com/nextcloud/deck/pull/3665)
|
||||
|
||||
### Fixed
|
||||
|
||||
- 🐛 Fix missing files sidebar [#3641](https://github.com/nextcloud/deck/pull/3641)
|
||||
- Add a missing translation - not found in transifex [#3706](https://github.com/nextcloud/deck/pull/3706)
|
||||
- Fix: Check all circle shares for permissions [#3717](https://github.com/nextcloud/deck/pull/3717)
|
||||
- Sort boards non case sensitive [#3663](https://github.com/nextcloud/deck/pull/3663)
|
||||
- Use explicit cast to make use of index @juliushaertl [#3497](https://github.com/nextcloud/deck/pull/3497)
|
||||
- Fix paramter replacements when creating deck cards from talk messages @juliushaertl [#3741](https://github.com/nextcloud/deck/pull/3741)
|
||||
- Fix hidden attachment icon on archived cards [#3734](https://github.com/nextcloud/deck/pull/3734)
|
||||
- Fix text selection in dark mode and modal view [#3766](https://github.com/nextcloud/deck/pull/3766)
|
||||
- Fix: Check all circle shares for permissions [#3721](https://github.com/nextcloud/deck/pull/3721)
|
||||
- Add a missing translation - not found in transifex [#3707](https://github.com/nextcloud/deck/pull/3707)
|
||||
- 🐛 Fix missing files sidebar [#3642](https://github.com/nextcloud/deck/pull/3642)
|
||||
- [stable23] Use explicit cast to make use of index [#3731](https://github.com/nextcloud/deck/pull/3731)
|
||||
- Fix hidden attachment icon on archived cards [#3735](https://github.com/nextcloud/deck/pull/3735)
|
||||
- [stable23] Sort boards non case sensitive [#3739](https://github.com/nextcloud/deck/pull/3739)
|
||||
- add autofocus on board edit #3326 @juliushaertl [#3743](https://github.com/nextcloud/deck/pull/3743)
|
||||
- Fix paramter replacements when creating deck cards from talk messages @juliushaertl [#3742](https://github.com/nextcloud/deck/pull/3742)
|
||||
- Fix text selection in dark mode and modal view [#3767](https://github.com/nextcloud/deck/pull/3767)
|
||||
|
||||
### Other
|
||||
|
||||
- Properly check for the stack AND setting board permissions [#3713](https://github.com/nextcloud/deck/pull/3713)
|
||||
- Add missing indices [#3755](https://github.com/nextcloud/deck/pull/3755)
|
||||
- Properly check for the stack AND setting board permissions [#3714](https://github.com/nextcloud/deck/pull/3714)
|
||||
- Add missing indices [#3756](https://github.com/nextcloud/deck/pull/3756)
|
||||
|
||||
## 1.6.1
|
||||
|
||||
## 1.5.6
|
||||
|
||||
### Fixed
|
||||
|
||||
- Exclude deleted boards in the selection for target [#3523](https://api.github.com/repos/nextcloud/deck/pulls/3523)
|
||||
- CardApiController: Fix order of optional parameters [#3520](https://api.github.com/repos/nextcloud/deck/pulls/3520)
|
||||
- Fix cursor generation if no results are found [#3462](https://api.github.com/repos/nextcloud/deck/pulls/3462)
|
||||
- Fix CalDAV blocking and modernize circles API usage [#3526](https://api.github.com/repos/nextcloud/deck/pulls/3526)
|
||||
- Fix overview card listing [#3463](https://api.github.com/repos/nextcloud/deck/pulls/3463)
|
||||
- Generate fixed link for activity emails [#3626](https://api.github.com/repos/nextcloud/deck/pulls/3626)
|
||||
- return the selector for collections [#3618](https://api.github.com/repos/nextcloud/deck/pulls/3618)
|
||||
- Fix confusion between stackId and boardId in StackService [#3543](https://api.github.com/repos/nextcloud/deck/pulls/3543)
|
||||
- Fix talk integration [#3537](https://api.github.com/repos/nextcloud/deck/pulls/3537)
|
||||
- Make insert attachment buttom easy to click [#3614](https://api.github.com/repos/nextcloud/deck/pulls/3614)
|
||||
- Allow to download an attachment without navigating to the files app [#3441](https://api.github.com/repos/nextcloud/deck/pulls/3441)
|
||||
- Fix CalDAV blocking and modernize circles API usage [#3527](https://api.github.com/repos/nextcloud/deck/pulls/3527)
|
||||
- CardApiController: Fix order of optional parameters [#3521](https://api.github.com/repos/nextcloud/deck/pulls/3521)
|
||||
- Fix cursor generation if no results are found [#3460](https://api.github.com/repos/nextcloud/deck/pulls/3460)
|
||||
- Exclude deleted boards in the selection for target [#3524](https://api.github.com/repos/nextcloud/deck/pulls/3524)
|
||||
- Generate fixed link for activity emails [#3627](https://api.github.com/repos/nextcloud/deck/pulls/3627)
|
||||
- Make insert attachment buttom easy to click [#3615](https://api.github.com/repos/nextcloud/deck/pulls/3615)
|
||||
- Fix confusion between stackId and boardId in StackService [#3544](https://api.github.com/repos/nextcloud/deck/pulls/3544)
|
||||
|
||||
## 1.6.0
|
||||
## 1.5.5
|
||||
|
||||
- Fix release asset build
|
||||
|
||||
## 1.5.4
|
||||
|
||||
### Fixed
|
||||
|
||||
- #3378 Fix menu button position in card modal
|
||||
- #3392 Use displayname instead of uid for mentions (reopened against master)
|
||||
- #3361 Improve combined search @eneiluj
|
||||
- #3381 Extend drag-and-drop zone in card sidebar @Artem4590
|
||||
- #3366 Fix optional parameter order
|
||||
- #3407 Keep exceptions http response generic
|
||||
|
||||
|
||||
## 1.5.3
|
||||
|
||||
### Fied
|
||||
|
||||
- #3317 Additional check for stacks
|
||||
|
||||
|
||||
## 1.5.2
|
||||
|
||||
### Fixed
|
||||
|
||||
- #3300 Fix print style issues
|
||||
- #3303 Delete file shares through attachments API
|
||||
- #3306 Return false instead of throwing when getting calendar setting
|
||||
|
||||
## 1.5.1 - 2021-09-03
|
||||
|
||||
### Fixed
|
||||
|
||||
- #3224 Move circle checks to a unified service and improve member checks
|
||||
- #3231 Check for null value to avoid TypeError in the group manager
|
||||
- #3264 Defer obtaining the user session in the config service
|
||||
|
||||
|
||||
## 1.5.0 - 2021-07-09
|
||||
|
||||
### Added
|
||||
|
||||
- #3449 Cache most frequent queries
|
||||
- #3177 Use async import for vue component on collections entrypoint @juliushaertl
|
||||
- #2791 Open description links in new tab @fm-sys
|
||||
- #3344 Improve combined search @eneiluj
|
||||
- #3362 Improve search performance @eneiluj
|
||||
- #2710 Due date shortcuts in the datepicker @jakobroehrl
|
||||
* Nextcloud 22 compatibility
|
||||
* [#3105](https://github.com/nextcloud/deck/pull/3105) Compatibility with Cirlces changes in 22
|
||||
* [#3147](https://github.com/nextcloud/deck/pull/3147) Add card button to the dashboard widget @jakobroehrl
|
||||
* [#2854](https://github.com/nextcloud/deck/pull/2854) Add card button in card overview @jakobroehrl
|
||||
* [#3078](https://github.com/nextcloud/deck/pull/3078) Show on shared boards unassigned cards to all users @jakobroehrl
|
||||
|
||||
### Fixed
|
||||
|
||||
- #3446 Switch to QBMapper in BoardMapper
|
||||
- #3433 Fix event name for updating the description
|
||||
- #3463 Fix overview card listing
|
||||
- #3440 Allow to download an attachment without navigating to the files app
|
||||
- #3462 Fix cursor generation if no results are found
|
||||
- #3161 Reduce duplicate queries when fetching user boards an permissions @juliushaertl
|
||||
- #3151 Always log generic exceptions @juliushaertl
|
||||
- #3217 Move circle checks to a unified service and improve member checks @juliushaertl
|
||||
- #3225 Check for null value to avoid TypeError in the group manager @juliushaertl
|
||||
- #3263 Defer obtaining the user session in the config service @juliushaertl
|
||||
- #3294 Fix print style issues @weeman1337
|
||||
- #3299 Return false instead of throwing when getting calendar setting @juliushaertl
|
||||
- #3298 Delete file shares through attachments API @juliushaertl
|
||||
- #3343 Fix search pagination cursor @eneiluj
|
||||
- #3326 add autofocus on board edit @weeman1337
|
||||
- #3323 Extend drag-and-drop zone in card sidebar @old-green-frog
|
||||
- #3364 Fix optional parameter order @juliushaertl
|
||||
- #3324 Fix menu button position in card modal @valerydmitrieva
|
||||
- #3391 Use displayname instead of uid for mentions (reopened against master) @kffl
|
||||
- #3316 Additional check for stacks @juliushaertl
|
||||
- #3357 Revert "Fix search pagination cursor" @juliushaertl
|
||||
- #3327 Do not show both bullets and checkboxes for checklists @Themanwhosmellslikesugar
|
||||
- #3375 Show absolute dates when printing @weeman1337
|
||||
- #3376 Print assignee names @weeman1337
|
||||
- #3384 Keep exceptions http response generic @juliushaertl
|
||||
* [#2935](https://github.com/nextcloud/deck/pull/2935) Rich object string parameters for notifications @nickvergessen
|
||||
* [#2950](https://github.com/nextcloud/deck/pull/2950) Remove notification on unshare and add type hints
|
||||
* [#2983](https://github.com/nextcloud/deck/pull/2983) Fix codemirror description width
|
||||
* [#2989](https://github.com/nextcloud/deck/pull/2989) Fix unified comments search with postgres
|
||||
* [#3005](https://github.com/nextcloud/deck/pull/3005) Do not query the lookupserver when looking for sharees
|
||||
* [#3011](https://github.com/nextcloud/deck/pull/3011) L10n: Spelling unification @Valdnet
|
||||
* [#3014](https://github.com/nextcloud/deck/pull/3014) Proper error handling when fetching comments fails
|
||||
* [#3016](https://github.com/nextcloud/deck/pull/3016) Allow searching for filters without a query to match all that have a given filter set
|
||||
* [#3021](https://github.com/nextcloud/deck/pull/3021) L10n: Add word "Card" @Valdnet
|
||||
* [#3025](https://github.com/nextcloud/deck/pull/3025) Show comment counter and highlight if unread comments are available
|
||||
* [#3036](https://github.com/nextcloud/deck/pull/3036) Add link to migration tool for Trello @maxammann
|
||||
* [#3037](https://github.com/nextcloud/deck/pull/3037) Catch any error during circle detail fetching
|
||||
* [#3038](https://github.com/nextcloud/deck/pull/3038) Get attachment from the user node instead of the share source
|
||||
* [#3092](https://github.com/nextcloud/deck/pull/3092) Refactor update to have proper order of optional parameters
|
||||
* [#3113](https://github.com/nextcloud/deck/pull/3113) Use new viewer syntax with destructuring object @azul
|
||||
* [#3142](https://github.com/nextcloud/deck/pull/3142) Always pass user id in share provider
|
||||
* [#3152](https://github.com/nextcloud/deck/pull/3152) Only offer stack creation in emptycontent with proper permissions
|
||||
* [#3165](https://github.com/nextcloud/deck/pull/3165) Always log generic exceptions
|
||||
* [#3168](https://github.com/nextcloud/deck/pull/3168) Reduce duplicate queries when fetching user boards an permissions
|
||||
|
||||
|
||||
|
||||
## 1.4.0 - 2021-04-13
|
||||
@@ -163,15 +155,15 @@ All notable changes to this project will be documented in this file.
|
||||
## 1.3.0-beta2
|
||||
|
||||
### Fixed
|
||||
* [#2700](https://github.com/nextcloud/deck/pull/2700) Attempt to copy file on dropping it to deck @juliushaertl
|
||||
* [#2701](https://github.com/nextcloud/deck/pull/2701) Fix uploading files by drag and drop @juliushaertl
|
||||
* [#2700](https://github.com/nextcloud/deck/pull/2700) Attempt to copy file on dropping it to deck
|
||||
* [#2701](https://github.com/nextcloud/deck/pull/2701) Fix uploading files by drag and drop
|
||||
* [#2707](https://github.com/nextcloud/deck/pull/2707) L10n: Change to a capital letter @Valdnet
|
||||
* [#2712](https://github.com/nextcloud/deck/pull/2712) Docs: Fix table in section "GET /api/v1.0/config" @das-g
|
||||
* [#2716](https://github.com/nextcloud/deck/pull/2716) Remove repair step which is no longer needed as we cleanup properly @juliushaertl
|
||||
* [#2716](https://github.com/nextcloud/deck/pull/2716) Remove repair step which is no longer needed as we cleanup properly
|
||||
* [#2723](https://github.com/nextcloud/deck/pull/2723) Pad random color with leading zeroes @PVince81
|
||||
* [#2729](https://github.com/nextcloud/deck/pull/2729) Remove invalid activity parameters @nickvergessen
|
||||
* [#2750](https://github.com/nextcloud/deck/pull/2750) Fix deck activity emails not being translated @nickvergessen
|
||||
* [#2751](https://github.com/nextcloud/deck/pull/2751) Properly set author for activity events that are triggered by cron @juliushaertl
|
||||
* [#2751](https://github.com/nextcloud/deck/pull/2751) Properly set author for activity events that are triggered by cron
|
||||
|
||||
|
||||
## 1.2.2 - 2020-11-24
|
||||
@@ -280,31 +272,31 @@ All notable changes to this project will be documented in this file.
|
||||
### Fixed
|
||||
|
||||
|
||||
* [#2116](https://github.com/nextcloud/deck/pull/2116) Fix navigation layout issues @juliushaertl
|
||||
* [#2118](https://github.com/nextcloud/deck/pull/2118) Use proper parameter when handling attachments @juliushaertl
|
||||
* [#2116](https://github.com/nextcloud/deck/pull/2116) Fix navigation layout issues
|
||||
* [#2118](https://github.com/nextcloud/deck/pull/2118) Use proper parameter when handling attachments
|
||||
|
||||
## 1.0.4 - 2020-06-26
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#2062](https://github.com/nextcloud/deck/pull/2062) Fix saving card description after toggling checkboxes @juliushaertl
|
||||
* [#2062](https://github.com/nextcloud/deck/pull/2062) Fix saving card description after toggling checkboxes
|
||||
* [#2065](https://github.com/nextcloud/deck/pull/2065) Adding CSS rule for Markdown Blockquotes @reox
|
||||
* [#2059](https://github.com/nextcloud/deck/pull/2059) Fix fetching attachments on card change @juliushaertl
|
||||
* [#2060](https://github.com/nextcloud/deck/pull/2060) Use mixing for relative date in card sidebar @juliushaertl
|
||||
* [#2059](https://github.com/nextcloud/deck/pull/2059) Fix fetching attachments on card change
|
||||
* [#2060](https://github.com/nextcloud/deck/pull/2060) Use mixing for relative date in card sidebar
|
||||
|
||||
|
||||
## 1.0.3 - 2020-06-19
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#2019](https://github.com/nextcloud/deck/pull/2019) Remove old global css rule @juliushaertl
|
||||
* [#2020](https://github.com/nextcloud/deck/pull/2020) Fix navigation issue with leftover nodes @juliushaertl
|
||||
* [#2021](https://github.com/nextcloud/deck/pull/2021) Fix description issues @juliushaertl
|
||||
* [#2022](https://github.com/nextcloud/deck/pull/2022) Fix replyto issues with the comments API @juliushaertl
|
||||
* [#2027](https://github.com/nextcloud/deck/pull/2027) Allow to unassign current user from card @juliushaertl
|
||||
* [#2019](https://github.com/nextcloud/deck/pull/2019) Remove old global css rule
|
||||
* [#2020](https://github.com/nextcloud/deck/pull/2020) Fix navigation issue with leftover nodes
|
||||
* [#2021](https://github.com/nextcloud/deck/pull/2021) Fix description issues
|
||||
* [#2022](https://github.com/nextcloud/deck/pull/2022) Fix replyto issues with the comments API
|
||||
* [#2027](https://github.com/nextcloud/deck/pull/2027) Allow to unassign current user from card
|
||||
* [#2029](https://github.com/nextcloud/deck/pull/2029) Fix wording : stack -> list @cloud2018
|
||||
* [#2032](https://github.com/nextcloud/deck/pull/2032) Force order by id as second sorting key @juliushaertl
|
||||
* [#2045](https://github.com/nextcloud/deck/pull/2045) Improve label styling @juliushaertl
|
||||
* [#2032](https://github.com/nextcloud/deck/pull/2032) Force order by id as second sorting key
|
||||
* [#2045](https://github.com/nextcloud/deck/pull/2045) Improve label styling
|
||||
* [#2010](https://github.com/nextcloud/deck/pull/2010) User documentation fixes @Nyco
|
||||
* [#1998](https://github.com/nextcloud/deck/pull/1998) Add Checklist explaination to the doc @4rnoP
|
||||
|
||||
|
||||
@@ -25,8 +25,7 @@ Deck is a kanban style organization tool aimed at personal planning and project
|
||||
|
||||
- [trello-to-deck](https://github.com/maxammann/trello-to-deck) - Migrates cards from Trello
|
||||
- [mail2deck](https://github.com/newroco/mail2deck) - Provides an "email in" solution
|
||||
- [A-deck](https://github.com/leoossa/A-deck) - Chrome Extension that allows to create new card in selected stack based on current tab
|
||||
-
|
||||
|
||||
## Installation/Update
|
||||
|
||||
This app is supposed to work on the two latest Nextcloud versions.
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
- 🚀 Get your project organized
|
||||
|
||||
</description>
|
||||
<version>1.6.7</version>
|
||||
<version>1.5.8</version>
|
||||
<licence>agpl</licence>
|
||||
<author>Julius Härtl</author>
|
||||
<namespace>Deck</namespace>
|
||||
@@ -35,7 +35,7 @@
|
||||
<database min-version="9.4">pgsql</database>
|
||||
<database>sqlite</database>
|
||||
<database min-version="5.5">mysql</database>
|
||||
<nextcloud min-version="23" max-version="23"/>
|
||||
<nextcloud min-version="22" max-version="22"/>
|
||||
</dependencies>
|
||||
<background-jobs>
|
||||
<job>OCA\Deck\Cron\DeleteCron</job>
|
||||
|
||||
@@ -8,22 +8,24 @@
|
||||
"email": "jus@bitgrid.net"
|
||||
}
|
||||
],
|
||||
"config": {
|
||||
"platform": {
|
||||
"php": "7.3"
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
"cogpowered/finediff": "0.3.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"roave/security-advisories": "dev-master",
|
||||
"christophwurst/nextcloud": "^22@dev",
|
||||
"phpunit/phpunit": "^8",
|
||||
"nextcloud/coding-standard": "^0.5.0",
|
||||
"symfony/event-dispatcher": "^4.0",
|
||||
"vimeo/psalm": "^4.3",
|
||||
"php-parallel-lint/php-parallel-lint": "^1.2",
|
||||
"nextcloud/ocp": "dev-stable23"
|
||||
"php-parallel-lint/php-parallel-lint": "^1.2"
|
||||
},
|
||||
"config": {
|
||||
"platform": {
|
||||
"php": "7.3"
|
||||
},
|
||||
"optimize-autoloader": true,
|
||||
"classmap-authoritative": true
|
||||
},
|
||||
@@ -38,12 +40,6 @@
|
||||
"@test:integration"
|
||||
],
|
||||
"test:unit": "phpunit -c tests/phpunit.xml",
|
||||
"test:integration": "phpunit -c tests/phpunit.integration.xml",
|
||||
"test:api": "cd tests/integration && ./run.sh"
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"OCP\\": "vendor/nextcloud/ocp/OCP"
|
||||
}
|
||||
"test:integration": "phpunit -c tests/phpunit.integration.xml && cd tests/integration && ./run.sh"
|
||||
}
|
||||
}
|
||||
|
||||
95
composer.lock
generated
95
composer.lock
generated
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "388de1616aef9f3496ad3432af301215",
|
||||
"content-hash": "a984e9e37aadc6504b0f9ddbd6604835",
|
||||
"packages": [
|
||||
{
|
||||
"name": "cogpowered/finediff",
|
||||
@@ -230,6 +230,49 @@
|
||||
],
|
||||
"time": "2021-03-30T17:13:30+00:00"
|
||||
},
|
||||
{
|
||||
"name": "christophwurst/nextcloud",
|
||||
"version": "v22.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ChristophWurst/nextcloud_composer.git",
|
||||
"reference": "8bb086cd016128b5ef8353662fd1852db3248d1e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/ChristophWurst/nextcloud_composer/zipball/8bb086cd016128b5ef8353662fd1852db3248d1e",
|
||||
"reference": "8bb086cd016128b5ef8353662fd1852db3248d1e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.3 || ~8.0.0",
|
||||
"psr/container": "^1.0",
|
||||
"psr/event-dispatcher": "^1.0",
|
||||
"psr/log": "^1.1"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "23.0.0-dev"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"AGPL-3.0-or-later"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Christoph Wurst",
|
||||
"email": "christoph@winzerhof-wurst.at"
|
||||
}
|
||||
],
|
||||
"description": "Composer package containing Nextcloud's public API (classes, interfaces)",
|
||||
"support": {
|
||||
"issues": "https://github.com/ChristophWurst/nextcloud_composer/issues",
|
||||
"source": "https://github.com/ChristophWurst/nextcloud_composer/tree/v22.1.1"
|
||||
},
|
||||
"time": "2021-11-11T14:01:42+00:00"
|
||||
},
|
||||
{
|
||||
"name": "composer/package-versions-deprecated",
|
||||
"version": "1.11.99.5",
|
||||
@@ -1137,49 +1180,6 @@
|
||||
},
|
||||
"time": "2021-01-11T14:15:58+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nextcloud/ocp",
|
||||
"version": "dev-stable23",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nextcloud-deps/ocp.git",
|
||||
"reference": "5b18c55569528d8190224af04095e9dde1953c72"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nextcloud-deps/ocp/zipball/5b18c55569528d8190224af04095e9dde1953c72",
|
||||
"reference": "5b18c55569528d8190224af04095e9dde1953c72",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.3 || ~8.0.0",
|
||||
"psr/container": "^1.1.1",
|
||||
"psr/event-dispatcher": "^1.0",
|
||||
"psr/log": "^1.1"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "23.0.0-dev"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"AGPL-3.0-or-later"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Christoph Wurst",
|
||||
"email": "christoph@winzerhof-wurst.at"
|
||||
}
|
||||
],
|
||||
"description": "Composer package containing Nextcloud's public API (classes, interfaces)",
|
||||
"support": {
|
||||
"issues": "https://github.com/nextcloud-deps/ocp/issues",
|
||||
"source": "https://github.com/nextcloud-deps/ocp/tree/stable23"
|
||||
},
|
||||
"time": "2022-12-20T00:37:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nikic/php-parser",
|
||||
"version": "v4.13.2",
|
||||
@@ -5247,14 +5247,11 @@
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": {
|
||||
"roave/security-advisories": 20,
|
||||
"nextcloud/ocp": 20
|
||||
"christophwurst/nextcloud": 20
|
||||
},
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": [],
|
||||
"platform-dev": [],
|
||||
"platform-overrides": {
|
||||
"php": "7.3"
|
||||
},
|
||||
"plugin-api-version": "2.3.0"
|
||||
"plugin-api-version": "2.2.0"
|
||||
}
|
||||
|
||||
@@ -183,10 +183,8 @@ OC.L10N.register(
|
||||
"Failed to transfer the board to {user}" : "Неуспешно прехвърляне на таблото на {user}",
|
||||
"Add a new list" : "Добавяне на нов списък",
|
||||
"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" : "Име на карта",
|
||||
"List deleted" : "Списъкът е изтрит",
|
||||
@@ -262,7 +260,6 @@ OC.L10N.register(
|
||||
"Shared with you" : "Споделени с вас",
|
||||
"Deck settings" : "Настройки на платформата",
|
||||
"Use bigger card view" : "Използва по-голям изглед на картата",
|
||||
"Show card ID badge" : "Показване на обозначение за самоличност на картата",
|
||||
"Show boards in calendar/tasks" : "Показване на таблата в календар / задачи",
|
||||
"Limit deck usage of groups" : "Ограничава използването на набора от групи",
|
||||
"Limiting Deck will block users not part of those groups from creating their own boards. Users will still be able to work on boards that have been shared with them." : "Ограничаването на приложението Deck/набор/ ще блокира потребителите, които не са част от тези групи, да създават свои собствени табла. Потребителите все още ще могат да работят на таблата, които са споделени с тях.",
|
||||
|
||||
@@ -181,10 +181,8 @@
|
||||
"Failed to transfer the board to {user}" : "Неуспешно прехвърляне на таблото на {user}",
|
||||
"Add a new list" : "Добавяне на нов списък",
|
||||
"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" : "Име на карта",
|
||||
"List deleted" : "Списъкът е изтрит",
|
||||
@@ -260,7 +258,6 @@
|
||||
"Shared with you" : "Споделени с вас",
|
||||
"Deck settings" : "Настройки на платформата",
|
||||
"Use bigger card view" : "Използва по-голям изглед на картата",
|
||||
"Show card ID badge" : "Показване на обозначение за самоличност на картата",
|
||||
"Show boards in calendar/tasks" : "Показване на таблата в календар / задачи",
|
||||
"Limit deck usage of groups" : "Ограничава използването на набора от групи",
|
||||
"Limiting Deck will block users not part of those groups from creating their own boards. Users will still be able to work on boards that have been shared with them." : "Ограничаването на приложението Deck/набор/ ще блокира потребителите, които не са част от тези групи, да създават свои собствени табла. Потребителите все още ще могат да работят на таблата, които са споделени с тях.",
|
||||
|
||||
65
l10n/ca.js
65
l10n/ca.js
@@ -29,7 +29,7 @@ OC.L10N.register(
|
||||
"{user} has deleted card {card} in list {stack} on board {board}" : "{user} ha suprimit la targeta {card} a la llista {stack} al tauler {board}",
|
||||
"You have renamed the card {before} to {card}" : "Heu reanomenat la targeta {before} a {card}",
|
||||
"{user} has renamed the card {before} to {card}" : "{user} ha reanomenat la targeta {before} a {card}",
|
||||
"You have added a description to card {card} in list {stack} on board {board}" : "Heu afegit una descripció a la targeta {card} a la llista {stack} del tauler {board}",
|
||||
"You have added a description to card {card} in list {stack} on board {board}" : "Heu afegit una descripció a la targeta {card} a la llista {stack} al tauler {board}",
|
||||
"{user} has added a description to card {card} in list {stack} on board {board}" : "{user} ha afegit una descripció a la targeta {card} a la llista {stack} al tauler {board}",
|
||||
"You have updated the description of card {card} in list {stack} on board {board}" : "Heu actualitzat la descripció de la targeta {card} a la llista {stack} al tauler {board}",
|
||||
"{user} has updated the description of the card {card} in list {stack} on board {board}" : "{user} ha actualitzat la descripció de la targeta {card} a la llista {stack} al tauler {board}",
|
||||
@@ -37,12 +37,12 @@ OC.L10N.register(
|
||||
"{user} has archived card {card} in list {stack} on board {board}" : "{user} té la targeta arxivada {card} a la llista {stack} al tauler {board}",
|
||||
"You have unarchived card {card} in list {stack} on board {board}" : "Teniu una targeta no-arxchivada {card} a la llista {stack} al tauler {board}",
|
||||
"{user} has unarchived card {card} in list {stack} on board {board}" : "{user} té una targeta no-arxivada {card} a la llista {stack} al tauler {board}",
|
||||
"You have removed the due date of card {card}" : "Heu suprimit la data de caducitat de la targeta {targeta}",
|
||||
"{user} has removed the due date of card {card}" : "{user} ha suprimit la data de caducitat de la targeta {targeta}",
|
||||
"You have set the due date of card {card} to {after}" : "Heu establert la data de caducitat de la targeta {card} a {after}",
|
||||
"{user} has set the due date of card {card} to {after}" : "{user} ha establert la data de caducitat de la targeta {card} a {after}",
|
||||
"You have updated the due date of card {card} to {after}" : "Heu actualitzat la data de caducitat de la targeta {card} a {after}",
|
||||
"{user} has updated the due date of card {card} to {after}" : "{user} ha actualitzat la data de caducitat de la targeta {card} a {after}",
|
||||
"You have removed the due date of card {card}" : "Heu suprimit la data de venciment de la targeta {targeta}",
|
||||
"{user} has removed the due date of card {card}" : "{user} ha suprimit la data de venciment de la targeta {targeta}",
|
||||
"You have set the due date of card {card} to {after}" : "Heu establert la data de venciment de la targeta {card} a {after}",
|
||||
"{user} has set the due date of card {card} to {after}" : "{user} ha establert la data de venciment de la targeta {card} a {after}",
|
||||
"You have updated the due date of card {card} to {after}" : "Heu actualitzat la data de venciment de la targeta {card} a {after}",
|
||||
"{user} has updated the due date of card {card} to {after}" : "{user} ha actualitzat la data de venciment de la targeta {card} a {after}",
|
||||
"You have added the tag {label} to card {card} in list {stack} on board {board}" : "Heu afegit l'etiqueta {label} a la targeta {card} a la llista {stack} al tauler {board}",
|
||||
"{user} has added the tag {label} to card {card} in list {stack} on board {board}" : "{user} ha afegit l'etiqueta {label} a la targeta {card} a la llista {stack} al tauler {board}",
|
||||
"You have removed the tag {label} from card {card} in list {stack} on board {board}" : "Heu eliminat l'etiqueta {label} de la targeta {card} a la llista {stack} al tauler {board}",
|
||||
@@ -66,13 +66,13 @@ OC.L10N.register(
|
||||
"A <strong>card description</strong> inside the Deck app has been changed" : "S'ha canviat una <strong>descripció de targeta</strong> a l'aplicació Tauler",
|
||||
"Deck" : "Targetes",
|
||||
"Changes in the <strong>Deck app</strong>" : "Canvis a l'<strong>aplicació Targetes</strong>",
|
||||
"A <strong>comment</strong> was created on a card" : "S'ha creat un <strong>comentari</strong> a una targeta",
|
||||
"A <strong>comment</strong> was created on a card" : "S'ha afegit un <strong>comentari</strong> a una targeta",
|
||||
"Upcoming cards" : "Pròximes targetes",
|
||||
"Load more" : "Carrega'n més",
|
||||
"Personal" : "Personal",
|
||||
"The card \"%s\" on \"%s\" has been assigned to you by %s." : "La targeta \"%s\" sobre \"%s\" se us ha assignat per %s.",
|
||||
"{user} has assigned the card {deck-card} on {deck-board} to you." : "{user} us ha assignat la targeta {deck-card} a {deck-board}.",
|
||||
"The card \"%s\" on \"%s\" has reached its due date." : "La targeta \"%s\" sobre \"%s\" ha assolit la seva data de caducitat.",
|
||||
"The card \"%s\" on \"%s\" has reached its due date." : "La targeta \"%s\" sobre \"%s\" ha assolit la seva data de venciment.",
|
||||
"The card {deck-card} on {deck-board} has reached its due date." : "La targeta {deck-card} a {deck-board} ha assolit la seva data de caducitat.",
|
||||
"%s has mentioned you in a comment on \"%s\"." : "%s us ha anomenat en un comentari sobre \"%s\".",
|
||||
"{user} has mentioned you in a comment on {deck-card}." : "{user} us ha mencionat en un comentari a {deck-card}.",
|
||||
@@ -88,7 +88,7 @@ OC.L10N.register(
|
||||
"copy" : "còpia",
|
||||
"To do" : "Pendent",
|
||||
"Doing" : "En procés",
|
||||
"Done" : "Fet",
|
||||
"Done" : "Finalitzat",
|
||||
"Example Task 3" : "Tasca d'exemple 3",
|
||||
"Example Task 2" : "Tasca d'exemple 2",
|
||||
"Example Task 1" : "Tasca d'exemple 1",
|
||||
@@ -99,7 +99,7 @@ OC.L10N.register(
|
||||
"No file was uploaded" : "No s'ha pujat cap fitxer",
|
||||
"Missing a temporary folder" : "Falta una carpeta temporal",
|
||||
"Could not write file to disk" : "No s’ha pogut escriure el fitxer al disc",
|
||||
"A PHP extension stopped the file upload" : "Una extensió del PHP ha aturat la pujada del fitxer",
|
||||
"A PHP extension stopped the file upload" : "Una extensió del PHP ha aturat la carregada del fitxer",
|
||||
"No file uploaded or file size exceeds maximum of %s" : "No s'ha carregat cap fitxer o la mida del fitxer sobrepassa el màxim de %s",
|
||||
"This comment has more than %s characters.\nAdded as an attachment to the card with name %s.\nAccessible on URL: %s." : "Aquest comentari té més de %s caràcters.\nS'ha afegit com a fitxer adjunt a la targeta amb el nom %s.\nAccessible a l'URL: %s.",
|
||||
"Card not found" : "No s'ha trobat la targeta",
|
||||
@@ -131,7 +131,7 @@ OC.L10N.register(
|
||||
"Overwrite file" : "Sobreescriu el fitxer",
|
||||
"Keep existing file" : "Mantén el fitxer existent",
|
||||
"This board is read only" : "Aquest tauler és només de lectura",
|
||||
"Drop your files to upload" : "Deixeu anar els fitxers per pujar-los",
|
||||
"Drop your files to upload" : "Deixeu anar els fitxers per penjar-los",
|
||||
"Add card" : "Afegeix una targeta",
|
||||
"Archived cards" : "Targetes arxivades",
|
||||
"Add list" : "Afegeix una llista",
|
||||
@@ -174,38 +174,36 @@ OC.L10N.register(
|
||||
"Can share" : "Pot compartir",
|
||||
"Can manage" : "Pot gestionar",
|
||||
"Owner" : "Propietari",
|
||||
"Delete" : "Suprimeix",
|
||||
"Delete" : "Eliminar",
|
||||
"Failed to create share with {displayName}" : "Ha fallat la creació de la compartició amb {displayName}",
|
||||
"Are you sure you want to transfer the board {title} to {user}?" : "Esteu segur que voleu transferir el tauler {title} a {user}?",
|
||||
"Transfer the board." : "Transfereix el tauler.",
|
||||
"Transfer" : "Transferència",
|
||||
"The board has been transferred to {user}" : "El tauler s'ha transferit a {user}",
|
||||
"Failed to transfer the board to {user}" : "No s'ha pogut transferir el tauler a {user}",
|
||||
"Add a new list" : "Afegeix una llista nova",
|
||||
"Add a new list" : "Afegir una llista nova",
|
||||
"Archive all cards" : "Arxiva totes les targetes",
|
||||
"Unarchive all cards" : "Desarxivar totes les targetes",
|
||||
"Delete list" : "Suprimeix la llista",
|
||||
"Archive all cards in this list" : "Arxiva totes les targetes d'aquesta llista",
|
||||
"Unarchive all cards in this list" : "Desarxivar totes les targetes d'aquesta llista",
|
||||
"Add a new card" : "Afegeix una nova targeta",
|
||||
"Add a new card" : "Afegir una nova targeta",
|
||||
"Card name" : "Nom de la targeta",
|
||||
"List deleted" : "Llista suprimida",
|
||||
"Edit" : "Edició",
|
||||
"Add a new tag" : "Afegeix una etiqueta nova",
|
||||
"Edit" : "Edita",
|
||||
"Add a new tag" : "Afegir una etiqueta nova",
|
||||
"title and color value must be provided" : "s’ha de proporcionar el valor del títol i del color",
|
||||
"Board name" : "Nom del taulell",
|
||||
"Members" : "Membres",
|
||||
"Upload new files" : "Pujada de nous fitxers",
|
||||
"Upload new files" : "Puja nous fitxers",
|
||||
"Share from Files" : "Comparteix des de Fitxers",
|
||||
"Pending share" : "Compartició pendent",
|
||||
"Add this attachment" : "Afegeix aquest adjunt",
|
||||
"Show in Files" : "Mostra a Fitxers",
|
||||
"Download" : "Baixada",
|
||||
"Download" : "Baixa",
|
||||
"Remove attachment" : "Treu l'adjunt",
|
||||
"Delete Attachment" : "Suprimeix l’adjunt",
|
||||
"Restore Attachment" : "Restaura l'adjunt",
|
||||
"File to share" : "Fitxer a compartir",
|
||||
"Invalid path selected" : "S'ha seleccionat un camí no vàlid",
|
||||
"Invalid path selected" : "S'ha seleccionat una ruta invàlida",
|
||||
"Open in sidebar view" : "Obre a la vista de la barra lateral",
|
||||
"Open in bigger view" : "Obre a la vista més gran",
|
||||
"Attachments" : "Adjunts",
|
||||
@@ -215,13 +213,13 @@ OC.L10N.register(
|
||||
"The title cannot be empty." : "El títol no pot estar buit.",
|
||||
"No comments yet. Begin the discussion!" : "No hi ha comentaris encara. Començar la discussió!",
|
||||
"Failed to load comments" : "No s'han pogut carregar els comentaris",
|
||||
"Assign a tag to this card…" : "Assignació d'una etiqueta a aquesta targeta…",
|
||||
"Assign to users" : "Assignació als usuaris",
|
||||
"Assign to users/groups/circles" : "Assignació a usuaris/grups/cercles",
|
||||
"Assign a user to this card…" : "Assignació d'un usuari a aquesta targeta…",
|
||||
"Due date" : "Data de caducitat",
|
||||
"Set a due date" : "Definir una data de caducitat",
|
||||
"Remove due date" : "Suprimeix la data de caducitat",
|
||||
"Assign a tag to this card…" : "Assigna una etiqueta a aquesta targeta…",
|
||||
"Assign to users" : "Assigna als usuaris",
|
||||
"Assign to users/groups/circles" : "Assigna a usuaris/grups/cercles",
|
||||
"Assign a user to this card…" : "Assigneu un usuari a aquesta targeta…",
|
||||
"Due date" : "Per la data",
|
||||
"Set a due date" : "Definir una data de venciment",
|
||||
"Remove due date" : "Elimina la data de venciment",
|
||||
"Select Date" : "Selecciona la data",
|
||||
"Today" : "Avui",
|
||||
"Tomorrow" : "Demà",
|
||||
@@ -238,15 +236,15 @@ OC.L10N.register(
|
||||
"(Unsaved)" : "(No desat)",
|
||||
"(Saving…)" : "(Desant…)",
|
||||
"Formatting help" : "Format d'ajuda",
|
||||
"Edit description" : "Edició descripció",
|
||||
"Edit description" : "Edita descripció",
|
||||
"View description" : "Veure descripció",
|
||||
"Add Attachment" : "Afegeix un adjunt",
|
||||
"Write a description …" : "Escriviu una descripció …",
|
||||
"Choose attachment" : "Triar adjunt",
|
||||
"(group)" : "(grup)",
|
||||
"Todo items" : "Tasques pendents",
|
||||
"Todo items" : "Elements pendents",
|
||||
"{count} comments, {unread} unread" : "{count} comentaris, {unread} no llegits",
|
||||
"Edit card title" : "Edició del títol de la targeta",
|
||||
"Edit card title" : "Edita el títol de la targeta",
|
||||
"Assign to me" : "Assigna'm a mi",
|
||||
"Unassign myself" : "Desasignar a mi mateix",
|
||||
"Move card" : "Mou la targeta",
|
||||
@@ -260,9 +258,8 @@ OC.L10N.register(
|
||||
"All boards" : "Tots els taulers",
|
||||
"Archived boards" : "Taulers arxivats",
|
||||
"Shared with you" : "Us han compartit",
|
||||
"Deck settings" : "Paràmetres del Tauler",
|
||||
"Deck settings" : "Configuració del Tauler",
|
||||
"Use bigger card view" : "Utilitza la visualització de targetes més gran",
|
||||
"Show card ID badge" : "Mostra el distintiu d’ID de la targeta",
|
||||
"Show boards in calendar/tasks" : "Mostra els taulers al calendari/tasques",
|
||||
"Limit deck usage of groups" : "Limitar l'ús del tauler de grups",
|
||||
"Limiting Deck will block users not part of those groups from creating their own boards. Users will still be able to work on boards that have been shared with them." : "Limitant el Tauler bloquejarà la creació de taulers als usuaris que no són part d'aquests grups. Els usuaris podran seguir treballant en els taulers que hagin estat compartits amb ells.",
|
||||
|
||||
65
l10n/ca.json
65
l10n/ca.json
@@ -27,7 +27,7 @@
|
||||
"{user} has deleted card {card} in list {stack} on board {board}" : "{user} ha suprimit la targeta {card} a la llista {stack} al tauler {board}",
|
||||
"You have renamed the card {before} to {card}" : "Heu reanomenat la targeta {before} a {card}",
|
||||
"{user} has renamed the card {before} to {card}" : "{user} ha reanomenat la targeta {before} a {card}",
|
||||
"You have added a description to card {card} in list {stack} on board {board}" : "Heu afegit una descripció a la targeta {card} a la llista {stack} del tauler {board}",
|
||||
"You have added a description to card {card} in list {stack} on board {board}" : "Heu afegit una descripció a la targeta {card} a la llista {stack} al tauler {board}",
|
||||
"{user} has added a description to card {card} in list {stack} on board {board}" : "{user} ha afegit una descripció a la targeta {card} a la llista {stack} al tauler {board}",
|
||||
"You have updated the description of card {card} in list {stack} on board {board}" : "Heu actualitzat la descripció de la targeta {card} a la llista {stack} al tauler {board}",
|
||||
"{user} has updated the description of the card {card} in list {stack} on board {board}" : "{user} ha actualitzat la descripció de la targeta {card} a la llista {stack} al tauler {board}",
|
||||
@@ -35,12 +35,12 @@
|
||||
"{user} has archived card {card} in list {stack} on board {board}" : "{user} té la targeta arxivada {card} a la llista {stack} al tauler {board}",
|
||||
"You have unarchived card {card} in list {stack} on board {board}" : "Teniu una targeta no-arxchivada {card} a la llista {stack} al tauler {board}",
|
||||
"{user} has unarchived card {card} in list {stack} on board {board}" : "{user} té una targeta no-arxivada {card} a la llista {stack} al tauler {board}",
|
||||
"You have removed the due date of card {card}" : "Heu suprimit la data de caducitat de la targeta {targeta}",
|
||||
"{user} has removed the due date of card {card}" : "{user} ha suprimit la data de caducitat de la targeta {targeta}",
|
||||
"You have set the due date of card {card} to {after}" : "Heu establert la data de caducitat de la targeta {card} a {after}",
|
||||
"{user} has set the due date of card {card} to {after}" : "{user} ha establert la data de caducitat de la targeta {card} a {after}",
|
||||
"You have updated the due date of card {card} to {after}" : "Heu actualitzat la data de caducitat de la targeta {card} a {after}",
|
||||
"{user} has updated the due date of card {card} to {after}" : "{user} ha actualitzat la data de caducitat de la targeta {card} a {after}",
|
||||
"You have removed the due date of card {card}" : "Heu suprimit la data de venciment de la targeta {targeta}",
|
||||
"{user} has removed the due date of card {card}" : "{user} ha suprimit la data de venciment de la targeta {targeta}",
|
||||
"You have set the due date of card {card} to {after}" : "Heu establert la data de venciment de la targeta {card} a {after}",
|
||||
"{user} has set the due date of card {card} to {after}" : "{user} ha establert la data de venciment de la targeta {card} a {after}",
|
||||
"You have updated the due date of card {card} to {after}" : "Heu actualitzat la data de venciment de la targeta {card} a {after}",
|
||||
"{user} has updated the due date of card {card} to {after}" : "{user} ha actualitzat la data de venciment de la targeta {card} a {after}",
|
||||
"You have added the tag {label} to card {card} in list {stack} on board {board}" : "Heu afegit l'etiqueta {label} a la targeta {card} a la llista {stack} al tauler {board}",
|
||||
"{user} has added the tag {label} to card {card} in list {stack} on board {board}" : "{user} ha afegit l'etiqueta {label} a la targeta {card} a la llista {stack} al tauler {board}",
|
||||
"You have removed the tag {label} from card {card} in list {stack} on board {board}" : "Heu eliminat l'etiqueta {label} de la targeta {card} a la llista {stack} al tauler {board}",
|
||||
@@ -64,13 +64,13 @@
|
||||
"A <strong>card description</strong> inside the Deck app has been changed" : "S'ha canviat una <strong>descripció de targeta</strong> a l'aplicació Tauler",
|
||||
"Deck" : "Targetes",
|
||||
"Changes in the <strong>Deck app</strong>" : "Canvis a l'<strong>aplicació Targetes</strong>",
|
||||
"A <strong>comment</strong> was created on a card" : "S'ha creat un <strong>comentari</strong> a una targeta",
|
||||
"A <strong>comment</strong> was created on a card" : "S'ha afegit un <strong>comentari</strong> a una targeta",
|
||||
"Upcoming cards" : "Pròximes targetes",
|
||||
"Load more" : "Carrega'n més",
|
||||
"Personal" : "Personal",
|
||||
"The card \"%s\" on \"%s\" has been assigned to you by %s." : "La targeta \"%s\" sobre \"%s\" se us ha assignat per %s.",
|
||||
"{user} has assigned the card {deck-card} on {deck-board} to you." : "{user} us ha assignat la targeta {deck-card} a {deck-board}.",
|
||||
"The card \"%s\" on \"%s\" has reached its due date." : "La targeta \"%s\" sobre \"%s\" ha assolit la seva data de caducitat.",
|
||||
"The card \"%s\" on \"%s\" has reached its due date." : "La targeta \"%s\" sobre \"%s\" ha assolit la seva data de venciment.",
|
||||
"The card {deck-card} on {deck-board} has reached its due date." : "La targeta {deck-card} a {deck-board} ha assolit la seva data de caducitat.",
|
||||
"%s has mentioned you in a comment on \"%s\"." : "%s us ha anomenat en un comentari sobre \"%s\".",
|
||||
"{user} has mentioned you in a comment on {deck-card}." : "{user} us ha mencionat en un comentari a {deck-card}.",
|
||||
@@ -86,7 +86,7 @@
|
||||
"copy" : "còpia",
|
||||
"To do" : "Pendent",
|
||||
"Doing" : "En procés",
|
||||
"Done" : "Fet",
|
||||
"Done" : "Finalitzat",
|
||||
"Example Task 3" : "Tasca d'exemple 3",
|
||||
"Example Task 2" : "Tasca d'exemple 2",
|
||||
"Example Task 1" : "Tasca d'exemple 1",
|
||||
@@ -97,7 +97,7 @@
|
||||
"No file was uploaded" : "No s'ha pujat cap fitxer",
|
||||
"Missing a temporary folder" : "Falta una carpeta temporal",
|
||||
"Could not write file to disk" : "No s’ha pogut escriure el fitxer al disc",
|
||||
"A PHP extension stopped the file upload" : "Una extensió del PHP ha aturat la pujada del fitxer",
|
||||
"A PHP extension stopped the file upload" : "Una extensió del PHP ha aturat la carregada del fitxer",
|
||||
"No file uploaded or file size exceeds maximum of %s" : "No s'ha carregat cap fitxer o la mida del fitxer sobrepassa el màxim de %s",
|
||||
"This comment has more than %s characters.\nAdded as an attachment to the card with name %s.\nAccessible on URL: %s." : "Aquest comentari té més de %s caràcters.\nS'ha afegit com a fitxer adjunt a la targeta amb el nom %s.\nAccessible a l'URL: %s.",
|
||||
"Card not found" : "No s'ha trobat la targeta",
|
||||
@@ -129,7 +129,7 @@
|
||||
"Overwrite file" : "Sobreescriu el fitxer",
|
||||
"Keep existing file" : "Mantén el fitxer existent",
|
||||
"This board is read only" : "Aquest tauler és només de lectura",
|
||||
"Drop your files to upload" : "Deixeu anar els fitxers per pujar-los",
|
||||
"Drop your files to upload" : "Deixeu anar els fitxers per penjar-los",
|
||||
"Add card" : "Afegeix una targeta",
|
||||
"Archived cards" : "Targetes arxivades",
|
||||
"Add list" : "Afegeix una llista",
|
||||
@@ -172,38 +172,36 @@
|
||||
"Can share" : "Pot compartir",
|
||||
"Can manage" : "Pot gestionar",
|
||||
"Owner" : "Propietari",
|
||||
"Delete" : "Suprimeix",
|
||||
"Delete" : "Eliminar",
|
||||
"Failed to create share with {displayName}" : "Ha fallat la creació de la compartició amb {displayName}",
|
||||
"Are you sure you want to transfer the board {title} to {user}?" : "Esteu segur que voleu transferir el tauler {title} a {user}?",
|
||||
"Transfer the board." : "Transfereix el tauler.",
|
||||
"Transfer" : "Transferència",
|
||||
"The board has been transferred to {user}" : "El tauler s'ha transferit a {user}",
|
||||
"Failed to transfer the board to {user}" : "No s'ha pogut transferir el tauler a {user}",
|
||||
"Add a new list" : "Afegeix una llista nova",
|
||||
"Add a new list" : "Afegir una llista nova",
|
||||
"Archive all cards" : "Arxiva totes les targetes",
|
||||
"Unarchive all cards" : "Desarxivar totes les targetes",
|
||||
"Delete list" : "Suprimeix la llista",
|
||||
"Archive all cards in this list" : "Arxiva totes les targetes d'aquesta llista",
|
||||
"Unarchive all cards in this list" : "Desarxivar totes les targetes d'aquesta llista",
|
||||
"Add a new card" : "Afegeix una nova targeta",
|
||||
"Add a new card" : "Afegir una nova targeta",
|
||||
"Card name" : "Nom de la targeta",
|
||||
"List deleted" : "Llista suprimida",
|
||||
"Edit" : "Edició",
|
||||
"Add a new tag" : "Afegeix una etiqueta nova",
|
||||
"Edit" : "Edita",
|
||||
"Add a new tag" : "Afegir una etiqueta nova",
|
||||
"title and color value must be provided" : "s’ha de proporcionar el valor del títol i del color",
|
||||
"Board name" : "Nom del taulell",
|
||||
"Members" : "Membres",
|
||||
"Upload new files" : "Pujada de nous fitxers",
|
||||
"Upload new files" : "Puja nous fitxers",
|
||||
"Share from Files" : "Comparteix des de Fitxers",
|
||||
"Pending share" : "Compartició pendent",
|
||||
"Add this attachment" : "Afegeix aquest adjunt",
|
||||
"Show in Files" : "Mostra a Fitxers",
|
||||
"Download" : "Baixada",
|
||||
"Download" : "Baixa",
|
||||
"Remove attachment" : "Treu l'adjunt",
|
||||
"Delete Attachment" : "Suprimeix l’adjunt",
|
||||
"Restore Attachment" : "Restaura l'adjunt",
|
||||
"File to share" : "Fitxer a compartir",
|
||||
"Invalid path selected" : "S'ha seleccionat un camí no vàlid",
|
||||
"Invalid path selected" : "S'ha seleccionat una ruta invàlida",
|
||||
"Open in sidebar view" : "Obre a la vista de la barra lateral",
|
||||
"Open in bigger view" : "Obre a la vista més gran",
|
||||
"Attachments" : "Adjunts",
|
||||
@@ -213,13 +211,13 @@
|
||||
"The title cannot be empty." : "El títol no pot estar buit.",
|
||||
"No comments yet. Begin the discussion!" : "No hi ha comentaris encara. Començar la discussió!",
|
||||
"Failed to load comments" : "No s'han pogut carregar els comentaris",
|
||||
"Assign a tag to this card…" : "Assignació d'una etiqueta a aquesta targeta…",
|
||||
"Assign to users" : "Assignació als usuaris",
|
||||
"Assign to users/groups/circles" : "Assignació a usuaris/grups/cercles",
|
||||
"Assign a user to this card…" : "Assignació d'un usuari a aquesta targeta…",
|
||||
"Due date" : "Data de caducitat",
|
||||
"Set a due date" : "Definir una data de caducitat",
|
||||
"Remove due date" : "Suprimeix la data de caducitat",
|
||||
"Assign a tag to this card…" : "Assigna una etiqueta a aquesta targeta…",
|
||||
"Assign to users" : "Assigna als usuaris",
|
||||
"Assign to users/groups/circles" : "Assigna a usuaris/grups/cercles",
|
||||
"Assign a user to this card…" : "Assigneu un usuari a aquesta targeta…",
|
||||
"Due date" : "Per la data",
|
||||
"Set a due date" : "Definir una data de venciment",
|
||||
"Remove due date" : "Elimina la data de venciment",
|
||||
"Select Date" : "Selecciona la data",
|
||||
"Today" : "Avui",
|
||||
"Tomorrow" : "Demà",
|
||||
@@ -236,15 +234,15 @@
|
||||
"(Unsaved)" : "(No desat)",
|
||||
"(Saving…)" : "(Desant…)",
|
||||
"Formatting help" : "Format d'ajuda",
|
||||
"Edit description" : "Edició descripció",
|
||||
"Edit description" : "Edita descripció",
|
||||
"View description" : "Veure descripció",
|
||||
"Add Attachment" : "Afegeix un adjunt",
|
||||
"Write a description …" : "Escriviu una descripció …",
|
||||
"Choose attachment" : "Triar adjunt",
|
||||
"(group)" : "(grup)",
|
||||
"Todo items" : "Tasques pendents",
|
||||
"Todo items" : "Elements pendents",
|
||||
"{count} comments, {unread} unread" : "{count} comentaris, {unread} no llegits",
|
||||
"Edit card title" : "Edició del títol de la targeta",
|
||||
"Edit card title" : "Edita el títol de la targeta",
|
||||
"Assign to me" : "Assigna'm a mi",
|
||||
"Unassign myself" : "Desasignar a mi mateix",
|
||||
"Move card" : "Mou la targeta",
|
||||
@@ -258,9 +256,8 @@
|
||||
"All boards" : "Tots els taulers",
|
||||
"Archived boards" : "Taulers arxivats",
|
||||
"Shared with you" : "Us han compartit",
|
||||
"Deck settings" : "Paràmetres del Tauler",
|
||||
"Deck settings" : "Configuració del Tauler",
|
||||
"Use bigger card view" : "Utilitza la visualització de targetes més gran",
|
||||
"Show card ID badge" : "Mostra el distintiu d’ID de la targeta",
|
||||
"Show boards in calendar/tasks" : "Mostra els taulers al calendari/tasques",
|
||||
"Limit deck usage of groups" : "Limitar l'ús del tauler de grups",
|
||||
"Limiting Deck will block users not part of those groups from creating their own boards. Users will still be able to work on boards that have been shared with them." : "Limitant el Tauler bloquejarà la creació de taulers als usuaris que no són part d'aquests grups. Els usuaris podran seguir treballant en els taulers que hagin estat compartits amb ells.",
|
||||
|
||||
@@ -37,7 +37,6 @@ OC.L10N.register(
|
||||
"The card \"%s\" on \"%s\" has reached its due date." : "Kortet \"%s\" på \"%s\" har nået sin forfaldsdato.",
|
||||
"%s has mentioned you in a comment on \"%s\"." : " %s har nævnt dig i en kommentar på \"%s\".",
|
||||
"The board \"%s\" has been shared with you by %s." : "Tavlen \"%s\" er blevet delt med dig af %s.",
|
||||
"%s on %s" : "%s på %s",
|
||||
"No data was provided to create an attachment." : "Ingen data blev givet som kunne vedhæftes",
|
||||
"Finished" : "Færdiggjort",
|
||||
"To review" : "Til gennemgang",
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
"The card \"%s\" on \"%s\" has reached its due date." : "Kortet \"%s\" på \"%s\" har nået sin forfaldsdato.",
|
||||
"%s has mentioned you in a comment on \"%s\"." : " %s har nævnt dig i en kommentar på \"%s\".",
|
||||
"The board \"%s\" has been shared with you by %s." : "Tavlen \"%s\" er blevet delt med dig af %s.",
|
||||
"%s on %s" : "%s på %s",
|
||||
"No data was provided to create an attachment." : "Ingen data blev givet som kunne vedhæftes",
|
||||
"Finished" : "Færdiggjort",
|
||||
"To review" : "Til gennemgang",
|
||||
|
||||
@@ -245,7 +245,7 @@ OC.L10N.register(
|
||||
"Archive card" : "Αρχειοθέτηση καρτέλας",
|
||||
"Delete card" : "Διαγραφή καρτέλας",
|
||||
"Move card to another board" : "Μετακίνηση καρτέλας σε άλλο πίνακα",
|
||||
"List is empty" : "Η λίστα είναι κενή",
|
||||
"List is empty" : "Η λίστα είναι άδεια.",
|
||||
"Card deleted" : "Η καρτέλα διαγράφηκε",
|
||||
"seconds ago" : " δευτερόλεπτα πριν ",
|
||||
"All boards" : "Όλοι οι πίνακες",
|
||||
|
||||
@@ -243,7 +243,7 @@
|
||||
"Archive card" : "Αρχειοθέτηση καρτέλας",
|
||||
"Delete card" : "Διαγραφή καρτέλας",
|
||||
"Move card to another board" : "Μετακίνηση καρτέλας σε άλλο πίνακα",
|
||||
"List is empty" : "Η λίστα είναι κενή",
|
||||
"List is empty" : "Η λίστα είναι άδεια.",
|
||||
"Card deleted" : "Η καρτέλα διαγράφηκε",
|
||||
"seconds ago" : " δευτερόλεπτα πριν ",
|
||||
"All boards" : "Όλοι οι πίνακες",
|
||||
|
||||
237
l10n/en_GB.js
237
l10n/en_GB.js
@@ -1,97 +1,17 @@
|
||||
OC.L10N.register(
|
||||
"deck",
|
||||
{
|
||||
"You have created a new board {board}" : "You have created a new board {board}",
|
||||
"{user} has created a new board {board}" : "{user} has created a new board {board}",
|
||||
"You have deleted the board {board}" : "You have deleted the board {board}",
|
||||
"{user} has deleted the board {board}" : "{user} has deleted the board {board}",
|
||||
"You have restored the board {board}" : "You have restored the board {board}",
|
||||
"{user} has restored the board {board}" : "{user} has restored the board {board}",
|
||||
"You have shared the board {board} with {acl}" : "You have shared the board {board} with {acl}",
|
||||
"{user} has shared the board {board} with {acl}" : "{user} has shared the board {board} with {acl}",
|
||||
"You have removed {acl} from the board {board}" : "You have removed {acl} from the board {board}",
|
||||
"{user} has removed {acl} from the board {board}" : "{user} has removed {acl} from the board {board}",
|
||||
"You have renamed the board {before} to {board}" : "You have renamed the board {before} to {board}",
|
||||
"{user} has renamed the board {before} to {board}" : "{user} has renamed the board {before} to {board}",
|
||||
"You have archived the board {board}" : "You have archived the board {board}",
|
||||
"{user} has archived the board {before}" : "{user} has archived the board {before}",
|
||||
"You have unarchived the board {board}" : "You have unarchived the board {board}",
|
||||
"{user} has unarchived the board {before}" : "{user} has unarchived the board {before}",
|
||||
"You have created a new list {stack} on board {board}" : "You have created a new list {stack} on board {board}",
|
||||
"{user} has created a new list {stack} on board {board}" : "{user} has created a new list {stack} on board {board}",
|
||||
"You have renamed list {before} to {stack} on board {board}" : "You have renamed list {before} to {stack} on board {board}",
|
||||
"{user} has renamed list {before} to {stack} on board {board}" : "{user} has renamed list {before} to {stack} on board {board}",
|
||||
"You have deleted list {stack} on board {board}" : "You have deleted list {stack} on board {board}",
|
||||
"{user} has deleted list {stack} on board {board}" : "{user} has deleted list {stack} on board {board}",
|
||||
"You have created card {card} in list {stack} on board {board}" : "You have created card {card} in list {stack} on board {board}",
|
||||
"{user} has created card {card} in list {stack} on board {board}" : "{user} has created card {card} in list {stack} on board {board}",
|
||||
"You have deleted card {card} in list {stack} on board {board}" : "You have deleted card {card} in list {stack} on board {board}",
|
||||
"{user} has deleted card {card} in list {stack} on board {board}" : "{user} has deleted card {card} in list {stack} on board {board}",
|
||||
"You have renamed the card {before} to {card}" : "You have renamed the card {before} to {card}",
|
||||
"{user} has renamed the card {before} to {card}" : "{user} has renamed the card {before} to {card}",
|
||||
"You have added a description to card {card} in list {stack} on board {board}" : "You have added a description to card {card} in list {stack} on board {board}",
|
||||
"{user} has added a description to card {card} in list {stack} on board {board}" : "{user} has added a description to card {card} in list {stack} on board {board}",
|
||||
"You have updated the description of card {card} in list {stack} on board {board}" : "You have updated the description of card {card} in list {stack} on board {board}",
|
||||
"{user} has updated the description of the card {card} in list {stack} on board {board}" : "{user} has updated the description of the card {card} in list {stack} on board {board}",
|
||||
"You have archived card {card} in list {stack} on board {board}" : "You have archived card {card} in list {stack} on board {board}",
|
||||
"{user} has archived card {card} in list {stack} on board {board}" : "{user} has archived card {card} in list {stack} on board {board}",
|
||||
"You have unarchived card {card} in list {stack} on board {board}" : "You have unarchived card {card} in list {stack} on board {board}",
|
||||
"{user} has unarchived card {card} in list {stack} on board {board}" : "{user} has unarchived card {card} in list {stack} on board {board}",
|
||||
"You have removed the due date of card {card}" : "You have removed the due date of card {card}",
|
||||
"{user} has removed the due date of card {card}" : "{user} has removed the due date of card {card}",
|
||||
"You have set the due date of card {card} to {after}" : "You have set the due date of card {card} to {after}",
|
||||
"{user} has set the due date of card {card} to {after}" : "{user} has set the due date of card {card} to {after}",
|
||||
"You have updated the due date of card {card} to {after}" : "You have updated the due date of card {card} to {after}",
|
||||
"{user} has updated the due date of card {card} to {after}" : "{user} has updated the due date of card {card} to {after}",
|
||||
"You have added the tag {label} to card {card} in list {stack} on board {board}" : "You have added the tag {label} to card {card} in list {stack} on board {board}",
|
||||
"{user} has added the tag {label} to card {card} in list {stack} on board {board}" : "{user} has added the tag {label} to card {card} in list {stack} on board {board}",
|
||||
"You have removed the tag {label} from card {card} in list {stack} on board {board}" : "You have removed the tag {label} from card {card} in list {stack} on board {board}",
|
||||
"{user} has removed the tag {label} from card {card} in list {stack} on board {board}" : "{user} has removed the tag {label} from card {card} in list {stack} on board {board}",
|
||||
"You have assigned {assigneduser} to card {card} on board {board}" : "You have assigned {assigneduser} to card {card} on board {board}",
|
||||
"{user} has assigned {assigneduser} to card {card} on board {board}" : "{user} has assigned {assigneduser} to card {card} on board {board}",
|
||||
"You have unassigned {assigneduser} from card {card} on board {board}" : "You have unassigned {assigneduser} from card {card} on board {board}",
|
||||
"{user} has unassigned {assigneduser} from card {card} on board {board}" : "{user} has unassigned {assigneduser} from card {card} on board {board}",
|
||||
"You have moved the card {card} from list {stackBefore} to {stack}" : "You have moved the card {card} from list {stackBefore} to {stack}",
|
||||
"{user} has moved the card {card} from list {stackBefore} to {stack}" : "{user} has moved the card {card} from list {stackBefore} to {stack}",
|
||||
"You have added the attachment {attachment} to card {card}" : "You have added the attachment {attachment} to card {card}",
|
||||
"{user} has added the attachment {attachment} to card {card}" : "{user} has added the attachment {attachment} to card {card}",
|
||||
"You have updated the attachment {attachment} on card {card}" : "You have updated the attachment {attachment} on card {card}",
|
||||
"{user} has updated the attachment {attachment} on card {card}" : "{user} has updated the attachment {attachment} on card {card}",
|
||||
"You have deleted the attachment {attachment} from card {card}" : "You have deleted the attachment {attachment} from card {card}",
|
||||
"{user} has deleted the attachment {attachment} from card {card}" : "{user} has deleted the attachment {attachment} from card {card}",
|
||||
"You have restored the attachment {attachment} to card {card}" : "You have restored the attachment {attachment} to card {card}",
|
||||
"{user} has restored the attachment {attachment} to card {card}" : "{user} has restored the attachment {attachment} to card {card}",
|
||||
"You have commented on card {card}" : "You have commented on card {card}",
|
||||
"{user} has commented on card {card}" : "{user} has commented on card {card}",
|
||||
"A <strong>card description</strong> inside the Deck app has been changed" : "A <strong>card description</strong> inside the Deck app has been changed",
|
||||
"Deck" : "Deck",
|
||||
"Changes in the <strong>Deck app</strong>" : "Changes in the <strong>Deck app</strong>",
|
||||
"A <strong>comment</strong> was created on a card" : "A <strong>comment</strong> was created on a card",
|
||||
"Upcoming cards" : "Upcoming cards",
|
||||
"Load more" : "Load more",
|
||||
"Personal" : "Personal",
|
||||
"The card \"%s\" on \"%s\" has been assigned to you by %s." : "The card \"%s\" on \"%s\" has been assigned to you by %s.",
|
||||
"{user} has assigned the card {deck-card} on {deck-board} to you." : "{user} has assigned the card {deck-card} on {deck-board} to you.",
|
||||
"The card \"%s\" on \"%s\" has reached its due date." : "The card \"%s\" on \"%s\" has reached its due date.",
|
||||
"The card {deck-card} on {deck-board} has reached its due date." : "The card {deck-card} on {deck-board} has reached its due date.",
|
||||
"%s has mentioned you in a comment on \"%s\"." : "%s has mentioned you in a comment on \"%s\".",
|
||||
"{user} has mentioned you in a comment on {deck-card}." : "{user} has mentioned you in a comment on {deck-card}.",
|
||||
"The board \"%s\" has been shared with you by %s." : "The board \"%s\" has been shared with you by %s.",
|
||||
"{user} has shared {deck-board} with you." : "{user} has shared {deck-board} with you.",
|
||||
"Card comments" : "Card comments",
|
||||
"%s on %s" : "%s on %s",
|
||||
"No data was provided to create an attachment." : "No data was provided to create an attachment.",
|
||||
"Finished" : "Finished",
|
||||
"To review" : "To review",
|
||||
"Action needed" : "Action needed",
|
||||
"Later" : "Later",
|
||||
"copy" : "copy",
|
||||
"To do" : "To do",
|
||||
"Doing" : "Doing",
|
||||
"Done" : "Done",
|
||||
"Example Task 3" : "Example Task 3",
|
||||
"Example Task 2" : "Example Task 2",
|
||||
"Example Task 1" : "Example Task 1",
|
||||
"The file was uploaded" : "The file was uploaded",
|
||||
"The uploaded file exceeds the upload_max_filesize directive in php.ini" : "The uploaded file exceeds the upload_max_filesize directive in php.ini",
|
||||
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form",
|
||||
@@ -100,218 +20,63 @@ OC.L10N.register(
|
||||
"Missing a temporary folder" : "Missing a temporary folder",
|
||||
"Could not write file to disk" : "Could not write file to disk",
|
||||
"A PHP extension stopped the file upload" : "A PHP extension stopped the file upload",
|
||||
"No file uploaded or file size exceeds maximum of %s" : "No file uploaded or file size exceeds maximum of %s",
|
||||
"This comment has more than %s characters.\nAdded as an attachment to the card with name %s.\nAccessible on URL: %s." : "This comment has more than %s characters.\nAdded as an attachment to the card with name %s.\nAccessible on URL: %s.",
|
||||
"Card not found" : "Card not found",
|
||||
"Path is already shared with this card" : "Path is already shared with this card",
|
||||
"Invalid date, date format must be YYYY-MM-DD" : "Invalid date, date format must be YYYY-MM-DD",
|
||||
"Personal planning and team project organization" : "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 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",
|
||||
"Card details" : "Card details",
|
||||
"Add board" : "Add board",
|
||||
"Select the board to link to a project" : "Select the board to link to a project",
|
||||
"Search by board title" : "Search by board title",
|
||||
"Select board" : "Select board",
|
||||
"Create a new card" : "Create a new card",
|
||||
"Select a board" : "Select a board",
|
||||
"Select a list" : "Select a list",
|
||||
"Card title" : "Card title",
|
||||
"Cancel" : "Cancel",
|
||||
"Creating the new card …" : "Creating the new card …",
|
||||
"Card \"{card}\" was added to \"{board}\"" : "Card \"{card}\" was added to \"{board}\"",
|
||||
"Open card" : "Open card",
|
||||
"Close" : "Close",
|
||||
"Create card" : "Create card",
|
||||
"Select a card" : "Select a card",
|
||||
"Select the card to link to a project" : "Select the card to link to a project",
|
||||
"Link to card" : "Link to card",
|
||||
"File already exists" : "File already exists",
|
||||
"A file with the name {filename} already exists." : "A file with the name {filename} already exists.",
|
||||
"Do you want to overwrite it?" : "Do you want to overwrite it?",
|
||||
"Overwrite file" : "Overwrite file",
|
||||
"Keep existing file" : "Keep existing file",
|
||||
"This board is read only" : "This board is read only",
|
||||
"Drop your files to upload" : "Drop your files to upload",
|
||||
"Add card" : "Add card",
|
||||
"Archived cards" : "Archived cards",
|
||||
"Add list" : "Add list",
|
||||
"List name" : "List name",
|
||||
"Active filters" : "Active filters",
|
||||
"Apply filter" : "Apply filter",
|
||||
"Filter by tag" : "Filter by tag",
|
||||
"Filter by assigned user" : "Filter by assigned user",
|
||||
"Unassigned" : "Unassigned",
|
||||
"Filter by due date" : "Filter by due date",
|
||||
"Overdue" : "Overdue",
|
||||
"Next 24 hours" : "Next 24 hours",
|
||||
"Next 7 days" : "Next 7 days",
|
||||
"Next 30 days" : "Next 30 days",
|
||||
"No due date" : "No due date",
|
||||
"Clear filter" : "Clear filter",
|
||||
"Hide archived cards" : "Hide archived cards",
|
||||
"Show archived cards" : "Show archived cards",
|
||||
"Toggle compact mode" : "Toggle compact mode",
|
||||
"Open details" : "Open details",
|
||||
"Details" : "Details",
|
||||
"Loading board" : "Loading board",
|
||||
"No lists available" : "No lists available",
|
||||
"Create a new list to add cards to this board" : "Create a new list to add cards to this board",
|
||||
"Board not found" : "Board not found",
|
||||
"Sharing" : "Sharing",
|
||||
"Tags" : "Tags",
|
||||
"Deleted items" : "Deleted items",
|
||||
"Timeline" : "Timeline",
|
||||
"Deleted lists" : "Deleted lists",
|
||||
"Undo" : "Undo",
|
||||
"Deleted cards" : "Deleted cards",
|
||||
"Share board with a user, group or circle …" : "Share board with a user, group or circle …",
|
||||
"Searching for users, groups and circles …" : "Searching for users, groups and circles …",
|
||||
"No participants found" : "No participants found",
|
||||
"Board owner" : "Board owner",
|
||||
"(Group)" : "(Group)",
|
||||
"(Circle)" : "(Circle)",
|
||||
"Can edit" : "Can edit",
|
||||
"Can share" : "Can share",
|
||||
"Can manage" : "Can manage",
|
||||
"Owner" : "Owner",
|
||||
"Delete" : "Delete",
|
||||
"Failed to create share with {displayName}" : "Failed to create share with {displayName}",
|
||||
"Are you sure you want to transfer the board {title} to {user}?" : "Are you sure you want to transfer the board {title} to {user}?",
|
||||
"Transfer the board." : "Transfer the board.",
|
||||
"Transfer" : "Transfer",
|
||||
"The board has been transferred to {user}" : "The board has been transferred to {user}",
|
||||
"Failed to transfer the board to {user}" : "Failed to transfer the board to {user}",
|
||||
"Add a new list" : "Add a new list",
|
||||
"Archive all cards" : "Archive all cards",
|
||||
"Unarchive all cards" : "Unarchive all cards",
|
||||
"Delete list" : "Delete list",
|
||||
"Archive all cards in this list" : "Archive all cards in this list",
|
||||
"Unarchive all cards in this list" : "Unarchive all cards in this list",
|
||||
"Add a new card" : "Add a new card",
|
||||
"Card name" : "Card name",
|
||||
"List deleted" : "List deleted",
|
||||
"Edit" : "Edit",
|
||||
"Add a new tag" : "Add a new tag",
|
||||
"title and color value must be provided" : "title and colour value must be provided",
|
||||
"Board name" : "Board name",
|
||||
"Members" : "Members",
|
||||
"Upload new files" : "Upload new files",
|
||||
"Share from Files" : "Share from Files",
|
||||
"Pending share" : "Pending share",
|
||||
"Add this attachment" : "Add this attachment",
|
||||
"Show in Files" : "Show in Files",
|
||||
"Download" : "Download",
|
||||
"Remove attachment" : "Remove attachment",
|
||||
"Delete Attachment" : "Delete Attachment",
|
||||
"Restore Attachment" : "Restore Attachment",
|
||||
"File to share" : "File to share",
|
||||
"Invalid path selected" : "Invalid path selected",
|
||||
"Open in sidebar view" : "Open in sidebar view",
|
||||
"Open in bigger view" : "Open in bigger view",
|
||||
"Attachments" : "Attachments",
|
||||
"Comments" : "Comments",
|
||||
"Modified" : "Modified",
|
||||
"Created" : "Created",
|
||||
"The title cannot be empty." : "The title cannot be empty.",
|
||||
"No comments yet. Begin the discussion!" : "No comments yet. Begin the discussion!",
|
||||
"Failed to load comments" : "Failed to load comments",
|
||||
"Assign a tag to this card…" : "Assign a tag to this card…",
|
||||
"Assign to users" : "Assign to users",
|
||||
"Assign to users/groups/circles" : "Assign to users/groups/circles",
|
||||
"Assign a user to this card…" : "Assign a user to this card…",
|
||||
"Due date" : "Due date",
|
||||
"Set a due date" : "Set a due date",
|
||||
"Remove due date" : "Remove due date",
|
||||
"Select Date" : "Select Date",
|
||||
"Today" : "Today",
|
||||
"Tomorrow" : "Tomorrow",
|
||||
"Next week" : "Next week",
|
||||
"Next month" : "Next month",
|
||||
"Save" : "Save",
|
||||
"The comment cannot be empty." : "The comment cannot be empty.",
|
||||
"The comment cannot be longer than 1000 characters." : "The comment cannot be longer than 1000 characters.",
|
||||
"In reply to" : "In reply to",
|
||||
"Cancel reply" : "Cancel reply",
|
||||
"Reply" : "Reply",
|
||||
"Update" : "Update",
|
||||
"Description" : "Description",
|
||||
"(Unsaved)" : "(Unsaved)",
|
||||
"(Saving…)" : "(Saving…)",
|
||||
"Formatting help" : "Formatting help",
|
||||
"Edit description" : "Edit description",
|
||||
"View description" : "View description",
|
||||
"Add Attachment" : "Add Attachment",
|
||||
"Write a description …" : "Write a description …",
|
||||
"Choose attachment" : "Choose attachment",
|
||||
"(group)" : "(group)",
|
||||
"Todo items" : "Todo items",
|
||||
"{count} comments, {unread} unread" : "{count} comments, {unread} unread",
|
||||
"Edit card title" : "Edit card title",
|
||||
"Assign to me" : "Assign to me",
|
||||
"Unassign myself" : "Unassign myself",
|
||||
"Move card" : "Move card",
|
||||
"Unarchive card" : "Unarchive card",
|
||||
"Archive card" : "Archive card",
|
||||
"Delete card" : "Delete card",
|
||||
"Move card to another board" : "Move card to another board",
|
||||
"List is empty" : "List is empty",
|
||||
"Card deleted" : "Card deleted",
|
||||
"seconds ago" : "seconds ago",
|
||||
"All boards" : "All boards",
|
||||
"Archived boards" : "Archived boards",
|
||||
"Shared with you" : "Shared with you",
|
||||
"Deck settings" : "Deck settings",
|
||||
"Use bigger card view" : "Use bigger card view",
|
||||
"Show card ID badge" : "Show card ID badge",
|
||||
"Show boards in calendar/tasks" : "Show boards in calendar/tasks",
|
||||
"Limit deck usage of groups" : "Limit deck usage of groups",
|
||||
"Limiting Deck will block users not part of those groups from creating their own boards. Users will still be able to work on boards that have been shared with them." : "Limiting Deck will block users not part of those groups from creating their own boards. Users will still be able to work on boards that have been shared with them.",
|
||||
"Board details" : "Board details",
|
||||
"Edit board" : "Edit board",
|
||||
"Clone board" : "Clone board",
|
||||
"Unarchive board" : "Unarchive board",
|
||||
"Archive board" : "Archive board",
|
||||
"Turn on due date reminders" : "Turn on due date reminders",
|
||||
"Turn off due date reminders" : "Turn off due date reminders",
|
||||
"Due date reminders" : "Due date reminders",
|
||||
"All cards" : "All cards",
|
||||
"Assigned cards" : "Assigned cards",
|
||||
"No notifications" : "No notifications",
|
||||
"Delete board" : "Delete board",
|
||||
"Board {0} deleted" : "Board {0} deleted",
|
||||
"Only assigned cards" : "Only assigned cards",
|
||||
"No reminder" : "No reminder",
|
||||
"An error occurred" : "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." : "Are you sure you want to delete the board {title}? This will delete all the data of this board including archived cards.",
|
||||
"Delete the board?" : "Delete the board?",
|
||||
"Loading filtered view" : "Loading filtered view",
|
||||
"No due" : "No due",
|
||||
"Search for {searchQuery} in all boards" : "Search for {searchQuery} in all boards",
|
||||
"No results found" : "No results found",
|
||||
"{stack} in {board}" : "{stack} in {board}",
|
||||
"Click to expand description" : "Click to expand description",
|
||||
"* Created on {created}\n* Last modified on {lastMod}\n* {nbAttachments} attachments\n* {nbComments} comments" : "* Created on {created}\n* Last modified on {lastMod}\n* {nbAttachments} attachments\n* {nbComments} comments",
|
||||
"{nbCards} cards" : "{nbCards} cards",
|
||||
"No upcoming cards" : "No upcoming cards",
|
||||
"upcoming cards" : "upcoming cards",
|
||||
"Due on {date}" : "Due on {date}",
|
||||
"Link to a board" : "Link to a board",
|
||||
"Link to a card" : "Link to a card",
|
||||
"Create a card" : "Create a card",
|
||||
"Message from {author} in {conversationName}" : "Message from {author} in {conversationName}",
|
||||
"Something went wrong" : "Something went wrong",
|
||||
"Failed to upload {name}" : "Failed to upload {name}",
|
||||
"Maximum file size of {size} exceeded" : "Maximum file size of {size} exceeded",
|
||||
"Error creating the share" : "Error creating the share",
|
||||
"Share with a Deck card" : "Share with a Deck card",
|
||||
"Share {file} with a Deck card" : "Share {file} with a Deck card",
|
||||
"Share" : "Share",
|
||||
"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 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",
|
||||
"Are you sure you want to transfer the board {title} for {user} ?" : "Are you sure you want to transfer the board {title} for {user} ?",
|
||||
"Transfer the board for {user} successfully" : "Transfer the board for {user} successfully",
|
||||
"Failed to transfer the board for {user}" : "Failed to transfer the board for {user}",
|
||||
"Are you sure you want to delete the board {title}? This will delete all the data of this board." : "Are you sure you want to delete the board {title}? This will delete all the data of this board.",
|
||||
"This week" : "This week",
|
||||
"Are you sure you want to transfer the board {title} for {user}?" : "Are you sure you want to transfer the board {title} for {user}?"
|
||||
"This week" : "This week"
|
||||
},
|
||||
"nplurals=2; plural=(n != 1);");
|
||||
|
||||
237
l10n/en_GB.json
237
l10n/en_GB.json
@@ -1,95 +1,15 @@
|
||||
{ "translations": {
|
||||
"You have created a new board {board}" : "You have created a new board {board}",
|
||||
"{user} has created a new board {board}" : "{user} has created a new board {board}",
|
||||
"You have deleted the board {board}" : "You have deleted the board {board}",
|
||||
"{user} has deleted the board {board}" : "{user} has deleted the board {board}",
|
||||
"You have restored the board {board}" : "You have restored the board {board}",
|
||||
"{user} has restored the board {board}" : "{user} has restored the board {board}",
|
||||
"You have shared the board {board} with {acl}" : "You have shared the board {board} with {acl}",
|
||||
"{user} has shared the board {board} with {acl}" : "{user} has shared the board {board} with {acl}",
|
||||
"You have removed {acl} from the board {board}" : "You have removed {acl} from the board {board}",
|
||||
"{user} has removed {acl} from the board {board}" : "{user} has removed {acl} from the board {board}",
|
||||
"You have renamed the board {before} to {board}" : "You have renamed the board {before} to {board}",
|
||||
"{user} has renamed the board {before} to {board}" : "{user} has renamed the board {before} to {board}",
|
||||
"You have archived the board {board}" : "You have archived the board {board}",
|
||||
"{user} has archived the board {before}" : "{user} has archived the board {before}",
|
||||
"You have unarchived the board {board}" : "You have unarchived the board {board}",
|
||||
"{user} has unarchived the board {before}" : "{user} has unarchived the board {before}",
|
||||
"You have created a new list {stack} on board {board}" : "You have created a new list {stack} on board {board}",
|
||||
"{user} has created a new list {stack} on board {board}" : "{user} has created a new list {stack} on board {board}",
|
||||
"You have renamed list {before} to {stack} on board {board}" : "You have renamed list {before} to {stack} on board {board}",
|
||||
"{user} has renamed list {before} to {stack} on board {board}" : "{user} has renamed list {before} to {stack} on board {board}",
|
||||
"You have deleted list {stack} on board {board}" : "You have deleted list {stack} on board {board}",
|
||||
"{user} has deleted list {stack} on board {board}" : "{user} has deleted list {stack} on board {board}",
|
||||
"You have created card {card} in list {stack} on board {board}" : "You have created card {card} in list {stack} on board {board}",
|
||||
"{user} has created card {card} in list {stack} on board {board}" : "{user} has created card {card} in list {stack} on board {board}",
|
||||
"You have deleted card {card} in list {stack} on board {board}" : "You have deleted card {card} in list {stack} on board {board}",
|
||||
"{user} has deleted card {card} in list {stack} on board {board}" : "{user} has deleted card {card} in list {stack} on board {board}",
|
||||
"You have renamed the card {before} to {card}" : "You have renamed the card {before} to {card}",
|
||||
"{user} has renamed the card {before} to {card}" : "{user} has renamed the card {before} to {card}",
|
||||
"You have added a description to card {card} in list {stack} on board {board}" : "You have added a description to card {card} in list {stack} on board {board}",
|
||||
"{user} has added a description to card {card} in list {stack} on board {board}" : "{user} has added a description to card {card} in list {stack} on board {board}",
|
||||
"You have updated the description of card {card} in list {stack} on board {board}" : "You have updated the description of card {card} in list {stack} on board {board}",
|
||||
"{user} has updated the description of the card {card} in list {stack} on board {board}" : "{user} has updated the description of the card {card} in list {stack} on board {board}",
|
||||
"You have archived card {card} in list {stack} on board {board}" : "You have archived card {card} in list {stack} on board {board}",
|
||||
"{user} has archived card {card} in list {stack} on board {board}" : "{user} has archived card {card} in list {stack} on board {board}",
|
||||
"You have unarchived card {card} in list {stack} on board {board}" : "You have unarchived card {card} in list {stack} on board {board}",
|
||||
"{user} has unarchived card {card} in list {stack} on board {board}" : "{user} has unarchived card {card} in list {stack} on board {board}",
|
||||
"You have removed the due date of card {card}" : "You have removed the due date of card {card}",
|
||||
"{user} has removed the due date of card {card}" : "{user} has removed the due date of card {card}",
|
||||
"You have set the due date of card {card} to {after}" : "You have set the due date of card {card} to {after}",
|
||||
"{user} has set the due date of card {card} to {after}" : "{user} has set the due date of card {card} to {after}",
|
||||
"You have updated the due date of card {card} to {after}" : "You have updated the due date of card {card} to {after}",
|
||||
"{user} has updated the due date of card {card} to {after}" : "{user} has updated the due date of card {card} to {after}",
|
||||
"You have added the tag {label} to card {card} in list {stack} on board {board}" : "You have added the tag {label} to card {card} in list {stack} on board {board}",
|
||||
"{user} has added the tag {label} to card {card} in list {stack} on board {board}" : "{user} has added the tag {label} to card {card} in list {stack} on board {board}",
|
||||
"You have removed the tag {label} from card {card} in list {stack} on board {board}" : "You have removed the tag {label} from card {card} in list {stack} on board {board}",
|
||||
"{user} has removed the tag {label} from card {card} in list {stack} on board {board}" : "{user} has removed the tag {label} from card {card} in list {stack} on board {board}",
|
||||
"You have assigned {assigneduser} to card {card} on board {board}" : "You have assigned {assigneduser} to card {card} on board {board}",
|
||||
"{user} has assigned {assigneduser} to card {card} on board {board}" : "{user} has assigned {assigneduser} to card {card} on board {board}",
|
||||
"You have unassigned {assigneduser} from card {card} on board {board}" : "You have unassigned {assigneduser} from card {card} on board {board}",
|
||||
"{user} has unassigned {assigneduser} from card {card} on board {board}" : "{user} has unassigned {assigneduser} from card {card} on board {board}",
|
||||
"You have moved the card {card} from list {stackBefore} to {stack}" : "You have moved the card {card} from list {stackBefore} to {stack}",
|
||||
"{user} has moved the card {card} from list {stackBefore} to {stack}" : "{user} has moved the card {card} from list {stackBefore} to {stack}",
|
||||
"You have added the attachment {attachment} to card {card}" : "You have added the attachment {attachment} to card {card}",
|
||||
"{user} has added the attachment {attachment} to card {card}" : "{user} has added the attachment {attachment} to card {card}",
|
||||
"You have updated the attachment {attachment} on card {card}" : "You have updated the attachment {attachment} on card {card}",
|
||||
"{user} has updated the attachment {attachment} on card {card}" : "{user} has updated the attachment {attachment} on card {card}",
|
||||
"You have deleted the attachment {attachment} from card {card}" : "You have deleted the attachment {attachment} from card {card}",
|
||||
"{user} has deleted the attachment {attachment} from card {card}" : "{user} has deleted the attachment {attachment} from card {card}",
|
||||
"You have restored the attachment {attachment} to card {card}" : "You have restored the attachment {attachment} to card {card}",
|
||||
"{user} has restored the attachment {attachment} to card {card}" : "{user} has restored the attachment {attachment} to card {card}",
|
||||
"You have commented on card {card}" : "You have commented on card {card}",
|
||||
"{user} has commented on card {card}" : "{user} has commented on card {card}",
|
||||
"A <strong>card description</strong> inside the Deck app has been changed" : "A <strong>card description</strong> inside the Deck app has been changed",
|
||||
"Deck" : "Deck",
|
||||
"Changes in the <strong>Deck app</strong>" : "Changes in the <strong>Deck app</strong>",
|
||||
"A <strong>comment</strong> was created on a card" : "A <strong>comment</strong> was created on a card",
|
||||
"Upcoming cards" : "Upcoming cards",
|
||||
"Load more" : "Load more",
|
||||
"Personal" : "Personal",
|
||||
"The card \"%s\" on \"%s\" has been assigned to you by %s." : "The card \"%s\" on \"%s\" has been assigned to you by %s.",
|
||||
"{user} has assigned the card {deck-card} on {deck-board} to you." : "{user} has assigned the card {deck-card} on {deck-board} to you.",
|
||||
"The card \"%s\" on \"%s\" has reached its due date." : "The card \"%s\" on \"%s\" has reached its due date.",
|
||||
"The card {deck-card} on {deck-board} has reached its due date." : "The card {deck-card} on {deck-board} has reached its due date.",
|
||||
"%s has mentioned you in a comment on \"%s\"." : "%s has mentioned you in a comment on \"%s\".",
|
||||
"{user} has mentioned you in a comment on {deck-card}." : "{user} has mentioned you in a comment on {deck-card}.",
|
||||
"The board \"%s\" has been shared with you by %s." : "The board \"%s\" has been shared with you by %s.",
|
||||
"{user} has shared {deck-board} with you." : "{user} has shared {deck-board} with you.",
|
||||
"Card comments" : "Card comments",
|
||||
"%s on %s" : "%s on %s",
|
||||
"No data was provided to create an attachment." : "No data was provided to create an attachment.",
|
||||
"Finished" : "Finished",
|
||||
"To review" : "To review",
|
||||
"Action needed" : "Action needed",
|
||||
"Later" : "Later",
|
||||
"copy" : "copy",
|
||||
"To do" : "To do",
|
||||
"Doing" : "Doing",
|
||||
"Done" : "Done",
|
||||
"Example Task 3" : "Example Task 3",
|
||||
"Example Task 2" : "Example Task 2",
|
||||
"Example Task 1" : "Example Task 1",
|
||||
"The file was uploaded" : "The file was uploaded",
|
||||
"The uploaded file exceeds the upload_max_filesize directive in php.ini" : "The uploaded file exceeds the upload_max_filesize directive in php.ini",
|
||||
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form",
|
||||
@@ -98,218 +18,63 @@
|
||||
"Missing a temporary folder" : "Missing a temporary folder",
|
||||
"Could not write file to disk" : "Could not write file to disk",
|
||||
"A PHP extension stopped the file upload" : "A PHP extension stopped the file upload",
|
||||
"No file uploaded or file size exceeds maximum of %s" : "No file uploaded or file size exceeds maximum of %s",
|
||||
"This comment has more than %s characters.\nAdded as an attachment to the card with name %s.\nAccessible on URL: %s." : "This comment has more than %s characters.\nAdded as an attachment to the card with name %s.\nAccessible on URL: %s.",
|
||||
"Card not found" : "Card not found",
|
||||
"Path is already shared with this card" : "Path is already shared with this card",
|
||||
"Invalid date, date format must be YYYY-MM-DD" : "Invalid date, date format must be YYYY-MM-DD",
|
||||
"Personal planning and team project organization" : "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 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",
|
||||
"Card details" : "Card details",
|
||||
"Add board" : "Add board",
|
||||
"Select the board to link to a project" : "Select the board to link to a project",
|
||||
"Search by board title" : "Search by board title",
|
||||
"Select board" : "Select board",
|
||||
"Create a new card" : "Create a new card",
|
||||
"Select a board" : "Select a board",
|
||||
"Select a list" : "Select a list",
|
||||
"Card title" : "Card title",
|
||||
"Cancel" : "Cancel",
|
||||
"Creating the new card …" : "Creating the new card …",
|
||||
"Card \"{card}\" was added to \"{board}\"" : "Card \"{card}\" was added to \"{board}\"",
|
||||
"Open card" : "Open card",
|
||||
"Close" : "Close",
|
||||
"Create card" : "Create card",
|
||||
"Select a card" : "Select a card",
|
||||
"Select the card to link to a project" : "Select the card to link to a project",
|
||||
"Link to card" : "Link to card",
|
||||
"File already exists" : "File already exists",
|
||||
"A file with the name {filename} already exists." : "A file with the name {filename} already exists.",
|
||||
"Do you want to overwrite it?" : "Do you want to overwrite it?",
|
||||
"Overwrite file" : "Overwrite file",
|
||||
"Keep existing file" : "Keep existing file",
|
||||
"This board is read only" : "This board is read only",
|
||||
"Drop your files to upload" : "Drop your files to upload",
|
||||
"Add card" : "Add card",
|
||||
"Archived cards" : "Archived cards",
|
||||
"Add list" : "Add list",
|
||||
"List name" : "List name",
|
||||
"Active filters" : "Active filters",
|
||||
"Apply filter" : "Apply filter",
|
||||
"Filter by tag" : "Filter by tag",
|
||||
"Filter by assigned user" : "Filter by assigned user",
|
||||
"Unassigned" : "Unassigned",
|
||||
"Filter by due date" : "Filter by due date",
|
||||
"Overdue" : "Overdue",
|
||||
"Next 24 hours" : "Next 24 hours",
|
||||
"Next 7 days" : "Next 7 days",
|
||||
"Next 30 days" : "Next 30 days",
|
||||
"No due date" : "No due date",
|
||||
"Clear filter" : "Clear filter",
|
||||
"Hide archived cards" : "Hide archived cards",
|
||||
"Show archived cards" : "Show archived cards",
|
||||
"Toggle compact mode" : "Toggle compact mode",
|
||||
"Open details" : "Open details",
|
||||
"Details" : "Details",
|
||||
"Loading board" : "Loading board",
|
||||
"No lists available" : "No lists available",
|
||||
"Create a new list to add cards to this board" : "Create a new list to add cards to this board",
|
||||
"Board not found" : "Board not found",
|
||||
"Sharing" : "Sharing",
|
||||
"Tags" : "Tags",
|
||||
"Deleted items" : "Deleted items",
|
||||
"Timeline" : "Timeline",
|
||||
"Deleted lists" : "Deleted lists",
|
||||
"Undo" : "Undo",
|
||||
"Deleted cards" : "Deleted cards",
|
||||
"Share board with a user, group or circle …" : "Share board with a user, group or circle …",
|
||||
"Searching for users, groups and circles …" : "Searching for users, groups and circles …",
|
||||
"No participants found" : "No participants found",
|
||||
"Board owner" : "Board owner",
|
||||
"(Group)" : "(Group)",
|
||||
"(Circle)" : "(Circle)",
|
||||
"Can edit" : "Can edit",
|
||||
"Can share" : "Can share",
|
||||
"Can manage" : "Can manage",
|
||||
"Owner" : "Owner",
|
||||
"Delete" : "Delete",
|
||||
"Failed to create share with {displayName}" : "Failed to create share with {displayName}",
|
||||
"Are you sure you want to transfer the board {title} to {user}?" : "Are you sure you want to transfer the board {title} to {user}?",
|
||||
"Transfer the board." : "Transfer the board.",
|
||||
"Transfer" : "Transfer",
|
||||
"The board has been transferred to {user}" : "The board has been transferred to {user}",
|
||||
"Failed to transfer the board to {user}" : "Failed to transfer the board to {user}",
|
||||
"Add a new list" : "Add a new list",
|
||||
"Archive all cards" : "Archive all cards",
|
||||
"Unarchive all cards" : "Unarchive all cards",
|
||||
"Delete list" : "Delete list",
|
||||
"Archive all cards in this list" : "Archive all cards in this list",
|
||||
"Unarchive all cards in this list" : "Unarchive all cards in this list",
|
||||
"Add a new card" : "Add a new card",
|
||||
"Card name" : "Card name",
|
||||
"List deleted" : "List deleted",
|
||||
"Edit" : "Edit",
|
||||
"Add a new tag" : "Add a new tag",
|
||||
"title and color value must be provided" : "title and colour value must be provided",
|
||||
"Board name" : "Board name",
|
||||
"Members" : "Members",
|
||||
"Upload new files" : "Upload new files",
|
||||
"Share from Files" : "Share from Files",
|
||||
"Pending share" : "Pending share",
|
||||
"Add this attachment" : "Add this attachment",
|
||||
"Show in Files" : "Show in Files",
|
||||
"Download" : "Download",
|
||||
"Remove attachment" : "Remove attachment",
|
||||
"Delete Attachment" : "Delete Attachment",
|
||||
"Restore Attachment" : "Restore Attachment",
|
||||
"File to share" : "File to share",
|
||||
"Invalid path selected" : "Invalid path selected",
|
||||
"Open in sidebar view" : "Open in sidebar view",
|
||||
"Open in bigger view" : "Open in bigger view",
|
||||
"Attachments" : "Attachments",
|
||||
"Comments" : "Comments",
|
||||
"Modified" : "Modified",
|
||||
"Created" : "Created",
|
||||
"The title cannot be empty." : "The title cannot be empty.",
|
||||
"No comments yet. Begin the discussion!" : "No comments yet. Begin the discussion!",
|
||||
"Failed to load comments" : "Failed to load comments",
|
||||
"Assign a tag to this card…" : "Assign a tag to this card…",
|
||||
"Assign to users" : "Assign to users",
|
||||
"Assign to users/groups/circles" : "Assign to users/groups/circles",
|
||||
"Assign a user to this card…" : "Assign a user to this card…",
|
||||
"Due date" : "Due date",
|
||||
"Set a due date" : "Set a due date",
|
||||
"Remove due date" : "Remove due date",
|
||||
"Select Date" : "Select Date",
|
||||
"Today" : "Today",
|
||||
"Tomorrow" : "Tomorrow",
|
||||
"Next week" : "Next week",
|
||||
"Next month" : "Next month",
|
||||
"Save" : "Save",
|
||||
"The comment cannot be empty." : "The comment cannot be empty.",
|
||||
"The comment cannot be longer than 1000 characters." : "The comment cannot be longer than 1000 characters.",
|
||||
"In reply to" : "In reply to",
|
||||
"Cancel reply" : "Cancel reply",
|
||||
"Reply" : "Reply",
|
||||
"Update" : "Update",
|
||||
"Description" : "Description",
|
||||
"(Unsaved)" : "(Unsaved)",
|
||||
"(Saving…)" : "(Saving…)",
|
||||
"Formatting help" : "Formatting help",
|
||||
"Edit description" : "Edit description",
|
||||
"View description" : "View description",
|
||||
"Add Attachment" : "Add Attachment",
|
||||
"Write a description …" : "Write a description …",
|
||||
"Choose attachment" : "Choose attachment",
|
||||
"(group)" : "(group)",
|
||||
"Todo items" : "Todo items",
|
||||
"{count} comments, {unread} unread" : "{count} comments, {unread} unread",
|
||||
"Edit card title" : "Edit card title",
|
||||
"Assign to me" : "Assign to me",
|
||||
"Unassign myself" : "Unassign myself",
|
||||
"Move card" : "Move card",
|
||||
"Unarchive card" : "Unarchive card",
|
||||
"Archive card" : "Archive card",
|
||||
"Delete card" : "Delete card",
|
||||
"Move card to another board" : "Move card to another board",
|
||||
"List is empty" : "List is empty",
|
||||
"Card deleted" : "Card deleted",
|
||||
"seconds ago" : "seconds ago",
|
||||
"All boards" : "All boards",
|
||||
"Archived boards" : "Archived boards",
|
||||
"Shared with you" : "Shared with you",
|
||||
"Deck settings" : "Deck settings",
|
||||
"Use bigger card view" : "Use bigger card view",
|
||||
"Show card ID badge" : "Show card ID badge",
|
||||
"Show boards in calendar/tasks" : "Show boards in calendar/tasks",
|
||||
"Limit deck usage of groups" : "Limit deck usage of groups",
|
||||
"Limiting Deck will block users not part of those groups from creating their own boards. Users will still be able to work on boards that have been shared with them." : "Limiting Deck will block users not part of those groups from creating their own boards. Users will still be able to work on boards that have been shared with them.",
|
||||
"Board details" : "Board details",
|
||||
"Edit board" : "Edit board",
|
||||
"Clone board" : "Clone board",
|
||||
"Unarchive board" : "Unarchive board",
|
||||
"Archive board" : "Archive board",
|
||||
"Turn on due date reminders" : "Turn on due date reminders",
|
||||
"Turn off due date reminders" : "Turn off due date reminders",
|
||||
"Due date reminders" : "Due date reminders",
|
||||
"All cards" : "All cards",
|
||||
"Assigned cards" : "Assigned cards",
|
||||
"No notifications" : "No notifications",
|
||||
"Delete board" : "Delete board",
|
||||
"Board {0} deleted" : "Board {0} deleted",
|
||||
"Only assigned cards" : "Only assigned cards",
|
||||
"No reminder" : "No reminder",
|
||||
"An error occurred" : "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." : "Are you sure you want to delete the board {title}? This will delete all the data of this board including archived cards.",
|
||||
"Delete the board?" : "Delete the board?",
|
||||
"Loading filtered view" : "Loading filtered view",
|
||||
"No due" : "No due",
|
||||
"Search for {searchQuery} in all boards" : "Search for {searchQuery} in all boards",
|
||||
"No results found" : "No results found",
|
||||
"{stack} in {board}" : "{stack} in {board}",
|
||||
"Click to expand description" : "Click to expand description",
|
||||
"* Created on {created}\n* Last modified on {lastMod}\n* {nbAttachments} attachments\n* {nbComments} comments" : "* Created on {created}\n* Last modified on {lastMod}\n* {nbAttachments} attachments\n* {nbComments} comments",
|
||||
"{nbCards} cards" : "{nbCards} cards",
|
||||
"No upcoming cards" : "No upcoming cards",
|
||||
"upcoming cards" : "upcoming cards",
|
||||
"Due on {date}" : "Due on {date}",
|
||||
"Link to a board" : "Link to a board",
|
||||
"Link to a card" : "Link to a card",
|
||||
"Create a card" : "Create a card",
|
||||
"Message from {author} in {conversationName}" : "Message from {author} in {conversationName}",
|
||||
"Something went wrong" : "Something went wrong",
|
||||
"Failed to upload {name}" : "Failed to upload {name}",
|
||||
"Maximum file size of {size} exceeded" : "Maximum file size of {size} exceeded",
|
||||
"Error creating the share" : "Error creating the share",
|
||||
"Share with a Deck card" : "Share with a Deck card",
|
||||
"Share {file} with a Deck card" : "Share {file} with a Deck card",
|
||||
"Share" : "Share",
|
||||
"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 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",
|
||||
"Are you sure you want to transfer the board {title} for {user} ?" : "Are you sure you want to transfer the board {title} for {user} ?",
|
||||
"Transfer the board for {user} successfully" : "Transfer the board for {user} successfully",
|
||||
"Failed to transfer the board for {user}" : "Failed to transfer the board for {user}",
|
||||
"Are you sure you want to delete the board {title}? This will delete all the data of this board." : "Are you sure you want to delete the board {title}? This will delete all the data of this board.",
|
||||
"This week" : "This week",
|
||||
"Are you sure you want to transfer the board {title} for {user}?" : "Are you sure you want to transfer the board {title} for {user}?"
|
||||
"This week" : "This week"
|
||||
},"pluralForm" :"nplurals=2; plural=(n != 1);"
|
||||
}
|
||||
@@ -18,7 +18,6 @@ OC.L10N.register(
|
||||
"Details" : "Üksikasjad",
|
||||
"Sharing" : "Jagamine",
|
||||
"Tags" : "Sildid",
|
||||
"Undo" : "Tühista",
|
||||
"Can edit" : "Võib redigeerida",
|
||||
"Can share" : "Can share",
|
||||
"Owner" : "Omanik",
|
||||
@@ -43,7 +42,6 @@ OC.L10N.register(
|
||||
"Shared with you" : "Sinuga jagatud",
|
||||
"No notifications" : "Märguandeid pole",
|
||||
"An error occurred" : "Tekkis tõrge",
|
||||
"Share" : "Jaga",
|
||||
"This week" : "Käesolev nädal"
|
||||
"Share" : "Jaga"
|
||||
},
|
||||
"nplurals=2; plural=(n != 1);");
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
"Details" : "Üksikasjad",
|
||||
"Sharing" : "Jagamine",
|
||||
"Tags" : "Sildid",
|
||||
"Undo" : "Tühista",
|
||||
"Can edit" : "Võib redigeerida",
|
||||
"Can share" : "Can share",
|
||||
"Owner" : "Omanik",
|
||||
@@ -41,7 +40,6 @@
|
||||
"Shared with you" : "Sinuga jagatud",
|
||||
"No notifications" : "Märguandeid pole",
|
||||
"An error occurred" : "Tekkis tõrge",
|
||||
"Share" : "Jaga",
|
||||
"This week" : "Käesolev nädal"
|
||||
"Share" : "Jaga"
|
||||
},"pluralForm" :"nplurals=2; plural=(n != 1);"
|
||||
}
|
||||
@@ -131,7 +131,7 @@ OC.L10N.register(
|
||||
"Overwrite file" : "Remplacer le fichier",
|
||||
"Keep existing file" : "Conserver le fichier existant",
|
||||
"This board is read only" : "Ce tableau est en lecture seule",
|
||||
"Drop your files to upload" : "Glissez vos fichiers pour les téléverser",
|
||||
"Drop your files to upload" : "Glissez vos fichiers pour les envoyer",
|
||||
"Add card" : "Ajouter une carte",
|
||||
"Archived cards" : "Cartes archivées",
|
||||
"Add list" : "Ajouter une liste",
|
||||
@@ -183,10 +183,8 @@ OC.L10N.register(
|
||||
"Failed to transfer the board to {user}" : "Échec du transfert du tableau à {user}",
|
||||
"Add a new list" : "Ajouter une nouvelle liste",
|
||||
"Archive all cards" : "Archiver toutes les cartes",
|
||||
"Unarchive all cards" : "Désarchiver toutes les cartes",
|
||||
"Delete list" : "Supprimer la liste",
|
||||
"Archive all cards in this list" : "Archiver toutes les cartes de cette liste",
|
||||
"Unarchive all cards in this list" : "Désarchiver toutes les cartes de cette liste",
|
||||
"Add a new card" : "Ajouter une nouvelle carte",
|
||||
"Card name" : "Nom de la carte",
|
||||
"List deleted" : "Liste supprimée",
|
||||
|
||||
@@ -129,7 +129,7 @@
|
||||
"Overwrite file" : "Remplacer le fichier",
|
||||
"Keep existing file" : "Conserver le fichier existant",
|
||||
"This board is read only" : "Ce tableau est en lecture seule",
|
||||
"Drop your files to upload" : "Glissez vos fichiers pour les téléverser",
|
||||
"Drop your files to upload" : "Glissez vos fichiers pour les envoyer",
|
||||
"Add card" : "Ajouter une carte",
|
||||
"Archived cards" : "Cartes archivées",
|
||||
"Add list" : "Ajouter une liste",
|
||||
@@ -181,10 +181,8 @@
|
||||
"Failed to transfer the board to {user}" : "Échec du transfert du tableau à {user}",
|
||||
"Add a new list" : "Ajouter une nouvelle liste",
|
||||
"Archive all cards" : "Archiver toutes les cartes",
|
||||
"Unarchive all cards" : "Désarchiver toutes les cartes",
|
||||
"Delete list" : "Supprimer la liste",
|
||||
"Archive all cards in this list" : "Archiver toutes les cartes de cette liste",
|
||||
"Unarchive all cards in this list" : "Désarchiver toutes les cartes de cette liste",
|
||||
"Add a new card" : "Ajouter une nouvelle carte",
|
||||
"Card name" : "Nom de la carte",
|
||||
"List deleted" : "Liste supprimée",
|
||||
|
||||
@@ -183,10 +183,8 @@ OC.L10N.register(
|
||||
"Failed to transfer the board to {user}" : "A tábla átadása {user} számára sikertelen",
|
||||
"Add a new list" : "Új lista hozzáadása",
|
||||
"Archive all cards" : "Az összes kártya archiválása",
|
||||
"Unarchive all cards" : "Az összes kártya archiválásának visszavonása",
|
||||
"Delete list" : "Lista törlése",
|
||||
"Archive all cards in this list" : "Az összes kártya archiválása ebben a listában",
|
||||
"Unarchive all cards in this list" : "Az összes kártya archiválásának visszavonása ebben a listában",
|
||||
"Add a new card" : "Új kártya hozzáadása",
|
||||
"Card name" : "Kártya neve",
|
||||
"List deleted" : "Lista törölve",
|
||||
@@ -262,7 +260,6 @@ OC.L10N.register(
|
||||
"Shared with you" : "Megosztva Önnel",
|
||||
"Deck settings" : "Kártyák beállításai",
|
||||
"Use bigger card view" : "Nagyobb kártyanézet használata",
|
||||
"Show card ID badge" : "Kártyaazonosító jelvény megjelenítése",
|
||||
"Show boards in calendar/tasks" : "Táblák megjelenítése a naptárak/teendők között",
|
||||
"Limit deck usage of groups" : "A kártyák használatának csoportokra korlátozása",
|
||||
"Limiting Deck will block users not part of those groups from creating their own boards. Users will still be able to work on boards that have been shared with them." : "A Kártyák korlátozása blokkolja a saját táblák létrehozását azoknál a felhasználóknál, akik nem tagjai a megadott csoportoknak. A felhasználók továbbra is tudnak dolgozni a velük megosztott táblákon.",
|
||||
@@ -289,7 +286,6 @@ OC.L10N.register(
|
||||
"Search for {searchQuery} in all boards" : "Keresés a(z) {searchQuery} kifejezésre az összes táblában",
|
||||
"No results found" : "Nincs találat",
|
||||
"{stack} in {board}" : "{stack} itt: {board}",
|
||||
"Click to expand description" : "Kattintson a leírás kibontásához",
|
||||
"* Created on {created}\n* Last modified on {lastMod}\n* {nbAttachments} attachments\n* {nbComments} comments" : "* Létrehozva: {created}\n* Utoljára módosítva: {lastMod}\n* {nbAttachments} melléklet\n* {nbComments} megjegyzés",
|
||||
"{nbCards} cards" : "{nbCards} kártya",
|
||||
"No upcoming cards" : "Nincsenek közelgő kártyák",
|
||||
|
||||
@@ -181,10 +181,8 @@
|
||||
"Failed to transfer the board to {user}" : "A tábla átadása {user} számára sikertelen",
|
||||
"Add a new list" : "Új lista hozzáadása",
|
||||
"Archive all cards" : "Az összes kártya archiválása",
|
||||
"Unarchive all cards" : "Az összes kártya archiválásának visszavonása",
|
||||
"Delete list" : "Lista törlése",
|
||||
"Archive all cards in this list" : "Az összes kártya archiválása ebben a listában",
|
||||
"Unarchive all cards in this list" : "Az összes kártya archiválásának visszavonása ebben a listában",
|
||||
"Add a new card" : "Új kártya hozzáadása",
|
||||
"Card name" : "Kártya neve",
|
||||
"List deleted" : "Lista törölve",
|
||||
@@ -260,7 +258,6 @@
|
||||
"Shared with you" : "Megosztva Önnel",
|
||||
"Deck settings" : "Kártyák beállításai",
|
||||
"Use bigger card view" : "Nagyobb kártyanézet használata",
|
||||
"Show card ID badge" : "Kártyaazonosító jelvény megjelenítése",
|
||||
"Show boards in calendar/tasks" : "Táblák megjelenítése a naptárak/teendők között",
|
||||
"Limit deck usage of groups" : "A kártyák használatának csoportokra korlátozása",
|
||||
"Limiting Deck will block users not part of those groups from creating their own boards. Users will still be able to work on boards that have been shared with them." : "A Kártyák korlátozása blokkolja a saját táblák létrehozását azoknál a felhasználóknál, akik nem tagjai a megadott csoportoknak. A felhasználók továbbra is tudnak dolgozni a velük megosztott táblákon.",
|
||||
@@ -287,7 +284,6 @@
|
||||
"Search for {searchQuery} in all boards" : "Keresés a(z) {searchQuery} kifejezésre az összes táblában",
|
||||
"No results found" : "Nincs találat",
|
||||
"{stack} in {board}" : "{stack} itt: {board}",
|
||||
"Click to expand description" : "Kattintson a leírás kibontásához",
|
||||
"* Created on {created}\n* Last modified on {lastMod}\n* {nbAttachments} attachments\n* {nbComments} comments" : "* Létrehozva: {created}\n* Utoljára módosítva: {lastMod}\n* {nbAttachments} melléklet\n* {nbComments} megjegyzés",
|
||||
"{nbCards} cards" : "{nbCards} kártya",
|
||||
"No upcoming cards" : "Nincsenek közelgő kártyák",
|
||||
|
||||
@@ -71,14 +71,14 @@ OC.L10N.register(
|
||||
"Load more" : "Carregar mais",
|
||||
"Personal" : "Pessoal",
|
||||
"The card \"%s\" on \"%s\" has been assigned to you by %s." : "O cartão \"%s\" em \"%s\" foi vinculado com você por %s.",
|
||||
"{user} has assigned the card {deck-card} on {deck-board} to you." : "{user} atribuiu o cartão {deck-card} no {deck-board} a você.",
|
||||
"{user} has assigned the card {deck-card} on {deck-board} to you." : "{usuário} atribuiu a carta {deck-card} no {deck-board} para você.",
|
||||
"The card \"%s\" on \"%s\" has reached its due date." : "O cartão \"%s\" em \"%s\" atingiu sua data de vencimento.",
|
||||
"The card {deck-card} on {deck-board} has reached its due date." : "O cartão {deck-card} em {deck-board} atingiu sua data de vencimento.",
|
||||
"The card {deck-card} on {deck-board} has reached its due date." : "A carta {deck-card} em {deck-board} atingiu sua data de vencimento.",
|
||||
"%s has mentioned you in a comment on \"%s\"." : "%s citou você num comentário em \"%s\".",
|
||||
"{user} has mentioned you in a comment on {deck-card}." : "{user} mencionou você em um comentário em {deck-card}.",
|
||||
"The board \"%s\" has been shared with you by %s." : "O painel \"%s\" foi compartilhado com você por %s.",
|
||||
"{user} has shared {deck-board} with you." : "{user} compartilhou o {deck-board} com você.",
|
||||
"Card comments" : "Comentários do cartão",
|
||||
"{user} has shared {deck-board} with you." : "{user} compartilhou {deck-board} com você.",
|
||||
"Card comments" : "Comentários nos Cards",
|
||||
"%s on %s" : "%s em %s",
|
||||
"No data was provided to create an attachment." : "Nenhum dado foi fornecido para criar um anexo.",
|
||||
"Finished" : "Terminado",
|
||||
@@ -101,12 +101,12 @@ OC.L10N.register(
|
||||
"Could not write file to disk" : "Não foi possível escrever no disco",
|
||||
"A PHP extension stopped the file upload" : "Uma extensão PHP parou o envio do arquivo",
|
||||
"No file uploaded or file size exceeds maximum of %s" : "Nenhum arquivo enviado ou o tamanho excede o máximo de %s",
|
||||
"This comment has more than %s characters.\nAdded as an attachment to the card with name %s.\nAccessible on URL: %s." : "Este comentário tem mais de %s caracteres.\nEle foi adicionado como um anexo ao cartão de nome %s.\nAcessível na URL: %s.",
|
||||
"This comment has more than %s characters.\nAdded as an attachment to the card with name %s.\nAccessible on URL: %s." : "Este comentário tem mais de %s caracteres.\nAdicionado como um anexo ao cartão com o nome %s.\nAcessível no URL: %s.",
|
||||
"Card not found" : "Cartão não encontrado",
|
||||
"Path is already shared with this card" : "O caminho já é compartilhado com este cartão",
|
||||
"Invalid date, date format must be YYYY-MM-DD" : "Data inválida, o formato da data deve ser AAAA-MM-DD",
|
||||
"Personal planning and team project organization" : "Planejamento pessoal e organização de projetos em equipe",
|
||||
"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" : "O Deck é uma ferramenta de organização ao estilo kanban voltada para o planejamento pessoal e para a organização de projetos para equipes, integrada ao Nextcloud.\n\n\n- 📥Adicione suas tarefas aos cartões e coloque-os em ordem\n- 📄 Escreva notas adicionais formatadas em Markdown \n- 🔖 Atribua rótulos para uma organização ainda melhor\n- 👥 Compartilhe com sua equipe, seus amigos ou sua família\n- 📎 Anexe arquivos e incorpore-os à sua descrição em Markdown\n- 💬 Discuta com sua equipe usando comentários\n- ⚡ Acompanhe as alterações no fluxo de atividades \n- 🚀 Organize seu projeto ",
|
||||
"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 é uma ferramenta de organização do estilo kanban voltada para o planejamento pessoal e organização de projetos para equipes integradas ao Nextcloud.\n\n\n- 📥Adicione suas tarefas aos cartões e coloque-as em ordem\n- 📄 Escreva notas adicionais em Anotar \n- 🔖 Atribua rótulos para uma organização ainda melhor\n- 👥 Compartilhe com sua equipe, amigos ou família\n- 📎 Anexar arquivos e incorporá-los à descrição da Nota\n- 💬 Discuta com sua equipe usando comentários\n- ⚡ Acompanhe as mudanças no fluxo de atividades \n- 🚀 Organize seu projeto ",
|
||||
"Card details" : "Detalhes do cartão",
|
||||
"Add board" : "Adicionar painel",
|
||||
"Select the board to link to a project" : "Selecione o painel para vincular a um projeto",
|
||||
@@ -117,7 +117,7 @@ OC.L10N.register(
|
||||
"Select a list" : "Selecione uma lista",
|
||||
"Card title" : "Título do cartão",
|
||||
"Cancel" : "Cancelar",
|
||||
"Creating the new card …" : "Criando o novo cartão…",
|
||||
"Creating the new card …" : "Criando o novo cartão …",
|
||||
"Card \"{card}\" was added to \"{board}\"" : "O cartão \"{card}\" foi adicionado a \"{board}\" ",
|
||||
"Open card" : "Abrir o cartão",
|
||||
"Close" : "Fechar",
|
||||
@@ -150,7 +150,7 @@ OC.L10N.register(
|
||||
"Clear filter" : "Limpar filtro",
|
||||
"Hide archived cards" : "Ocultar cartões arquivados",
|
||||
"Show archived cards" : "Exibir cartões arquivados",
|
||||
"Toggle compact mode" : "Alternar modo compacto",
|
||||
"Toggle compact mode" : "Alternar para modo compacto",
|
||||
"Open details" : "Abrir detalhes",
|
||||
"Details" : "Detalhes",
|
||||
"Loading board" : "Carregando painel",
|
||||
@@ -176,17 +176,15 @@ OC.L10N.register(
|
||||
"Owner" : "Proprietário",
|
||||
"Delete" : "Excluir",
|
||||
"Failed to create share with {displayName}" : "Falha ao criar compartilhamento com {displayName}",
|
||||
"Are you sure you want to transfer the board {title} to {user}?" : "Deseja realmente transferir o painel {title} para {user}?",
|
||||
"Transfer the board." : "Transferir o painel.",
|
||||
"Are you sure you want to transfer the board {title} to {user}?" : "Tem certeza de que deseja transferir o quadro {title} para {user}?",
|
||||
"Transfer the board." : "Transfira a reunião.",
|
||||
"Transfer" : "Transferir",
|
||||
"The board has been transferred to {user}" : "A painel foi transferida para {user}",
|
||||
"Failed to transfer the board to {user}" : "Não foi possível transferir o painel para {user}",
|
||||
"The board has been transferred to {user}" : "A quadro foi transferida para {user}",
|
||||
"Failed to transfer the board to {user}" : "Falha ao transferir o quadro para {user}",
|
||||
"Add a new list" : "Adicionar nova lista",
|
||||
"Archive all cards" : "Arquivar todos os cartões",
|
||||
"Unarchive all cards" : "Desarquivar todos os cartões",
|
||||
"Delete list" : "Excluir lista",
|
||||
"Archive all cards in this list" : "Arquivar todos os cartões desta lista",
|
||||
"Unarchive all cards in this list" : "Desarquivar todos os cartões desta lista",
|
||||
"Add a new card" : "Adicionar um novo cartão",
|
||||
"Card name" : "Nome do cartão",
|
||||
"List deleted" : "Lista excluída",
|
||||
@@ -199,7 +197,7 @@ OC.L10N.register(
|
||||
"Share from Files" : "Compartilhar de Arquivos",
|
||||
"Pending share" : "Compartilhamento pendente",
|
||||
"Add this attachment" : "Adicionar este anexo",
|
||||
"Show in Files" : "Exibir em Arquivos",
|
||||
"Show in Files" : "Mostrar em Arquivos",
|
||||
"Download" : "Baixar",
|
||||
"Remove attachment" : "Remover anexo",
|
||||
"Delete Attachment" : "Excluir Anexo",
|
||||
@@ -214,13 +212,13 @@ OC.L10N.register(
|
||||
"Created" : "Criado",
|
||||
"The title cannot be empty." : "O título não pode ficar em branco.",
|
||||
"No comments yet. Begin the discussion!" : "Nenhum comentário ainda. Inicie a conversa!",
|
||||
"Failed to load comments" : "Não foi possível carregar os comentários",
|
||||
"Failed to load comments" : "Falha ao carregar comentários",
|
||||
"Assign a tag to this card…" : "Atribuir uma etiqueta a este cartão...",
|
||||
"Assign to users" : "Atribuir a usuários",
|
||||
"Assign to users/groups/circles" : "Atribuir a usuários/grupos/círculos",
|
||||
"Assign a user to this card…" : "Atribuir um usuário a este cartão...",
|
||||
"Due date" : "Data de vencimento",
|
||||
"Set a due date" : "Definir uma data de vencimento",
|
||||
"Set a due date" : "Definir uma data de finalização",
|
||||
"Remove due date" : "Remover data de vencimento",
|
||||
"Select Date" : "Selecionar Data",
|
||||
"Today" : "Hoje",
|
||||
@@ -244,7 +242,7 @@ OC.L10N.register(
|
||||
"Write a description …" : "Escreva uma descrição...",
|
||||
"Choose attachment" : "Escolher anexo",
|
||||
"(group)" : "(grupo)",
|
||||
"Todo items" : "Itens a fazer",
|
||||
"Todo items" : "Itens para fazer",
|
||||
"{count} comments, {unread} unread" : "{count} comentários, {unread} não lidos",
|
||||
"Edit card title" : "Editar título do cartão",
|
||||
"Assign to me" : "Atribuir a mim",
|
||||
@@ -254,7 +252,7 @@ OC.L10N.register(
|
||||
"Archive card" : "Arquivar cartão",
|
||||
"Delete card" : "Excluir cartão",
|
||||
"Move card to another board" : "Mover o cartão para outro painel",
|
||||
"List is empty" : "A lista está vazia",
|
||||
"List is empty" : "A Lista está vazia",
|
||||
"Card deleted" : "Cartão excluído",
|
||||
"seconds ago" : "segundos atrás",
|
||||
"All boards" : "Todos os painéis",
|
||||
@@ -262,8 +260,7 @@ OC.L10N.register(
|
||||
"Shared with you" : "Compartilhado com você",
|
||||
"Deck settings" : "Configurações do Deck",
|
||||
"Use bigger card view" : "Use uma exibição de cartão maior",
|
||||
"Show card ID badge" : "Exibir o distintivo de identificação do cartão",
|
||||
"Show boards in calendar/tasks" : "Exibir os painéis em calendários/tarefas",
|
||||
"Show boards in calendar/tasks" : "Mostrar painéis em calendários/tarefas",
|
||||
"Limit deck usage of groups" : "Limitar o uso de grupos no deck",
|
||||
"Limiting Deck will block users not part of those groups from creating their own boards. Users will still be able to work on boards that have been shared with them." : "Limitar o Deck impedirá que usuários que não fazem parte desses grupos criem seus próprios painéis. Os usuários ainda poderão trabalhar em pastas que foram compartilhadas com eles.",
|
||||
"Board details" : "Detalhes do painel",
|
||||
@@ -282,20 +279,20 @@ OC.L10N.register(
|
||||
"Only assigned cards" : "Apenas cartões atribuídos",
|
||||
"No reminder" : "Nenhum lembrete",
|
||||
"An error occurred" : "Ocorreu um erro",
|
||||
"Are you sure you want to delete the board {title}? This will delete all the data of this board including archived cards." : "Deseja realmente excluir o painel {title}? Isso excluirá todos os dados deste painel, inclusive os cartões arquivados.",
|
||||
"Are you sure you want to delete the board {title}? This will delete all the data of this board including archived cards." : "Tem certeza de que deseja excluir o quadro {title}? Isso excluirá todos os dados deste quadro, incluindo cartões arquivados.",
|
||||
"Delete the board?" : "Excluir o painel?",
|
||||
"Loading filtered view" : "Carregando exibição filtrada",
|
||||
"No due" : "Sem vencimento",
|
||||
"Search for {searchQuery} in all boards" : "Pesquisar por {searchQuery} em todos os painéis",
|
||||
"No results found" : "Nenhum resultado encontrado",
|
||||
"{stack} in {board}" : "{stack} em {board}",
|
||||
"{stack} in {board}" : "{stack} de {board}",
|
||||
"Click to expand description" : "Clique para expandir a descrição",
|
||||
"* Created on {created}\n* Last modified on {lastMod}\n* {nbAttachments} attachments\n* {nbComments} comments" : "* Criado em {created}\n* Última modificação em {lastMod}\n* {nbAttachments} anexos\n* {nbComments} comentários",
|
||||
"{nbCards} cards" : "{nbCards} cartões",
|
||||
"No upcoming cards" : "Não há mais cartões",
|
||||
"upcoming cards" : "próximos cartões",
|
||||
"Due on {date}" : "Vencimento em {date}",
|
||||
"Link to a board" : "Vincular a um painel",
|
||||
"Link to a board" : "Linkar a um painel",
|
||||
"Link to a card" : "Vincular a um cartão",
|
||||
"Create a card" : "Criar um cartão",
|
||||
"Message from {author} in {conversationName}" : "Mensagem de {author} em {conversationName}",
|
||||
@@ -307,11 +304,11 @@ OC.L10N.register(
|
||||
"Share {file} with a Deck card" : "Compartilhar {file} com um cartão Deck",
|
||||
"Share" : "Compartilhar",
|
||||
"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 é uma ferramenta de organização de estilo kanban destinada ao planejamento pessoal e organização para equipes integradas com o Nextcloud.\n\n\n- 📥 Adicione suas tarefas aos cartões e coloque-os em ordem\n- 📄 Insira notas adicionais em markdown\n- 🔖 Atribua etiquetas para melhorar a organização\n- 👥 Compartilhe com sua equipe, amigos ou familiares\n- 📎 Anexe arquivos e incorpore-os em sua descrição no markdown\n- 💬 Discuta com sua equipe usando os comentários\n- ⚡ Acompanhe as alterações no fluxo de atividades\n- 🚀 Mantenha seu projeto organizado",
|
||||
"Are you sure you want to transfer the board {title} for {user} ?" : "Deseja realmente transferir o painel {title} para {user}?",
|
||||
"Transfer the board for {user} successfully" : "O painel foi transferido para {user} com sucesso",
|
||||
"Failed to transfer the board for {user}" : "Não foi possível transferir o painel para {user}",
|
||||
"Are you sure you want to transfer the board {title} for {user} ?" : "Tem certeza de que deseja transferir o quadro {title} para {user}?",
|
||||
"Transfer the board for {user} successfully" : "Transferida a reunião para {user} com sucesso",
|
||||
"Failed to transfer the board for {user}" : "Falha ao transferir a reunião para {user}",
|
||||
"Are you sure you want to delete the board {title}? This will delete all the data of this board." : "Deseja realmente excluir o painel {title}? Isto excluirá todos os dados deste painel.",
|
||||
"This week" : "Esta semana",
|
||||
"Are you sure you want to transfer the board {title} for {user}?" : "Deseja realmente transferir o painel {title} para {user}?"
|
||||
"Are you sure you want to transfer the board {title} for {user}?" : "Tem certeza de que deseja transferir o quadro {title} para {user}?"
|
||||
},
|
||||
"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
|
||||
|
||||
@@ -69,14 +69,14 @@
|
||||
"Load more" : "Carregar mais",
|
||||
"Personal" : "Pessoal",
|
||||
"The card \"%s\" on \"%s\" has been assigned to you by %s." : "O cartão \"%s\" em \"%s\" foi vinculado com você por %s.",
|
||||
"{user} has assigned the card {deck-card} on {deck-board} to you." : "{user} atribuiu o cartão {deck-card} no {deck-board} a você.",
|
||||
"{user} has assigned the card {deck-card} on {deck-board} to you." : "{usuário} atribuiu a carta {deck-card} no {deck-board} para você.",
|
||||
"The card \"%s\" on \"%s\" has reached its due date." : "O cartão \"%s\" em \"%s\" atingiu sua data de vencimento.",
|
||||
"The card {deck-card} on {deck-board} has reached its due date." : "O cartão {deck-card} em {deck-board} atingiu sua data de vencimento.",
|
||||
"The card {deck-card} on {deck-board} has reached its due date." : "A carta {deck-card} em {deck-board} atingiu sua data de vencimento.",
|
||||
"%s has mentioned you in a comment on \"%s\"." : "%s citou você num comentário em \"%s\".",
|
||||
"{user} has mentioned you in a comment on {deck-card}." : "{user} mencionou você em um comentário em {deck-card}.",
|
||||
"The board \"%s\" has been shared with you by %s." : "O painel \"%s\" foi compartilhado com você por %s.",
|
||||
"{user} has shared {deck-board} with you." : "{user} compartilhou o {deck-board} com você.",
|
||||
"Card comments" : "Comentários do cartão",
|
||||
"{user} has shared {deck-board} with you." : "{user} compartilhou {deck-board} com você.",
|
||||
"Card comments" : "Comentários nos Cards",
|
||||
"%s on %s" : "%s em %s",
|
||||
"No data was provided to create an attachment." : "Nenhum dado foi fornecido para criar um anexo.",
|
||||
"Finished" : "Terminado",
|
||||
@@ -99,12 +99,12 @@
|
||||
"Could not write file to disk" : "Não foi possível escrever no disco",
|
||||
"A PHP extension stopped the file upload" : "Uma extensão PHP parou o envio do arquivo",
|
||||
"No file uploaded or file size exceeds maximum of %s" : "Nenhum arquivo enviado ou o tamanho excede o máximo de %s",
|
||||
"This comment has more than %s characters.\nAdded as an attachment to the card with name %s.\nAccessible on URL: %s." : "Este comentário tem mais de %s caracteres.\nEle foi adicionado como um anexo ao cartão de nome %s.\nAcessível na URL: %s.",
|
||||
"This comment has more than %s characters.\nAdded as an attachment to the card with name %s.\nAccessible on URL: %s." : "Este comentário tem mais de %s caracteres.\nAdicionado como um anexo ao cartão com o nome %s.\nAcessível no URL: %s.",
|
||||
"Card not found" : "Cartão não encontrado",
|
||||
"Path is already shared with this card" : "O caminho já é compartilhado com este cartão",
|
||||
"Invalid date, date format must be YYYY-MM-DD" : "Data inválida, o formato da data deve ser AAAA-MM-DD",
|
||||
"Personal planning and team project organization" : "Planejamento pessoal e organização de projetos em equipe",
|
||||
"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" : "O Deck é uma ferramenta de organização ao estilo kanban voltada para o planejamento pessoal e para a organização de projetos para equipes, integrada ao Nextcloud.\n\n\n- 📥Adicione suas tarefas aos cartões e coloque-os em ordem\n- 📄 Escreva notas adicionais formatadas em Markdown \n- 🔖 Atribua rótulos para uma organização ainda melhor\n- 👥 Compartilhe com sua equipe, seus amigos ou sua família\n- 📎 Anexe arquivos e incorpore-os à sua descrição em Markdown\n- 💬 Discuta com sua equipe usando comentários\n- ⚡ Acompanhe as alterações no fluxo de atividades \n- 🚀 Organize seu projeto ",
|
||||
"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 é uma ferramenta de organização do estilo kanban voltada para o planejamento pessoal e organização de projetos para equipes integradas ao Nextcloud.\n\n\n- 📥Adicione suas tarefas aos cartões e coloque-as em ordem\n- 📄 Escreva notas adicionais em Anotar \n- 🔖 Atribua rótulos para uma organização ainda melhor\n- 👥 Compartilhe com sua equipe, amigos ou família\n- 📎 Anexar arquivos e incorporá-los à descrição da Nota\n- 💬 Discuta com sua equipe usando comentários\n- ⚡ Acompanhe as mudanças no fluxo de atividades \n- 🚀 Organize seu projeto ",
|
||||
"Card details" : "Detalhes do cartão",
|
||||
"Add board" : "Adicionar painel",
|
||||
"Select the board to link to a project" : "Selecione o painel para vincular a um projeto",
|
||||
@@ -115,7 +115,7 @@
|
||||
"Select a list" : "Selecione uma lista",
|
||||
"Card title" : "Título do cartão",
|
||||
"Cancel" : "Cancelar",
|
||||
"Creating the new card …" : "Criando o novo cartão…",
|
||||
"Creating the new card …" : "Criando o novo cartão …",
|
||||
"Card \"{card}\" was added to \"{board}\"" : "O cartão \"{card}\" foi adicionado a \"{board}\" ",
|
||||
"Open card" : "Abrir o cartão",
|
||||
"Close" : "Fechar",
|
||||
@@ -148,7 +148,7 @@
|
||||
"Clear filter" : "Limpar filtro",
|
||||
"Hide archived cards" : "Ocultar cartões arquivados",
|
||||
"Show archived cards" : "Exibir cartões arquivados",
|
||||
"Toggle compact mode" : "Alternar modo compacto",
|
||||
"Toggle compact mode" : "Alternar para modo compacto",
|
||||
"Open details" : "Abrir detalhes",
|
||||
"Details" : "Detalhes",
|
||||
"Loading board" : "Carregando painel",
|
||||
@@ -174,17 +174,15 @@
|
||||
"Owner" : "Proprietário",
|
||||
"Delete" : "Excluir",
|
||||
"Failed to create share with {displayName}" : "Falha ao criar compartilhamento com {displayName}",
|
||||
"Are you sure you want to transfer the board {title} to {user}?" : "Deseja realmente transferir o painel {title} para {user}?",
|
||||
"Transfer the board." : "Transferir o painel.",
|
||||
"Are you sure you want to transfer the board {title} to {user}?" : "Tem certeza de que deseja transferir o quadro {title} para {user}?",
|
||||
"Transfer the board." : "Transfira a reunião.",
|
||||
"Transfer" : "Transferir",
|
||||
"The board has been transferred to {user}" : "A painel foi transferida para {user}",
|
||||
"Failed to transfer the board to {user}" : "Não foi possível transferir o painel para {user}",
|
||||
"The board has been transferred to {user}" : "A quadro foi transferida para {user}",
|
||||
"Failed to transfer the board to {user}" : "Falha ao transferir o quadro para {user}",
|
||||
"Add a new list" : "Adicionar nova lista",
|
||||
"Archive all cards" : "Arquivar todos os cartões",
|
||||
"Unarchive all cards" : "Desarquivar todos os cartões",
|
||||
"Delete list" : "Excluir lista",
|
||||
"Archive all cards in this list" : "Arquivar todos os cartões desta lista",
|
||||
"Unarchive all cards in this list" : "Desarquivar todos os cartões desta lista",
|
||||
"Add a new card" : "Adicionar um novo cartão",
|
||||
"Card name" : "Nome do cartão",
|
||||
"List deleted" : "Lista excluída",
|
||||
@@ -197,7 +195,7 @@
|
||||
"Share from Files" : "Compartilhar de Arquivos",
|
||||
"Pending share" : "Compartilhamento pendente",
|
||||
"Add this attachment" : "Adicionar este anexo",
|
||||
"Show in Files" : "Exibir em Arquivos",
|
||||
"Show in Files" : "Mostrar em Arquivos",
|
||||
"Download" : "Baixar",
|
||||
"Remove attachment" : "Remover anexo",
|
||||
"Delete Attachment" : "Excluir Anexo",
|
||||
@@ -212,13 +210,13 @@
|
||||
"Created" : "Criado",
|
||||
"The title cannot be empty." : "O título não pode ficar em branco.",
|
||||
"No comments yet. Begin the discussion!" : "Nenhum comentário ainda. Inicie a conversa!",
|
||||
"Failed to load comments" : "Não foi possível carregar os comentários",
|
||||
"Failed to load comments" : "Falha ao carregar comentários",
|
||||
"Assign a tag to this card…" : "Atribuir uma etiqueta a este cartão...",
|
||||
"Assign to users" : "Atribuir a usuários",
|
||||
"Assign to users/groups/circles" : "Atribuir a usuários/grupos/círculos",
|
||||
"Assign a user to this card…" : "Atribuir um usuário a este cartão...",
|
||||
"Due date" : "Data de vencimento",
|
||||
"Set a due date" : "Definir uma data de vencimento",
|
||||
"Set a due date" : "Definir uma data de finalização",
|
||||
"Remove due date" : "Remover data de vencimento",
|
||||
"Select Date" : "Selecionar Data",
|
||||
"Today" : "Hoje",
|
||||
@@ -242,7 +240,7 @@
|
||||
"Write a description …" : "Escreva uma descrição...",
|
||||
"Choose attachment" : "Escolher anexo",
|
||||
"(group)" : "(grupo)",
|
||||
"Todo items" : "Itens a fazer",
|
||||
"Todo items" : "Itens para fazer",
|
||||
"{count} comments, {unread} unread" : "{count} comentários, {unread} não lidos",
|
||||
"Edit card title" : "Editar título do cartão",
|
||||
"Assign to me" : "Atribuir a mim",
|
||||
@@ -252,7 +250,7 @@
|
||||
"Archive card" : "Arquivar cartão",
|
||||
"Delete card" : "Excluir cartão",
|
||||
"Move card to another board" : "Mover o cartão para outro painel",
|
||||
"List is empty" : "A lista está vazia",
|
||||
"List is empty" : "A Lista está vazia",
|
||||
"Card deleted" : "Cartão excluído",
|
||||
"seconds ago" : "segundos atrás",
|
||||
"All boards" : "Todos os painéis",
|
||||
@@ -260,8 +258,7 @@
|
||||
"Shared with you" : "Compartilhado com você",
|
||||
"Deck settings" : "Configurações do Deck",
|
||||
"Use bigger card view" : "Use uma exibição de cartão maior",
|
||||
"Show card ID badge" : "Exibir o distintivo de identificação do cartão",
|
||||
"Show boards in calendar/tasks" : "Exibir os painéis em calendários/tarefas",
|
||||
"Show boards in calendar/tasks" : "Mostrar painéis em calendários/tarefas",
|
||||
"Limit deck usage of groups" : "Limitar o uso de grupos no deck",
|
||||
"Limiting Deck will block users not part of those groups from creating their own boards. Users will still be able to work on boards that have been shared with them." : "Limitar o Deck impedirá que usuários que não fazem parte desses grupos criem seus próprios painéis. Os usuários ainda poderão trabalhar em pastas que foram compartilhadas com eles.",
|
||||
"Board details" : "Detalhes do painel",
|
||||
@@ -280,20 +277,20 @@
|
||||
"Only assigned cards" : "Apenas cartões atribuídos",
|
||||
"No reminder" : "Nenhum lembrete",
|
||||
"An error occurred" : "Ocorreu um erro",
|
||||
"Are you sure you want to delete the board {title}? This will delete all the data of this board including archived cards." : "Deseja realmente excluir o painel {title}? Isso excluirá todos os dados deste painel, inclusive os cartões arquivados.",
|
||||
"Are you sure you want to delete the board {title}? This will delete all the data of this board including archived cards." : "Tem certeza de que deseja excluir o quadro {title}? Isso excluirá todos os dados deste quadro, incluindo cartões arquivados.",
|
||||
"Delete the board?" : "Excluir o painel?",
|
||||
"Loading filtered view" : "Carregando exibição filtrada",
|
||||
"No due" : "Sem vencimento",
|
||||
"Search for {searchQuery} in all boards" : "Pesquisar por {searchQuery} em todos os painéis",
|
||||
"No results found" : "Nenhum resultado encontrado",
|
||||
"{stack} in {board}" : "{stack} em {board}",
|
||||
"{stack} in {board}" : "{stack} de {board}",
|
||||
"Click to expand description" : "Clique para expandir a descrição",
|
||||
"* Created on {created}\n* Last modified on {lastMod}\n* {nbAttachments} attachments\n* {nbComments} comments" : "* Criado em {created}\n* Última modificação em {lastMod}\n* {nbAttachments} anexos\n* {nbComments} comentários",
|
||||
"{nbCards} cards" : "{nbCards} cartões",
|
||||
"No upcoming cards" : "Não há mais cartões",
|
||||
"upcoming cards" : "próximos cartões",
|
||||
"Due on {date}" : "Vencimento em {date}",
|
||||
"Link to a board" : "Vincular a um painel",
|
||||
"Link to a board" : "Linkar a um painel",
|
||||
"Link to a card" : "Vincular a um cartão",
|
||||
"Create a card" : "Criar um cartão",
|
||||
"Message from {author} in {conversationName}" : "Mensagem de {author} em {conversationName}",
|
||||
@@ -305,11 +302,11 @@
|
||||
"Share {file} with a Deck card" : "Compartilhar {file} com um cartão Deck",
|
||||
"Share" : "Compartilhar",
|
||||
"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 é uma ferramenta de organização de estilo kanban destinada ao planejamento pessoal e organização para equipes integradas com o Nextcloud.\n\n\n- 📥 Adicione suas tarefas aos cartões e coloque-os em ordem\n- 📄 Insira notas adicionais em markdown\n- 🔖 Atribua etiquetas para melhorar a organização\n- 👥 Compartilhe com sua equipe, amigos ou familiares\n- 📎 Anexe arquivos e incorpore-os em sua descrição no markdown\n- 💬 Discuta com sua equipe usando os comentários\n- ⚡ Acompanhe as alterações no fluxo de atividades\n- 🚀 Mantenha seu projeto organizado",
|
||||
"Are you sure you want to transfer the board {title} for {user} ?" : "Deseja realmente transferir o painel {title} para {user}?",
|
||||
"Transfer the board for {user} successfully" : "O painel foi transferido para {user} com sucesso",
|
||||
"Failed to transfer the board for {user}" : "Não foi possível transferir o painel para {user}",
|
||||
"Are you sure you want to transfer the board {title} for {user} ?" : "Tem certeza de que deseja transferir o quadro {title} para {user}?",
|
||||
"Transfer the board for {user} successfully" : "Transferida a reunião para {user} com sucesso",
|
||||
"Failed to transfer the board for {user}" : "Falha ao transferir a reunião para {user}",
|
||||
"Are you sure you want to delete the board {title}? This will delete all the data of this board." : "Deseja realmente excluir o painel {title}? Isto excluirá todos os dados deste painel.",
|
||||
"This week" : "Esta semana",
|
||||
"Are you sure you want to transfer the board {title} for {user}?" : "Deseja realmente transferir o painel {title} para {user}?"
|
||||
"Are you sure you want to transfer the board {title} for {user}?" : "Tem certeza de que deseja transferir o quadro {title} para {user}?"
|
||||
},"pluralForm" :"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
|
||||
}
|
||||
@@ -183,10 +183,8 @@ OC.L10N.register(
|
||||
"Failed to transfer the board to {user}" : "Не удалось передать доску пользователю {user}",
|
||||
"Add a new list" : "Создать список",
|
||||
"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" : "Название карточки",
|
||||
"List deleted" : "Список удалён",
|
||||
@@ -244,9 +242,7 @@ OC.L10N.register(
|
||||
"Write a description …" : "Добавьте описание...",
|
||||
"Choose attachment" : "Выберите вложение",
|
||||
"(group)" : "(группа)",
|
||||
"Todo items" : "Элементы списка задач",
|
||||
"{count} comments, {unread} unread" : "{count} комментариев, {unread} непрочитано",
|
||||
"Edit card title" : "Изменить заголовок карточки",
|
||||
"Assign to me" : "Назначить себе",
|
||||
"Unassign myself" : "Отказаться от назначения",
|
||||
"Move card" : "Переместить карточку",
|
||||
@@ -260,9 +256,7 @@ OC.L10N.register(
|
||||
"All boards" : "Все доски",
|
||||
"Archived boards" : "Архив досок",
|
||||
"Shared with you" : "Предоставленные вам",
|
||||
"Deck settings" : "Параметры карточек",
|
||||
"Use bigger card view" : "Режим просмотра с увеличенными карточками",
|
||||
"Show card ID badge" : "Показывать идентификатор карточки",
|
||||
"Show boards in calendar/tasks" : "Показывать карточки в календаре и задачах",
|
||||
"Limit deck usage of groups" : "Разрешить использовать приложение Карточки только участникам заданных групп",
|
||||
"Limiting Deck will block users not part of those groups from creating their own boards. Users will still be able to work on boards that have been shared with them." : "Создание собственных рабочих досок пользователям, не входящим в заданные группы, будет заблокировано. Тем не менее, такие пользователи смогут продолжить работать с общими досками, к которым у них есть доступ. ",
|
||||
@@ -282,15 +276,12 @@ OC.L10N.register(
|
||||
"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?" : "Удалить доску?",
|
||||
"Loading filtered view" : "Выполняется отбор",
|
||||
"No due" : "Без назначенной даты",
|
||||
"Search for {searchQuery} in all boards" : "Искать {searchQuery} на всех досках",
|
||||
"No results found" : "Результаты отсутствуют",
|
||||
"{stack} in {board}" : "«{stack}» с доски «{board}»",
|
||||
"Click to expand description" : "Нажмите, чтобы развернуть поле описания",
|
||||
"{nbCards} cards" : "карточек: {nbCards}",
|
||||
"No upcoming cards" : "Отсутствуют карточки, ожидающие выполнения",
|
||||
"upcoming cards" : "карточки, ожидающие выполнения",
|
||||
"Link to a board" : "Ссылка на доску",
|
||||
|
||||
@@ -181,10 +181,8 @@
|
||||
"Failed to transfer the board to {user}" : "Не удалось передать доску пользователю {user}",
|
||||
"Add a new list" : "Создать список",
|
||||
"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" : "Название карточки",
|
||||
"List deleted" : "Список удалён",
|
||||
@@ -242,9 +240,7 @@
|
||||
"Write a description …" : "Добавьте описание...",
|
||||
"Choose attachment" : "Выберите вложение",
|
||||
"(group)" : "(группа)",
|
||||
"Todo items" : "Элементы списка задач",
|
||||
"{count} comments, {unread} unread" : "{count} комментариев, {unread} непрочитано",
|
||||
"Edit card title" : "Изменить заголовок карточки",
|
||||
"Assign to me" : "Назначить себе",
|
||||
"Unassign myself" : "Отказаться от назначения",
|
||||
"Move card" : "Переместить карточку",
|
||||
@@ -258,9 +254,7 @@
|
||||
"All boards" : "Все доски",
|
||||
"Archived boards" : "Архив досок",
|
||||
"Shared with you" : "Предоставленные вам",
|
||||
"Deck settings" : "Параметры карточек",
|
||||
"Use bigger card view" : "Режим просмотра с увеличенными карточками",
|
||||
"Show card ID badge" : "Показывать идентификатор карточки",
|
||||
"Show boards in calendar/tasks" : "Показывать карточки в календаре и задачах",
|
||||
"Limit deck usage of groups" : "Разрешить использовать приложение Карточки только участникам заданных групп",
|
||||
"Limiting Deck will block users not part of those groups from creating their own boards. Users will still be able to work on boards that have been shared with them." : "Создание собственных рабочих досок пользователям, не входящим в заданные группы, будет заблокировано. Тем не менее, такие пользователи смогут продолжить работать с общими досками, к которым у них есть доступ. ",
|
||||
@@ -280,15 +274,12 @@
|
||||
"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?" : "Удалить доску?",
|
||||
"Loading filtered view" : "Выполняется отбор",
|
||||
"No due" : "Без назначенной даты",
|
||||
"Search for {searchQuery} in all boards" : "Искать {searchQuery} на всех досках",
|
||||
"No results found" : "Результаты отсутствуют",
|
||||
"{stack} in {board}" : "«{stack}» с доски «{board}»",
|
||||
"Click to expand description" : "Нажмите, чтобы развернуть поле описания",
|
||||
"{nbCards} cards" : "карточек: {nbCards}",
|
||||
"No upcoming cards" : "Отсутствуют карточки, ожидающие выполнения",
|
||||
"upcoming cards" : "карточки, ожидающие выполнения",
|
||||
"Link to a board" : "Ссылка на доску",
|
||||
|
||||
@@ -183,10 +183,8 @@ OC.L10N.register(
|
||||
"Failed to transfer the board to {user}" : "Chyba pri presune nástenky na {user}",
|
||||
"Add a new list" : "Pridať nový zoznam",
|
||||
"Archive all cards" : "Archivovať všetky karty",
|
||||
"Unarchive all cards" : "Zrušiť archiváciu všetkých kariet",
|
||||
"Delete list" : "Vymazať zoznam",
|
||||
"Archive all cards in this list" : "Archivovať všetky karty v tomto zozname",
|
||||
"Unarchive all cards in this list" : "Zrušiť archiváciu všetkých kariet v tomto zozname",
|
||||
"Add a new card" : "Pridať novú kartu",
|
||||
"Card name" : "Názov karty",
|
||||
"List deleted" : "Zoznam bol vymazaný",
|
||||
@@ -262,7 +260,6 @@ OC.L10N.register(
|
||||
"Shared with you" : "Vám sprístupnené",
|
||||
"Deck settings" : "Nastavenia paluby",
|
||||
"Use bigger card view" : "Použiť väčšie zobrazenie karty",
|
||||
"Show card ID badge" : "Ukázať ID karty",
|
||||
"Show boards in calendar/tasks" : "Zobrazovať nástenky v kalendári/úlohách",
|
||||
"Limit deck usage of groups" : "Obmedziť použitie Deck na skupiny",
|
||||
"Limiting Deck will block users not part of those groups from creating their own boards. Users will still be able to work on boards that have been shared with them." : "Obmedzenie Násteniek bráni používateľom, ktorí nie sú súčasťou týchto skupín, aby si vytvárali vlastné nástenky. Môžu však stále pracovať na nástenkách, ktoré im niekto sprístupní.",
|
||||
|
||||
@@ -181,10 +181,8 @@
|
||||
"Failed to transfer the board to {user}" : "Chyba pri presune nástenky na {user}",
|
||||
"Add a new list" : "Pridať nový zoznam",
|
||||
"Archive all cards" : "Archivovať všetky karty",
|
||||
"Unarchive all cards" : "Zrušiť archiváciu všetkých kariet",
|
||||
"Delete list" : "Vymazať zoznam",
|
||||
"Archive all cards in this list" : "Archivovať všetky karty v tomto zozname",
|
||||
"Unarchive all cards in this list" : "Zrušiť archiváciu všetkých kariet v tomto zozname",
|
||||
"Add a new card" : "Pridať novú kartu",
|
||||
"Card name" : "Názov karty",
|
||||
"List deleted" : "Zoznam bol vymazaný",
|
||||
@@ -260,7 +258,6 @@
|
||||
"Shared with you" : "Vám sprístupnené",
|
||||
"Deck settings" : "Nastavenia paluby",
|
||||
"Use bigger card view" : "Použiť väčšie zobrazenie karty",
|
||||
"Show card ID badge" : "Ukázať ID karty",
|
||||
"Show boards in calendar/tasks" : "Zobrazovať nástenky v kalendári/úlohách",
|
||||
"Limit deck usage of groups" : "Obmedziť použitie Deck na skupiny",
|
||||
"Limiting Deck will block users not part of those groups from creating their own boards. Users will still be able to work on boards that have been shared with them." : "Obmedzenie Násteniek bráni používateľom, ktorí nie sú súčasťou týchto skupín, aby si vytvárali vlastné nástenky. Môžu však stále pracovať na nástenkách, ktoré im niekto sprístupní.",
|
||||
|
||||
@@ -260,7 +260,7 @@ OC.L10N.register(
|
||||
"All boards" : "Alla tavlor",
|
||||
"Archived boards" : "Arkiverade tavlor",
|
||||
"Shared with you" : "Delad med dig",
|
||||
"Deck settings" : "Deck-inställningar",
|
||||
"Deck settings" : "Deckinställningar",
|
||||
"Use bigger card view" : "Visa större kort",
|
||||
"Show card ID badge" : "Visa kortets ID-märke",
|
||||
"Show boards in calendar/tasks" : "Visa tavlor i kalender / uppgifter",
|
||||
|
||||
@@ -258,7 +258,7 @@
|
||||
"All boards" : "Alla tavlor",
|
||||
"Archived boards" : "Arkiverade tavlor",
|
||||
"Shared with you" : "Delad med dig",
|
||||
"Deck settings" : "Deck-inställningar",
|
||||
"Deck settings" : "Deckinställningar",
|
||||
"Use bigger card view" : "Visa större kort",
|
||||
"Show card ID badge" : "Visa kortets ID-märke",
|
||||
"Show boards in calendar/tasks" : "Visa tavlor i kalender / uppgifter",
|
||||
|
||||
@@ -11,7 +11,7 @@ OC.L10N.register(
|
||||
"{user} has shared the board {board} with {acl}" : "{user} поділився дошкою {board} з {acl}",
|
||||
"You have removed {acl} from the board {board}" : "Ви вилучили {acl} з дошки {board}",
|
||||
"{user} has removed {acl} from the board {board}" : "{user} вилучив {acl} з дошки {board}",
|
||||
"You have renamed the board {before} to {board}" : "Ви перейменували дошку з {before} на {board}",
|
||||
"You have renamed the board {before} to {board}" : "Ви перейменували дошку з {before} у {board}",
|
||||
"{user} has renamed the board {before} to {board}" : "{user} змінив назву дошки {before} на {board}",
|
||||
"You have archived the board {board}" : "Ви заархівували дошку {board}",
|
||||
"{user} has archived the board {before}" : "{user} заархівував дошку {before}",
|
||||
@@ -125,7 +125,7 @@ OC.L10N.register(
|
||||
"Upload new files" : "Додати файл",
|
||||
"Share from Files" : "Відкрити Файли",
|
||||
"Add this attachment" : "Долучити вкладення",
|
||||
"Download" : "Звантажити",
|
||||
"Download" : "Завантажити",
|
||||
"Delete Attachment" : "Забрати вкладення",
|
||||
"Restore Attachment" : "Відновити вкладення",
|
||||
"File to share" : "Виберіть файл для надання доступу",
|
||||
@@ -190,7 +190,7 @@ OC.L10N.register(
|
||||
"Something went wrong" : "От халепа!",
|
||||
"Maximum file size of {size} exceeded" : "Досягнуто максимальний розмір файлу {size}",
|
||||
"Error creating the share" : "Помилка створення спільного доступу",
|
||||
"Share" : "Спільний доступ",
|
||||
"Share" : "Поділитися",
|
||||
"This week" : "Цього тижня"
|
||||
},
|
||||
"nplurals=4; plural=(n % 1 == 0 && n % 10 == 1 && n % 100 != 11 ? 0 : n % 1 == 0 && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14) ? 1 : n % 1 == 0 && (n % 10 ==0 || (n % 10 >=5 && n % 10 <=9) || (n % 100 >=11 && n % 100 <=14 )) ? 2: 3);");
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"{user} has shared the board {board} with {acl}" : "{user} поділився дошкою {board} з {acl}",
|
||||
"You have removed {acl} from the board {board}" : "Ви вилучили {acl} з дошки {board}",
|
||||
"{user} has removed {acl} from the board {board}" : "{user} вилучив {acl} з дошки {board}",
|
||||
"You have renamed the board {before} to {board}" : "Ви перейменували дошку з {before} на {board}",
|
||||
"You have renamed the board {before} to {board}" : "Ви перейменували дошку з {before} у {board}",
|
||||
"{user} has renamed the board {before} to {board}" : "{user} змінив назву дошки {before} на {board}",
|
||||
"You have archived the board {board}" : "Ви заархівували дошку {board}",
|
||||
"{user} has archived the board {before}" : "{user} заархівував дошку {before}",
|
||||
@@ -123,7 +123,7 @@
|
||||
"Upload new files" : "Додати файл",
|
||||
"Share from Files" : "Відкрити Файли",
|
||||
"Add this attachment" : "Долучити вкладення",
|
||||
"Download" : "Звантажити",
|
||||
"Download" : "Завантажити",
|
||||
"Delete Attachment" : "Забрати вкладення",
|
||||
"Restore Attachment" : "Відновити вкладення",
|
||||
"File to share" : "Виберіть файл для надання доступу",
|
||||
@@ -188,7 +188,7 @@
|
||||
"Something went wrong" : "От халепа!",
|
||||
"Maximum file size of {size} exceeded" : "Досягнуто максимальний розмір файлу {size}",
|
||||
"Error creating the share" : "Помилка створення спільного доступу",
|
||||
"Share" : "Спільний доступ",
|
||||
"Share" : "Поділитися",
|
||||
"This week" : "Цього тижня"
|
||||
},"pluralForm" :"nplurals=4; plural=(n % 1 == 0 && n % 10 == 1 && n % 100 != 11 ? 0 : n % 1 == 0 && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14) ? 1 : n % 1 == 0 && (n % 10 ==0 || (n % 10 >=5 && n % 10 <=9) || (n % 100 >=11 && n % 100 <=14 )) ? 2: 3);"
|
||||
}
|
||||
@@ -134,7 +134,6 @@ OC.L10N.register(
|
||||
"Archived cards" : "已归档卡片",
|
||||
"Add list" : "添加列表",
|
||||
"List name" : "列表名称",
|
||||
"Active filters" : "已开启的过滤器",
|
||||
"Apply filter" : "应用筛选",
|
||||
"Filter by tag" : "按标签筛选",
|
||||
"Filter by assigned user" : "按指派的用户筛选",
|
||||
@@ -236,9 +235,7 @@ OC.L10N.register(
|
||||
"Write a description …" : "写一段描述",
|
||||
"Choose attachment" : "选择附件",
|
||||
"(group)" : "(组)",
|
||||
"Todo items" : "待办事项",
|
||||
"{count} comments, {unread} unread" : "{count} 条评论,{unread} 未读",
|
||||
"Edit card title" : "编辑卡片标题",
|
||||
"Assign to me" : "指派给我",
|
||||
"Unassign myself" : "不再指派给我",
|
||||
"Move card" : "移动卡片",
|
||||
|
||||
@@ -132,7 +132,6 @@
|
||||
"Archived cards" : "已归档卡片",
|
||||
"Add list" : "添加列表",
|
||||
"List name" : "列表名称",
|
||||
"Active filters" : "已开启的过滤器",
|
||||
"Apply filter" : "应用筛选",
|
||||
"Filter by tag" : "按标签筛选",
|
||||
"Filter by assigned user" : "按指派的用户筛选",
|
||||
@@ -234,9 +233,7 @@
|
||||
"Write a description …" : "写一段描述",
|
||||
"Choose attachment" : "选择附件",
|
||||
"(group)" : "(组)",
|
||||
"Todo items" : "待办事项",
|
||||
"{count} comments, {unread} unread" : "{count} 条评论,{unread} 未读",
|
||||
"Edit card title" : "编辑卡片标题",
|
||||
"Assign to me" : "指派给我",
|
||||
"Unassign myself" : "不再指派给我",
|
||||
"Move card" : "移动卡片",
|
||||
|
||||
@@ -39,7 +39,6 @@ use OCA\Deck\Db\CardMapper;
|
||||
use OCA\Deck\Db\Label;
|
||||
use OCA\Deck\Db\Stack;
|
||||
use OCA\Deck\Db\StackMapper;
|
||||
use OCA\Deck\NoPermissionException;
|
||||
use OCA\Deck\Service\PermissionService;
|
||||
use OCP\Activity\IEvent;
|
||||
use OCP\Activity\IManager;
|
||||
@@ -544,24 +543,4 @@ class ActivityManager {
|
||||
'board' => $board
|
||||
];
|
||||
}
|
||||
|
||||
public function canSeeCardActivity(int $cardId): bool {
|
||||
try {
|
||||
$this->permissionService->checkPermission($this->cardMapper, $cardId, Acl::PERMISSION_READ);
|
||||
$card = $this->cardMapper->find($cardId);
|
||||
return $card->getDeletedAt() === 0;
|
||||
} catch (NoPermissionException $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function canSeeBoardActivity(int $boardId): bool {
|
||||
try {
|
||||
$this->permissionService->checkPermission($this->boardMapper, $boardId, Acl::PERMISSION_READ);
|
||||
$board = $this->boardMapper->find($boardId);
|
||||
return $board->getDeletedAt() === 0;
|
||||
} catch (NoPermissionException $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,9 +111,6 @@ class DeckProvider implements IProvider {
|
||||
$event->setAuthor($author);
|
||||
}
|
||||
if ($event->getObjectType() === ActivityManager::DECK_OBJECT_BOARD) {
|
||||
if (!$this->activityManager->canSeeBoardActivity($event->getObjectId())) {
|
||||
throw new \InvalidArgumentException();
|
||||
}
|
||||
if (isset($subjectParams['board']) && $event->getObjectName() === '') {
|
||||
$event->setObject($event->getObjectType(), $event->getObjectId(), $subjectParams['board']['title']);
|
||||
}
|
||||
@@ -124,13 +121,9 @@ class DeckProvider implements IProvider {
|
||||
'link' => $this->deckUrl('/board/' . $event->getObjectId()),
|
||||
];
|
||||
$params['board'] = $board;
|
||||
$event->setLink($this->deckUrl('/board/' . $event->getObjectId()));
|
||||
}
|
||||
|
||||
if (isset($subjectParams['card']) && $event->getObjectType() === ActivityManager::DECK_OBJECT_CARD) {
|
||||
if (!$this->activityManager->canSeeCardActivity($event->getObjectId())) {
|
||||
throw new \InvalidArgumentException();
|
||||
}
|
||||
if ($event->getObjectName() === '') {
|
||||
$event->setObject($event->getObjectType(), $event->getObjectId(), $subjectParams['card']['title']);
|
||||
}
|
||||
@@ -141,8 +134,8 @@ class DeckProvider implements IProvider {
|
||||
];
|
||||
|
||||
if (array_key_exists('board', $subjectParams)) {
|
||||
$archivedParam = $subjectParams['card']['archived'] ? 'archived/' : '';
|
||||
$card['link'] = $this->cardService->getRedirectUrlForCard($event->getObjectId());
|
||||
$event->setLink($card['link']);
|
||||
}
|
||||
$params['card'] = $card;
|
||||
}
|
||||
|
||||
@@ -100,15 +100,12 @@ class ResourceProvider implements IProvider {
|
||||
if ($board->getOwner() === $user->getUID()) {
|
||||
return true;
|
||||
}
|
||||
if ($board->getAcl() === null) {
|
||||
return false;
|
||||
}
|
||||
return $this->permissionService->userCan($board->getAcl(), Acl::PERMISSION_READ, $user->getUID());
|
||||
}
|
||||
|
||||
private function getBoard(IResource $resource) {
|
||||
try {
|
||||
return $this->boardMapper->find((int)$resource->getId(), false, true);
|
||||
return $this->boardMapper->find($resource->getId(), false, true);
|
||||
} catch (DoesNotExistException $e) {
|
||||
} catch (MultipleObjectsReturnedException $e) {
|
||||
return null;
|
||||
|
||||
@@ -127,9 +127,6 @@ class ResourceProviderCard implements IProvider {
|
||||
if ($board->getOwner() === $user->getUID()) {
|
||||
return true;
|
||||
}
|
||||
if ($board->getAcl() === null) {
|
||||
return false;
|
||||
}
|
||||
return $this->permissionService->userCan($board->getAcl(), Acl::PERMISSION_READ, $user->getUID());
|
||||
}
|
||||
|
||||
|
||||
@@ -52,6 +52,12 @@ class Calendar extends ExternalCalendar {
|
||||
$this->board = $board;
|
||||
|
||||
$this->principalUri = $principalUri;
|
||||
|
||||
if ($board) {
|
||||
$this->children = $this->backend->getChildren($board->getId());
|
||||
} else {
|
||||
$this->children = [];
|
||||
}
|
||||
}
|
||||
|
||||
public function getOwner() {
|
||||
@@ -116,7 +122,7 @@ class Calendar extends ExternalCalendar {
|
||||
public function getChild($name) {
|
||||
if ($this->childExists($name)) {
|
||||
$card = array_values(array_filter(
|
||||
$this->getBackendChildren(),
|
||||
$this->children,
|
||||
function ($card) use (&$name) {
|
||||
return $card->getCalendarPrefix() . '-' . $card->getId() . '.ics' === $name;
|
||||
}
|
||||
@@ -131,7 +137,7 @@ class Calendar extends ExternalCalendar {
|
||||
public function getChildren() {
|
||||
$childNames = array_map(function ($card) {
|
||||
return $card->getCalendarPrefix() . '-' . $card->getId() . '.ics';
|
||||
}, $this->getBackendChildren());
|
||||
}, $this->children);
|
||||
|
||||
$children = [];
|
||||
|
||||
@@ -142,23 +148,9 @@ class Calendar extends ExternalCalendar {
|
||||
return $children;
|
||||
}
|
||||
|
||||
private function getBackendChildren() {
|
||||
if ($this->children) {
|
||||
return $this->children;
|
||||
}
|
||||
|
||||
if ($this->board) {
|
||||
$this->children = $this->backend->getChildren($this->board->getId());
|
||||
} else {
|
||||
$this->children = [];
|
||||
}
|
||||
|
||||
return $this->children;
|
||||
}
|
||||
|
||||
public function childExists($name) {
|
||||
return count(array_filter(
|
||||
$this->getBackendChildren(),
|
||||
$this->children,
|
||||
function ($card) use (&$name) {
|
||||
return $card->getCalendarPrefix() . '-' . $card->getId() . '.ics' === $name;
|
||||
}
|
||||
|
||||
@@ -67,13 +67,13 @@ class AttachmentMapper extends DeckMapper implements IPermissionMapper {
|
||||
$row = $cursor->fetch(PDO::FETCH_ASSOC);
|
||||
if ($row === false) {
|
||||
$cursor->closeCursor();
|
||||
throw new DoesNotExistException('Did expect one result but found none when executing query: ' . $qb->getSQL());
|
||||
throw new DoesNotExistException('Did expect one result but found none when executing' . $qb);
|
||||
}
|
||||
|
||||
$row2 = $cursor->fetch();
|
||||
$cursor->closeCursor();
|
||||
if ($row2 !== false) {
|
||||
throw new MultipleObjectsReturnedException('Did not expect more than one result when executing query: ' . $qb->getSQL());
|
||||
throw new MultipleObjectsReturnedException('Did not expect more than one result when executing' . $qb);
|
||||
}
|
||||
|
||||
return $this->mapRowToEntity($row);
|
||||
@@ -89,7 +89,7 @@ class AttachmentMapper extends DeckMapper implements IPermissionMapper {
|
||||
$row = $cursor->fetch(PDO::FETCH_ASSOC);
|
||||
if ($row === false) {
|
||||
$cursor->closeCursor();
|
||||
throw new DoesNotExistException('Did expect one result but found none when executing query: ' . $qb->getSQL());
|
||||
throw new DoesNotExistException('Did expect one result but found none when executing' . $qb);
|
||||
}
|
||||
$cursor->closeCursor();
|
||||
return $this->mapRowToEntity($row);
|
||||
|
||||
@@ -28,10 +28,8 @@ class Board extends RelationalEntity {
|
||||
protected $owner;
|
||||
protected $color;
|
||||
protected $archived = false;
|
||||
/** @var Label[]|null */
|
||||
protected $labels = null;
|
||||
/** @var Acl[]|null */
|
||||
protected $acl = null;
|
||||
protected $labels = [];
|
||||
protected $acl = [];
|
||||
protected $permissions = [];
|
||||
protected $users = [];
|
||||
protected $shared;
|
||||
@@ -63,10 +61,6 @@ class Board extends RelationalEntity {
|
||||
if ($this->shared === -1) {
|
||||
unset($json['shared']);
|
||||
}
|
||||
// FIXME: Ideally the API responses should follow the internal data structure and return null if the labels/acls have not been fetched from the db
|
||||
// however this would be a breaking change for consumers of the API
|
||||
$json['acl'] = $this->acl ?? [];
|
||||
$json['labels'] = $this->labels ?? [];
|
||||
return $json;
|
||||
}
|
||||
|
||||
@@ -74,27 +68,21 @@ class Board extends RelationalEntity {
|
||||
* @param Label[] $labels
|
||||
*/
|
||||
public function setLabels($labels) {
|
||||
$this->labels = $labels;
|
||||
foreach ($labels as $l) {
|
||||
$this->labels[] = $l;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Acl[] $acl
|
||||
*/
|
||||
public function setAcl($acl) {
|
||||
$this->acl = $acl;
|
||||
foreach ($acl as $a) {
|
||||
$this->acl[] = $a;
|
||||
}
|
||||
}
|
||||
|
||||
public function getETag() {
|
||||
return md5((string)$this->getLastModified());
|
||||
}
|
||||
|
||||
/** @returns Acl[]|null */
|
||||
public function getAcl(): ?array {
|
||||
return $this->acl;
|
||||
}
|
||||
|
||||
/** @returns Label[]|null */
|
||||
public function getLabels(): ?array {
|
||||
return $this->labels;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,14 +26,13 @@ namespace OCA\Deck\Db;
|
||||
use OC\Cache\CappedMemoryCache;
|
||||
use OCA\Deck\Service\CirclesService;
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
use OCP\AppFramework\Db\QBMapper;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\IUserManager;
|
||||
use OCP\IGroupManager;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class BoardMapper extends QBMapper implements IPermissionMapper {
|
||||
class BoardMapper extends DeckMapper implements IPermissionMapper {
|
||||
private $labelMapper;
|
||||
private $aclMapper;
|
||||
private $stackMapper;
|
||||
@@ -44,8 +43,6 @@ class BoardMapper extends QBMapper implements IPermissionMapper {
|
||||
|
||||
/** @var CappedMemoryCache */
|
||||
private $userBoardCache;
|
||||
/** @var CappedMemoryCache */
|
||||
private $boardCache;
|
||||
|
||||
public function __construct(
|
||||
IDBConnection $db,
|
||||
@@ -67,7 +64,6 @@ class BoardMapper extends QBMapper implements IPermissionMapper {
|
||||
$this->logger = $logger;
|
||||
|
||||
$this->userBoardCache = new CappedMemoryCache();
|
||||
$this->boardCache = new CappedMemoryCache();
|
||||
}
|
||||
|
||||
|
||||
@@ -75,54 +71,40 @@ class BoardMapper extends QBMapper implements IPermissionMapper {
|
||||
* @param $id
|
||||
* @param bool $withLabels
|
||||
* @param bool $withAcl
|
||||
* @return Board
|
||||
* @return \OCP\AppFramework\Db\Entity
|
||||
* @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException
|
||||
* @throws DoesNotExistException
|
||||
*/
|
||||
public function find(int $id, bool $withLabels = false, bool $withAcl = false, bool $allowDeleted = false): Board {
|
||||
if (!isset($this->boardCache[$id])) {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$deletedWhere = $allowDeleted ? $qb->expr()->gte('deleted_at', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT)) : $qb->expr()->eq('deleted_at', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT));
|
||||
$qb->select('*')
|
||||
->from('deck_boards')
|
||||
->where($qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)))
|
||||
->andWhere($deletedWhere)
|
||||
->orderBy('id');
|
||||
$this->boardCache[$id] = $this->findEntity($qb);
|
||||
}
|
||||
|
||||
// FIXME is this necessary? it was NOT done with the old mapper
|
||||
// $this->mapOwner($board);
|
||||
public function find($id, $withLabels = false, $withAcl = false) {
|
||||
$sql = 'SELECT id, title, owner, color, archived, deleted_at, last_modified FROM `*PREFIX*deck_boards` ' .
|
||||
'WHERE `id` = ?';
|
||||
$board = $this->findEntity($sql, [$id]);
|
||||
|
||||
// Add labels
|
||||
if ($withLabels && $this->boardCache[$id]->getLabels() === null) {
|
||||
if ($withLabels) {
|
||||
$labels = $this->labelMapper->findAll($id);
|
||||
$this->boardCache[$id]->setLabels($labels);
|
||||
$board->setLabels($labels);
|
||||
}
|
||||
|
||||
// Add acl
|
||||
if ($withAcl && $this->boardCache[$id]->getAcl() === null) {
|
||||
if ($withAcl) {
|
||||
$acl = $this->aclMapper->findAll($id);
|
||||
$this->boardCache[$id]->setAcl($acl);
|
||||
$board->setAcl($acl);
|
||||
}
|
||||
|
||||
return $this->boardCache[$id];
|
||||
return $board;
|
||||
}
|
||||
|
||||
public function findAllForUser(string $userId, ?int $since = null, bool $includeArchived = true, ?int $before = null,
|
||||
?string $term = null): array {
|
||||
$useCache = ($since === -1 && $includeArchived === true && $before === null && $term === null);
|
||||
public function findAllForUser(string $userId, int $since = -1, $includeArchived = true): array {
|
||||
$useCache = ($since === -1 && $includeArchived === true);
|
||||
if (!isset($this->userBoardCache[$userId]) || !$useCache) {
|
||||
$groups = $this->groupManager->getUserGroupIds(
|
||||
$this->userManager->get($userId)
|
||||
);
|
||||
$userBoards = $this->findAllByUser($userId, null, null, $since, $includeArchived, $before, $term);
|
||||
$groupBoards = $this->findAllByGroups($userId, $groups, null, null, $since, $includeArchived, $before, $term);
|
||||
$circleBoards = $this->findAllByCircles($userId, null, null, $since, $includeArchived, $before, $term);
|
||||
$userBoards = $this->findAllByUser($userId, null, null, $since, $includeArchived);
|
||||
$groupBoards = $this->findAllByGroups($userId, $groups, null, null, $since, $includeArchived);
|
||||
$circleBoards = $this->findAllByCircles($userId, null, null, $since, $includeArchived);
|
||||
$allBoards = array_unique(array_merge($userBoards, $groupBoards, $circleBoards));
|
||||
foreach ($allBoards as $board) {
|
||||
$this->boardCache[$board->getId()] = $board;
|
||||
}
|
||||
if ($useCache) {
|
||||
$this->userBoardCache[$userId] = $allBoards;
|
||||
}
|
||||
@@ -139,91 +121,19 @@ class BoardMapper extends QBMapper implements IPermissionMapper {
|
||||
* @param null $offset
|
||||
* @return array
|
||||
*/
|
||||
public function findAllByUser(string $userId, ?int $limit = null, ?int $offset = null, ?int $since = null,
|
||||
bool $includeArchived = true, ?int $before = null, ?string $term = null) {
|
||||
// FIXME this used to be a UNION to get boards owned by $userId and the user shares in one single query
|
||||
// Is it possible with the query builder?
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->select('id', 'title', 'owner', 'color', 'archived', 'deleted_at', 'last_modified')
|
||||
// this does not work in MySQL/PostgreSQL
|
||||
//->selectAlias('0', 'shared')
|
||||
->from('deck_boards', 'b')
|
||||
->where($qb->expr()->eq('owner', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)));
|
||||
public function findAllByUser($userId, $limit = null, $offset = null, $since = -1, $includeArchived = true) {
|
||||
// FIXME: One moving to QBMapper we should allow filtering the boards probably by method chaining for additional where clauses
|
||||
$sql = 'SELECT id, title, owner, color, archived, deleted_at, 0 as shared, last_modified FROM `*PREFIX*deck_boards` WHERE owner = ? AND last_modified > ?';
|
||||
if (!$includeArchived) {
|
||||
$qb->andWhere($qb->expr()->eq('archived', $qb->createNamedParameter(false, IQueryBuilder::PARAM_BOOL)))
|
||||
->andWhere($qb->expr()->eq('deleted_at', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT)));
|
||||
$sql .= ' AND NOT archived AND deleted_at = 0';
|
||||
}
|
||||
if ($since !== null) {
|
||||
$qb->andWhere($qb->expr()->gt('last_modified', $qb->createNamedParameter($since, IQueryBuilder::PARAM_INT)));
|
||||
}
|
||||
if ($before !== null) {
|
||||
$qb->andWhere($qb->expr()->lt('last_modified', $qb->createNamedParameter($before, IQueryBuilder::PARAM_INT)));
|
||||
}
|
||||
if ($term !== null) {
|
||||
$qb->andWhere(
|
||||
$qb->expr()->iLike(
|
||||
'title',
|
||||
$qb->createNamedParameter(
|
||||
'%' . $this->db->escapeLikeParameter($term) . '%',
|
||||
IQueryBuilder::PARAM_STR
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
$qb->orderBy('b.id');
|
||||
if ($limit !== null) {
|
||||
$qb->setMaxResults($limit);
|
||||
}
|
||||
if ($offset !== null) {
|
||||
$qb->setFirstResult($offset);
|
||||
}
|
||||
$entries = $this->findEntities($qb);
|
||||
foreach ($entries as $entry) {
|
||||
$entry->setShared(0);
|
||||
}
|
||||
|
||||
// shared with user
|
||||
$qb->resetQueryParts();
|
||||
$qb->select('b.id', 'title', 'owner', 'color', 'archived', 'deleted_at', 'last_modified')
|
||||
//->selectAlias('1', 'shared')
|
||||
->from('deck_boards', 'b')
|
||||
->innerJoin('b', 'deck_board_acl', 'acl', $qb->expr()->eq('b.id', 'acl.board_id'))
|
||||
->where($qb->expr()->eq('acl.participant', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)))
|
||||
->andWhere($qb->expr()->eq('acl.type', $qb->createNamedParameter(Acl::PERMISSION_TYPE_USER, IQueryBuilder::PARAM_INT)))
|
||||
->andWhere($qb->expr()->neq('b.owner', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)));
|
||||
$sql .= ' UNION ' .
|
||||
'SELECT boards.id, title, owner, color, archived, deleted_at, 1 as shared, last_modified FROM `*PREFIX*deck_boards` as boards ' .
|
||||
'JOIN `*PREFIX*deck_board_acl` as acl ON boards.id=acl.board_id WHERE acl.participant=? AND acl.type=? AND boards.owner != ? AND last_modified > ?';
|
||||
if (!$includeArchived) {
|
||||
$qb->andWhere($qb->expr()->eq('archived', $qb->createNamedParameter(false, IQueryBuilder::PARAM_BOOL)))
|
||||
->andWhere($qb->expr()->eq('deleted_at', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT)));
|
||||
$sql .= ' AND NOT archived AND deleted_at = 0';
|
||||
}
|
||||
if ($since !== null) {
|
||||
$qb->andWhere($qb->expr()->gt('last_modified', $qb->createNamedParameter($since, IQueryBuilder::PARAM_INT)));
|
||||
}
|
||||
if ($before !== null) {
|
||||
$qb->andWhere($qb->expr()->lt('last_modified', $qb->createNamedParameter($before, IQueryBuilder::PARAM_INT)));
|
||||
}
|
||||
if ($term !== null) {
|
||||
$qb->andWhere(
|
||||
$qb->expr()->iLike(
|
||||
'title',
|
||||
$qb->createNamedParameter(
|
||||
'%' . $this->db->escapeLikeParameter($term) . '%',
|
||||
IQueryBuilder::PARAM_STR
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
$qb->orderBy('b.id');
|
||||
if ($limit !== null) {
|
||||
$qb->setMaxResults($limit);
|
||||
}
|
||||
if ($offset !== null) {
|
||||
$qb->setFirstResult($offset);
|
||||
}
|
||||
$sharedEntries = $this->findEntities($qb);
|
||||
foreach ($sharedEntries as $entry) {
|
||||
$entry->setShared(1);
|
||||
}
|
||||
$entries = array_merge($entries, $sharedEntries);
|
||||
$entries = $this->findEntities($sql, [$userId, $since, $userId, Acl::PERMISSION_TYPE_USER, $userId, $since], $limit, $offset);
|
||||
/* @var Board $entry */
|
||||
foreach ($entries as $entry) {
|
||||
$acl = $this->aclMapper->findAll($entry->id);
|
||||
@@ -232,19 +142,9 @@ class BoardMapper extends QBMapper implements IPermissionMapper {
|
||||
return $entries;
|
||||
}
|
||||
|
||||
public function findAllByOwner(string $userId, ?int $limit = null, ?int $offset = null) {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->select('*')
|
||||
->from('deck_boards')
|
||||
->where($qb->expr()->eq('owner', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)))
|
||||
->orderBy('id');
|
||||
if ($limit !== null) {
|
||||
$qb->setMaxResults($limit);
|
||||
}
|
||||
if ($offset !== null) {
|
||||
$qb->setFirstResult($offset);
|
||||
}
|
||||
return $this->findEntities($qb);
|
||||
public function findAllByOwner(string $userId, int $limit = null, int $offset = null) {
|
||||
$sql = 'SELECT * FROM `*PREFIX*deck_boards` WHERE owner = ?';
|
||||
return $this->findEntities($sql, [$userId], $limit, $offset);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -256,57 +156,23 @@ class BoardMapper extends QBMapper implements IPermissionMapper {
|
||||
* @param null $offset
|
||||
* @return array
|
||||
*/
|
||||
public function findAllByGroups(string $userId, array $groups, ?int $limit = null, ?int $offset = null, ?int $since = null,
|
||||
bool $includeArchived = true, ?int $before = null, ?string $term = null) {
|
||||
public function findAllByGroups($userId, $groups, $limit = null, $offset = null, $since = -1,$includeArchived = true) {
|
||||
if (count($groups) <= 0) {
|
||||
return [];
|
||||
}
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->select('b.id', 'title', 'owner', 'color', 'archived', 'deleted_at', 'last_modified')
|
||||
//->selectAlias('2', 'shared')
|
||||
->from('deck_boards', 'b')
|
||||
->innerJoin('b', 'deck_board_acl', 'acl', $qb->expr()->eq('b.id', 'acl.board_id'))
|
||||
->where($qb->expr()->eq('acl.type', $qb->createNamedParameter(Acl::PERMISSION_TYPE_GROUP, IQueryBuilder::PARAM_INT)))
|
||||
->andWhere($qb->expr()->neq('b.owner', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)));
|
||||
$or = $qb->expr()->orx();
|
||||
$sql = 'SELECT boards.id, title, owner, color, archived, deleted_at, 2 as shared, last_modified FROM `*PREFIX*deck_boards` as boards ' .
|
||||
'INNER JOIN `*PREFIX*deck_board_acl` as acl ON boards.id=acl.board_id WHERE owner != ? AND type=? AND (';
|
||||
for ($i = 0, $iMax = count($groups); $i < $iMax; $i++) {
|
||||
$or->add(
|
||||
$qb->expr()->eq('acl.participant', $qb->createNamedParameter($groups[$i], IQueryBuilder::PARAM_STR))
|
||||
);
|
||||
$sql .= 'acl.participant = ? ';
|
||||
if (count($groups) > 1 && $i < count($groups) - 1) {
|
||||
$sql .= ' OR ';
|
||||
}
|
||||
}
|
||||
$qb->andWhere($or);
|
||||
$sql .= ')';
|
||||
if (!$includeArchived) {
|
||||
$qb->andWhere($qb->expr()->eq('archived', $qb->createNamedParameter(false, IQueryBuilder::PARAM_BOOL)))
|
||||
->andWhere($qb->expr()->eq('deleted_at', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT)));
|
||||
}
|
||||
if ($since !== null) {
|
||||
$qb->andWhere($qb->expr()->gt('last_modified', $qb->createNamedParameter($since, IQueryBuilder::PARAM_INT)));
|
||||
}
|
||||
if ($before !== null) {
|
||||
$qb->andWhere($qb->expr()->lt('last_modified', $qb->createNamedParameter($before, IQueryBuilder::PARAM_INT)));
|
||||
}
|
||||
if ($term !== null) {
|
||||
$qb->andWhere(
|
||||
$qb->expr()->iLike(
|
||||
'title',
|
||||
$qb->createNamedParameter(
|
||||
'%' . $this->db->escapeLikeParameter($term) . '%',
|
||||
IQueryBuilder::PARAM_STR
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
$qb->orderBy('b.id');
|
||||
if ($limit !== null) {
|
||||
$qb->setMaxResults($limit);
|
||||
}
|
||||
if ($offset !== null) {
|
||||
$qb->setFirstResult($offset);
|
||||
}
|
||||
$entries = $this->findEntities($qb);
|
||||
foreach ($entries as $entry) {
|
||||
$entry->setShared(2);
|
||||
$sql .= ' AND NOT archived AND deleted_at = 0';
|
||||
}
|
||||
$entries = $this->findEntities($sql, array_merge([$userId, Acl::PERMISSION_TYPE_GROUP], $groups), $limit, $offset);
|
||||
/* @var Board $entry */
|
||||
foreach ($entries as $entry) {
|
||||
$acl = $this->aclMapper->findAll($entry->id);
|
||||
@@ -315,59 +181,25 @@ class BoardMapper extends QBMapper implements IPermissionMapper {
|
||||
return $entries;
|
||||
}
|
||||
|
||||
public function findAllByCircles(string $userId, ?int $limit = null, ?int $offset = null, ?int $since = null,
|
||||
bool $includeArchived = true, ?int $before = null, ?string $term = null) {
|
||||
public function findAllByCircles($userId, $limit = null, $offset = null, $since = -1,$includeArchived = true) {
|
||||
$circles = $this->circlesService->getUserCircles($userId);
|
||||
if (count($circles) === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->select('b.id', 'title', 'owner', 'color', 'archived', 'deleted_at', 'last_modified')
|
||||
//->selectAlias('2', 'shared')
|
||||
->from('deck_boards', 'b')
|
||||
->innerJoin('b', 'deck_board_acl', 'acl', $qb->expr()->eq('b.id', 'acl.board_id'))
|
||||
->where($qb->expr()->eq('acl.type', $qb->createNamedParameter(Acl::PERMISSION_TYPE_CIRCLE, IQueryBuilder::PARAM_INT)))
|
||||
->andWhere($qb->expr()->neq('b.owner', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)));
|
||||
$or = $qb->expr()->orx();
|
||||
$sql = 'SELECT boards.id, title, owner, color, archived, deleted_at, 2 as shared, last_modified FROM `*PREFIX*deck_boards` as boards ' .
|
||||
'INNER JOIN `*PREFIX*deck_board_acl` as acl ON boards.id=acl.board_id WHERE owner != ? AND type=? AND (';
|
||||
for ($i = 0, $iMax = count($circles); $i < $iMax; $i++) {
|
||||
$or->add(
|
||||
$qb->expr()->eq('acl.participant', $qb->createNamedParameter($circles[$i], IQueryBuilder::PARAM_STR))
|
||||
);
|
||||
$sql .= 'acl.participant = ? ';
|
||||
if (count($circles) > 1 && $i < count($circles) - 1) {
|
||||
$sql .= ' OR ';
|
||||
}
|
||||
}
|
||||
$qb->andWhere($or);
|
||||
$sql .= ')';
|
||||
if (!$includeArchived) {
|
||||
$qb->andWhere($qb->expr()->eq('archived', $qb->createNamedParameter(false, IQueryBuilder::PARAM_BOOL)))
|
||||
->andWhere($qb->expr()->eq('deleted_at', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT)));
|
||||
}
|
||||
if ($since !== null) {
|
||||
$qb->andWhere($qb->expr()->gt('last_modified', $qb->createNamedParameter($since, IQueryBuilder::PARAM_INT)));
|
||||
}
|
||||
if ($before !== null) {
|
||||
$qb->andWhere($qb->expr()->lt('last_modified', $qb->createNamedParameter($before, IQueryBuilder::PARAM_INT)));
|
||||
}
|
||||
if ($term !== null) {
|
||||
$qb->andWhere(
|
||||
$qb->expr()->iLike(
|
||||
'title',
|
||||
$qb->createNamedParameter(
|
||||
'%' . $this->db->escapeLikeParameter($term) . '%',
|
||||
IQueryBuilder::PARAM_STR
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
$qb->orderBy('b.id');
|
||||
if ($limit !== null) {
|
||||
$qb->setMaxResults($limit);
|
||||
}
|
||||
if ($offset !== null) {
|
||||
$qb->setFirstResult($offset);
|
||||
}
|
||||
$entries = $this->findEntities($qb);
|
||||
foreach ($entries as $entry) {
|
||||
$entry->setShared(2);
|
||||
$sql .= ' AND NOT archived AND deleted_at = 0';
|
||||
}
|
||||
$entries = $this->findEntities($sql, array_merge([$userId, Acl::PERMISSION_TYPE_CIRCLE], $circles), $limit, $offset);
|
||||
/* @var Board $entry */
|
||||
foreach ($entries as $entry) {
|
||||
$acl = $this->aclMapper->findAll($entry->id);
|
||||
@@ -376,26 +208,21 @@ class BoardMapper extends QBMapper implements IPermissionMapper {
|
||||
return $entries;
|
||||
}
|
||||
|
||||
public function findAll(): array {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->select('id')
|
||||
->from('deck_boards');
|
||||
return $this->findEntities($qb);
|
||||
public function findAll() {
|
||||
$sql = 'SELECT id from *PREFIX*deck_boards;';
|
||||
return $this->findEntities($sql);
|
||||
}
|
||||
|
||||
public function findToDelete() {
|
||||
// add buffer of 5 min
|
||||
$timeLimit = time() - (60 * 5);
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->select('id', 'title', 'owner', 'color', 'archived', 'deleted_at', 'last_modified')
|
||||
->from('deck_boards')
|
||||
->where($qb->expr()->gt('deleted_at', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT)))
|
||||
->andWhere($qb->expr()->lt('deleted_at', $qb->createNamedParameter($timeLimit, IQueryBuilder::PARAM_INT)));
|
||||
return $this->findEntities($qb);
|
||||
$sql = 'SELECT id, title, owner, color, archived, deleted_at, last_modified FROM `*PREFIX*deck_boards` ' .
|
||||
'WHERE `deleted_at` > 0 AND `deleted_at` < ?';
|
||||
return $this->findEntities($sql, [$timeLimit]);
|
||||
}
|
||||
|
||||
public function delete(/** @noinspection PhpUnnecessaryFullyQualifiedNameInspection */
|
||||
\OCP\AppFramework\Db\Entity $entity): \OCP\AppFramework\Db\Entity {
|
||||
\OCP\AppFramework\Db\Entity $entity) {
|
||||
// delete acl
|
||||
$acl = $this->aclMapper->findAll($entity->getId());
|
||||
foreach ($acl as $item) {
|
||||
@@ -496,11 +323,6 @@ class BoardMapper extends QBMapper implements IPermissionMapper {
|
||||
* Reset cache for a given board or a given user
|
||||
*/
|
||||
public function flushCache(?int $boardId = null, ?string $userId = null) {
|
||||
if ($boardId) {
|
||||
unset($this->boardCache[$boardId]);
|
||||
} else {
|
||||
$this->boardCache = null;
|
||||
}
|
||||
if ($userId) {
|
||||
unset($this->userBoardCache[$userId]);
|
||||
} else {
|
||||
|
||||
@@ -30,8 +30,6 @@ use OCA\Deck\Search\Query\SearchQuery;
|
||||
use OCP\AppFramework\Db\Entity;
|
||||
use OCP\AppFramework\Db\QBMapper;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\ICache;
|
||||
use OCP\ICacheFactory;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\IGroupManager;
|
||||
use OCP\IUser;
|
||||
@@ -48,8 +46,6 @@ class CardMapper extends QBMapper implements IPermissionMapper {
|
||||
private $groupManager;
|
||||
/** @var IManager */
|
||||
private $notificationManager;
|
||||
/** @var ICache */
|
||||
private $cache;
|
||||
private $databaseType;
|
||||
private $database4ByteSupport;
|
||||
|
||||
@@ -59,7 +55,6 @@ class CardMapper extends QBMapper implements IPermissionMapper {
|
||||
IUserManager $userManager,
|
||||
IGroupManager $groupManager,
|
||||
IManager $notificationManager,
|
||||
ICacheFactory $cacheFactory,
|
||||
$databaseType = 'sqlite3',
|
||||
$database4ByteSupport = true
|
||||
) {
|
||||
@@ -68,7 +63,6 @@ class CardMapper extends QBMapper implements IPermissionMapper {
|
||||
$this->userManager = $userManager;
|
||||
$this->groupManager = $groupManager;
|
||||
$this->notificationManager = $notificationManager;
|
||||
$this->cache = $cacheFactory->createDistributed('deck-cardMapper');
|
||||
$this->databaseType = $databaseType;
|
||||
$this->database4ByteSupport = $database4ByteSupport;
|
||||
}
|
||||
@@ -81,9 +75,7 @@ class CardMapper extends QBMapper implements IPermissionMapper {
|
||||
$description = preg_replace('/[\x{10000}-\x{10FFFF}]/u', "\xEF\xBF\xBD", $entity->getDescription());
|
||||
$entity->setDescription($description);
|
||||
}
|
||||
$entity = parent::insert($entity);
|
||||
$this->cache->remove('findBoardId:' . $entity->getId());
|
||||
return $entity;
|
||||
return parent::insert($entity);
|
||||
}
|
||||
|
||||
public function update(Entity $entity, $updateModified = true): Entity {
|
||||
@@ -115,10 +107,6 @@ class CardMapper extends QBMapper implements IPermissionMapper {
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
}
|
||||
// Invalidate cache when the card may be moved to a different board
|
||||
if (isset($updatedFields['stackId'])) {
|
||||
$this->cache->remove('findBoardId:' . $entity->getId());
|
||||
}
|
||||
return parent::update($entity);
|
||||
}
|
||||
|
||||
@@ -193,7 +181,6 @@ class CardMapper extends QBMapper implements IPermissionMapper {
|
||||
->from('deck_cards', 'c')
|
||||
->join('c', 'deck_stacks', 's', 's.id = c.stack_id')
|
||||
->where($qb->expr()->eq('s.board_id', $qb->createNamedParameter($boardId)))
|
||||
->andWhere($qb->expr()->eq('c.archived', $qb->createNamedParameter(false, IQueryBuilder::PARAM_BOOL)))
|
||||
->andWhere($qb->expr()->eq('c.deleted_at', $qb->createNamedParameter('0')))
|
||||
->orderBy('c.duedate')
|
||||
->setMaxResults($limit)
|
||||
@@ -492,8 +479,8 @@ class CardMapper extends QBMapper implements IPermissionMapper {
|
||||
}
|
||||
return $qb->createNamedParameter($dateTime, IQueryBuilder::PARAM_DATE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public function searchRaw($boardIds, $term, $limit = null, $offset = null) {
|
||||
$qb = $this->queryCardsByBoards($boardIds)
|
||||
@@ -519,8 +506,9 @@ class CardMapper extends QBMapper implements IPermissionMapper {
|
||||
}
|
||||
|
||||
public function delete(Entity $entity): Entity {
|
||||
// delete assigned labels
|
||||
$this->labelMapper->deleteLabelAssignmentsForCard($entity->getId());
|
||||
$this->cache->remove('findBoardId:' . $entity->getId());
|
||||
// delete card
|
||||
return parent::delete($entity);
|
||||
}
|
||||
|
||||
@@ -559,22 +547,11 @@ class CardMapper extends QBMapper implements IPermissionMapper {
|
||||
}
|
||||
|
||||
public function findBoardId($id): ?int {
|
||||
$result = $this->cache->get('findBoardId:' . $id);
|
||||
if ($result === null) {
|
||||
try {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->select('board_id')
|
||||
->from('deck_stacks', 's')
|
||||
->innerJoin('s', 'deck_cards', 'c', 'c.stack_id = s.id')
|
||||
->where($qb->expr()->eq('c.id', $qb->createNamedParameter($id)));
|
||||
$queryResult = $qb->executeQuery();
|
||||
$result = $queryResult->fetchOne();
|
||||
} catch (\Exception $e) {
|
||||
$result = false;
|
||||
}
|
||||
$this->cache->set('findBoardId:' . $id, $result);
|
||||
}
|
||||
return $result !== false ? $result : null;
|
||||
$sql = 'SELECT id FROM `*PREFIX*deck_boards` WHERE `id` IN (SELECT board_id FROM `*PREFIX*deck_stacks` WHERE id IN (SELECT stack_id FROM `*PREFIX*deck_cards` WHERE id = ?))';
|
||||
$stmt = $this->db->prepare($sql);
|
||||
$stmt->bindParam(1, $id, \PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
return $stmt->fetchColumn() ?? null;
|
||||
}
|
||||
|
||||
public function mapOwner(Card &$card) {
|
||||
|
||||
@@ -35,7 +35,6 @@ use OCA\Deck\Event\CardUpdatedEvent;
|
||||
use OCA\Deck\NoPermissionException;
|
||||
use OCA\Deck\NotFoundException;
|
||||
use OCA\Deck\Notification\NotificationHelper;
|
||||
use OCA\Deck\Validators\AssignmentServiceValidator;
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
use OCP\AppFramework\Db\Entity;
|
||||
use OCP\AppFramework\Db\MultipleObjectsReturnedException;
|
||||
@@ -77,11 +76,6 @@ class AssignmentService {
|
||||
private $eventDispatcher;
|
||||
/** @var string|null */
|
||||
private $currentUser;
|
||||
/**
|
||||
* @var AssignmentServiceValidator
|
||||
*/
|
||||
private $assignmentServiceValidator;
|
||||
|
||||
|
||||
public function __construct(
|
||||
PermissionService $permissionService,
|
||||
@@ -92,10 +86,8 @@ class AssignmentService {
|
||||
ActivityManager $activityManager,
|
||||
ChangeHelper $changeHelper,
|
||||
IEventDispatcher $eventDispatcher,
|
||||
AssignmentServiceValidator $assignmentServiceValidator,
|
||||
$userId
|
||||
) {
|
||||
$this->assignmentServiceValidator = $assignmentServiceValidator;
|
||||
$this->permissionService = $permissionService;
|
||||
$this->cardMapper = $cardMapper;
|
||||
$this->assignedUsersMapper = $assignedUsersMapper;
|
||||
@@ -104,8 +96,6 @@ class AssignmentService {
|
||||
$this->changeHelper = $changeHelper;
|
||||
$this->activityManager = $activityManager;
|
||||
$this->eventDispatcher = $eventDispatcher;
|
||||
|
||||
$this->assignmentServiceValidator->check(compact('userId'));
|
||||
$this->currentUser = $userId;
|
||||
}
|
||||
|
||||
@@ -119,7 +109,13 @@ class AssignmentService {
|
||||
* @throws DoesNotExistException
|
||||
*/
|
||||
public function assignUser($cardId, $userId, int $type = Assignment::TYPE_USER) {
|
||||
$this->assignmentServiceValidator->check(compact('cardId', 'userId'));
|
||||
if (is_numeric($cardId) === false) {
|
||||
throw new BadRequestException('card id must be a number');
|
||||
}
|
||||
|
||||
if ($userId === false || $userId === null) {
|
||||
throw new BadRequestException('user id must be provided');
|
||||
}
|
||||
|
||||
if ($type !== Assignment::TYPE_USER && $type !== Assignment::TYPE_GROUP) {
|
||||
throw new BadRequestException('Invalid type provided for assignemnt');
|
||||
@@ -172,9 +168,16 @@ class AssignmentService {
|
||||
* @throws MultipleObjectsReturnedException
|
||||
*/
|
||||
public function unassignUser($cardId, $userId, $type = 0) {
|
||||
$this->assignmentServiceValidator->check(compact('cardId', 'userId'));
|
||||
$this->permissionService->checkPermission($this->cardMapper, $cardId, Acl::PERMISSION_EDIT);
|
||||
|
||||
if (is_numeric($cardId) === false) {
|
||||
throw new BadRequestException('card id must be a number');
|
||||
}
|
||||
|
||||
if ($userId === false || $userId === null) {
|
||||
throw new BadRequestException('user must be provided');
|
||||
}
|
||||
|
||||
$assignments = $this->assignedUsersMapper->findAll($cardId);
|
||||
foreach ($assignments as $assignment) {
|
||||
if ($assignment->getParticipant() === $userId && $assignment->getType() === $type) {
|
||||
|
||||
@@ -36,7 +36,6 @@ use OCA\Deck\NoPermissionException;
|
||||
use OCA\Deck\NotFoundException;
|
||||
use OCA\Deck\Cache\AttachmentCacheHelper;
|
||||
use OCA\Deck\StatusException;
|
||||
use OCA\Deck\Validators\AttachmentServiceValidator;
|
||||
use OCP\AppFramework\Db\IMapperException;
|
||||
use OCP\AppFramework\Http\Response;
|
||||
use OCP\IL10N;
|
||||
@@ -59,10 +58,8 @@ class AttachmentService {
|
||||
private $activityManager;
|
||||
/** @var ChangeHelper */
|
||||
private $changeHelper;
|
||||
/** @var AttachmentServiceValidator */
|
||||
private $attachmentServiceValidator;
|
||||
|
||||
public function __construct(AttachmentMapper $attachmentMapper, CardMapper $cardMapper, ChangeHelper $changeHelper, PermissionService $permissionService, Application $application, AttachmentCacheHelper $attachmentCacheHelper, $userId, IL10N $l10n, ActivityManager $activityManager, AttachmentServiceValidator $attachmentServiceValidator) {
|
||||
public function __construct(AttachmentMapper $attachmentMapper, CardMapper $cardMapper, ChangeHelper $changeHelper, PermissionService $permissionService, Application $application, AttachmentCacheHelper $attachmentCacheHelper, $userId, IL10N $l10n, ActivityManager $activityManager) {
|
||||
$this->attachmentMapper = $attachmentMapper;
|
||||
$this->cardMapper = $cardMapper;
|
||||
$this->permissionService = $permissionService;
|
||||
@@ -72,7 +69,6 @@ class AttachmentService {
|
||||
$this->l10n = $l10n;
|
||||
$this->activityManager = $activityManager;
|
||||
$this->changeHelper = $changeHelper;
|
||||
$this->attachmentServiceValidator = $attachmentServiceValidator;
|
||||
|
||||
// Register shipped attachment services
|
||||
// TODO: move this to a plugin based approach once we have different types of attachments
|
||||
@@ -178,7 +174,17 @@ class AttachmentService {
|
||||
* @throws BadRequestException
|
||||
*/
|
||||
public function create($cardId, $type, $data) {
|
||||
$this->attachmentServiceValidator->check(compact('cardId', 'type'));
|
||||
if (is_numeric($cardId) === false) {
|
||||
throw new BadRequestException('card id must be a number');
|
||||
}
|
||||
|
||||
if ($type === false || $type === null) {
|
||||
throw new BadRequestException('type must be provided');
|
||||
}
|
||||
|
||||
if ($data === false || $data === null) {
|
||||
//throw new BadRequestException('data must be provided');
|
||||
}
|
||||
|
||||
$this->permissionService->checkPermission($this->cardMapper, $cardId, Acl::PERMISSION_EDIT);
|
||||
|
||||
@@ -263,8 +269,6 @@ class AttachmentService {
|
||||
* @throws NoPermissionException
|
||||
*/
|
||||
public function update($cardId, $attachmentId, $data, $type = 'deck_file') {
|
||||
$this->attachmentServiceValidator->check(compact('cardId', 'type', 'data'));
|
||||
|
||||
try {
|
||||
$service = $this->getService($type);
|
||||
} catch (InvalidAttachmentType $e) {
|
||||
@@ -286,6 +290,9 @@ class AttachmentService {
|
||||
}
|
||||
}
|
||||
|
||||
if ($data === false || $data === null) {
|
||||
//throw new BadRequestException('data must be provided');
|
||||
}
|
||||
try {
|
||||
$attachment = $this->attachmentMapper->find($attachmentId);
|
||||
} catch (\Exception $e) {
|
||||
|
||||
@@ -52,7 +52,6 @@ use OCA\Deck\Db\BoardMapper;
|
||||
use OCA\Deck\Db\LabelMapper;
|
||||
use OCP\IUserManager;
|
||||
use OCA\Deck\BadRequestException;
|
||||
use OCA\Deck\Validators\BoardServiceValidator;
|
||||
use OCP\IURLGenerator;
|
||||
|
||||
class BoardService {
|
||||
@@ -76,7 +75,6 @@ class BoardService {
|
||||
|
||||
private $boardsCache = null;
|
||||
private $urlGenerator;
|
||||
private $boardServiceValidator;
|
||||
|
||||
|
||||
public function __construct(
|
||||
@@ -96,7 +94,6 @@ class BoardService {
|
||||
IEventDispatcher $eventDispatcher,
|
||||
ChangeHelper $changeHelper,
|
||||
IURLGenerator $urlGenerator,
|
||||
BoardServiceValidator $boardServiceValidator,
|
||||
$userId
|
||||
) {
|
||||
$this->boardMapper = $boardMapper;
|
||||
@@ -116,7 +113,6 @@ class BoardService {
|
||||
$this->userId = $userId;
|
||||
$this->urlGenerator = $urlGenerator;
|
||||
$this->cardMapper = $cardMapper;
|
||||
$this->boardServiceValidator = $boardServiceValidator;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -126,15 +122,13 @@ class BoardService {
|
||||
*/
|
||||
public function setUserId(string $userId): void {
|
||||
$this->userId = $userId;
|
||||
$this->permissionService->setUserId($userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all boards that are shared with a user, their groups or circles
|
||||
*/
|
||||
public function getUserBoards(?int $since = null, bool $includeArchived = true, ?int $before = null,
|
||||
?string $term = null): array {
|
||||
return $this->boardMapper->findAllForUser($this->userId, $since, $includeArchived, $before, $term);
|
||||
public function getUserBoards(int $since = -1, bool $includeArchived = true): array {
|
||||
return $this->boardMapper->findAllForUser($this->userId, $since, $includeArchived);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -181,8 +175,7 @@ class BoardService {
|
||||
* @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException
|
||||
* @throws BadRequestException
|
||||
*/
|
||||
public function find($boardId, bool $allowDeleted = false) {
|
||||
$this->boardServiceValidator->check(compact('boardId'));
|
||||
public function find($boardId) {
|
||||
if ($this->boardsCache && isset($this->boardsCache[$boardId])) {
|
||||
return $this->boardsCache[$boardId];
|
||||
}
|
||||
@@ -192,13 +185,11 @@ class BoardService {
|
||||
|
||||
$this->permissionService->checkPermission($this->boardMapper, $boardId, Acl::PERMISSION_READ);
|
||||
/** @var Board $board */
|
||||
$board = $this->boardMapper->find((int)$boardId, true, true, $allowDeleted);
|
||||
$board = $this->boardMapper->find($boardId, true, true);
|
||||
$this->boardMapper->mapOwner($board);
|
||||
if ($board->getAcl() !== null) {
|
||||
foreach ($board->getAcl() as $acl) {
|
||||
if ($acl !== null) {
|
||||
$this->boardMapper->mapAcl($acl);
|
||||
}
|
||||
foreach ($board->getAcl() as &$acl) {
|
||||
if ($acl !== null) {
|
||||
$this->boardMapper->mapAcl($acl);
|
||||
}
|
||||
}
|
||||
$permissions = $this->permissionService->matchPermissions($board);
|
||||
@@ -237,7 +228,9 @@ class BoardService {
|
||||
* @throws BadRequestException
|
||||
*/
|
||||
public function isArchived($mapper, $id) {
|
||||
$this->boardServiceValidator->check(compact('id'));
|
||||
if (is_numeric($id) === false) {
|
||||
throw new BadRequestException('id must be a number');
|
||||
}
|
||||
|
||||
try {
|
||||
$boardId = $id;
|
||||
@@ -264,7 +257,13 @@ class BoardService {
|
||||
* @throws BadRequestException
|
||||
*/
|
||||
public function isDeleted($mapper, $id) {
|
||||
$this->boardServiceValidator->check(compact('mapper', 'id'));
|
||||
if ($mapper === false || $mapper === null) {
|
||||
throw new BadRequestException('mapper must be provided');
|
||||
}
|
||||
|
||||
if (is_numeric($id) === false) {
|
||||
throw new BadRequestException('id must be a number');
|
||||
}
|
||||
|
||||
try {
|
||||
$boardId = $id;
|
||||
@@ -290,7 +289,17 @@ class BoardService {
|
||||
* @throws BadRequestException
|
||||
*/
|
||||
public function create($title, $userId, $color) {
|
||||
$this->boardServiceValidator->check(compact('title', 'userId', 'color'));
|
||||
if ($title === false || $title === null) {
|
||||
throw new BadRequestException('title must be provided');
|
||||
}
|
||||
|
||||
if ($userId === false || $userId === null) {
|
||||
throw new BadRequestException('userId must be provided');
|
||||
}
|
||||
|
||||
if ($color === false || $color === null) {
|
||||
throw new BadRequestException('color must be provided');
|
||||
}
|
||||
|
||||
if (!$this->permissionService->canCreate()) {
|
||||
throw new NoPermissionException('Creating boards has been disabled for your account.');
|
||||
@@ -341,7 +350,9 @@ class BoardService {
|
||||
* @throws BadRequestException
|
||||
*/
|
||||
public function delete($id) {
|
||||
$this->boardServiceValidator->check(compact('id'));
|
||||
if (is_numeric($id) === false) {
|
||||
throw new BadRequestException('board id must be a number');
|
||||
}
|
||||
|
||||
$this->permissionService->checkPermission($this->boardMapper, $id, Acl::PERMISSION_MANAGE);
|
||||
$board = $this->find($id);
|
||||
@@ -364,10 +375,12 @@ class BoardService {
|
||||
* @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException
|
||||
*/
|
||||
public function deleteUndo($id) {
|
||||
$this->boardServiceValidator->check(compact('id'));
|
||||
if (is_numeric($id) === false) {
|
||||
throw new BadRequestException('board id must be a number');
|
||||
}
|
||||
|
||||
$this->permissionService->checkPermission($this->boardMapper, $id, Acl::PERMISSION_MANAGE);
|
||||
$board = $this->find($id, true);
|
||||
$board = $this->find($id);
|
||||
$board->setDeletedAt(0);
|
||||
$board = $this->boardMapper->update($board);
|
||||
$this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_BOARD, $board, ActivityManager::SUBJECT_BOARD_RESTORE);
|
||||
@@ -385,10 +398,12 @@ class BoardService {
|
||||
* @throws BadRequestException
|
||||
*/
|
||||
public function deleteForce($id) {
|
||||
$this->boardServiceValidator->check(compact('id'));
|
||||
if (is_numeric($id) === false) {
|
||||
throw new BadRequestException('id must be a number');
|
||||
}
|
||||
|
||||
$this->permissionService->checkPermission($this->boardMapper, $id, Acl::PERMISSION_MANAGE);
|
||||
$board = $this->find($id, true);
|
||||
$board = $this->find($id);
|
||||
$delete = $this->boardMapper->delete($board);
|
||||
|
||||
return $delete;
|
||||
@@ -406,7 +421,21 @@ class BoardService {
|
||||
* @throws BadRequestException
|
||||
*/
|
||||
public function update($id, $title, $color, $archived) {
|
||||
$this->boardServiceValidator->check(compact('id', 'title', 'color', 'archived'));
|
||||
if (is_numeric($id) === false) {
|
||||
throw new BadRequestException('board id must be a number');
|
||||
}
|
||||
|
||||
if ($title === false || $title === null) {
|
||||
throw new BadRequestException('title must be provided');
|
||||
}
|
||||
|
||||
if ($color === false || $color === null) {
|
||||
throw new BadRequestException('color must be provided');
|
||||
}
|
||||
|
||||
if (is_bool($archived) === false) {
|
||||
throw new BadRequestException('archived must be a boolean');
|
||||
}
|
||||
|
||||
$this->permissionService->checkPermission($this->boardMapper, $id, Acl::PERMISSION_MANAGE);
|
||||
$board = $this->find($id);
|
||||
@@ -456,7 +485,29 @@ class BoardService {
|
||||
* @throws \OCA\Deck\NoPermissionException
|
||||
*/
|
||||
public function addAcl($boardId, $type, $participant, $edit, $share, $manage) {
|
||||
$this->boardServiceValidator->check(compact('boardId', 'type', 'participant', 'edit', 'share', 'manage'));
|
||||
if (is_numeric($boardId) === false) {
|
||||
throw new BadRequestException('board id must be a number');
|
||||
}
|
||||
|
||||
if ($type === false || $type === null) {
|
||||
throw new BadRequestException('type must be provided');
|
||||
}
|
||||
|
||||
if ($participant === false || $participant === null) {
|
||||
throw new BadRequestException('participant must be provided');
|
||||
}
|
||||
|
||||
if ($edit === null) {
|
||||
throw new BadRequestException('edit must be provided');
|
||||
}
|
||||
|
||||
if ($share === null) {
|
||||
throw new BadRequestException('share must be provided');
|
||||
}
|
||||
|
||||
if ($manage === null) {
|
||||
throw new BadRequestException('manage must be provided');
|
||||
}
|
||||
|
||||
$this->permissionService->checkPermission($this->boardMapper, $boardId, Acl::PERMISSION_SHARE);
|
||||
[$edit, $share, $manage] = $this->applyPermissions($boardId, $edit, $share, $manage);
|
||||
@@ -471,7 +522,7 @@ class BoardService {
|
||||
$newAcl = $this->aclMapper->insert($acl);
|
||||
|
||||
$this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_BOARD, $newAcl, ActivityManager::SUBJECT_BOARD_SHARE, [], $this->userId);
|
||||
$this->notificationHelper->sendBoardShared($boardId, $acl);
|
||||
$this->notificationHelper->sendBoardShared((int)$boardId, $acl);
|
||||
$this->boardMapper->mapAcl($newAcl);
|
||||
$this->changeHelper->boardChanged($boardId);
|
||||
|
||||
@@ -502,7 +553,21 @@ class BoardService {
|
||||
* @throws BadRequestException
|
||||
*/
|
||||
public function updateAcl($id, $edit, $share, $manage) {
|
||||
$this->boardServiceValidator->check(compact('id', 'edit', 'share', 'manage'));
|
||||
if (is_numeric($id) === false) {
|
||||
throw new BadRequestException('id must be a number');
|
||||
}
|
||||
|
||||
if ($edit === null) {
|
||||
throw new BadRequestException('edit must be provided');
|
||||
}
|
||||
|
||||
if ($share === null) {
|
||||
throw new BadRequestException('share must be provided');
|
||||
}
|
||||
|
||||
if ($manage === null) {
|
||||
throw new BadRequestException('manage must be provided');
|
||||
}
|
||||
|
||||
$this->permissionService->checkPermission($this->aclMapper, $id, Acl::PERMISSION_SHARE);
|
||||
|
||||
@@ -574,7 +639,9 @@ class BoardService {
|
||||
* @throws BadRequestException
|
||||
*/
|
||||
public function clone($id, $userId) {
|
||||
$this->boardServiceValidator->check(compact('id', 'userId'));
|
||||
if (is_numeric($id) === false) {
|
||||
throw new BadRequestException('board id must be a number');
|
||||
}
|
||||
|
||||
$this->permissionService->checkPermission($this->boardMapper, $id, Acl::PERMISSION_READ);
|
||||
|
||||
|
||||
@@ -43,7 +43,6 @@ use OCA\Deck\Db\BoardMapper;
|
||||
use OCA\Deck\Db\LabelMapper;
|
||||
use OCA\Deck\StatusException;
|
||||
use OCA\Deck\BadRequestException;
|
||||
use OCA\Deck\Validators\CardServiceValidator;
|
||||
use OCP\Comments\ICommentsManager;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use OCP\IUserManager;
|
||||
@@ -66,7 +65,6 @@ class CardService {
|
||||
private $eventDispatcher;
|
||||
private $userManager;
|
||||
private $urlGenerator;
|
||||
private $cardServiceValidator;
|
||||
|
||||
public function __construct(
|
||||
CardMapper $cardMapper,
|
||||
@@ -84,7 +82,6 @@ class CardService {
|
||||
ChangeHelper $changeHelper,
|
||||
IEventDispatcher $eventDispatcher,
|
||||
IURLGenerator $urlGenerator,
|
||||
CardServiceValidator $cardServiceValidator,
|
||||
$userId
|
||||
) {
|
||||
$this->cardMapper = $cardMapper;
|
||||
@@ -103,7 +100,6 @@ class CardService {
|
||||
$this->eventDispatcher = $eventDispatcher;
|
||||
$this->currentUser = $userId;
|
||||
$this->urlGenerator = $urlGenerator;
|
||||
$this->cardServiceValidator = $cardServiceValidator;
|
||||
}
|
||||
|
||||
public function enrich($card) {
|
||||
@@ -126,7 +122,6 @@ class CardService {
|
||||
}
|
||||
|
||||
public function fetchDeleted($boardId) {
|
||||
$this->cardServiceValidator->check(compact('boardId'));
|
||||
$this->permissionService->checkPermission($this->boardMapper, $boardId, Acl::PERMISSION_READ);
|
||||
$cards = $this->cardMapper->findDeleted($boardId);
|
||||
foreach ($cards as $card) {
|
||||
@@ -192,7 +187,29 @@ class CardService {
|
||||
* @throws BadrequestException
|
||||
*/
|
||||
public function create($title, $stackId, $type, $order, $owner, $description = '', $duedate = null) {
|
||||
$this->cardServiceValidator->check(compact('title', 'stackId', 'type', 'order', 'owner'));
|
||||
if ($title === 'false' || $title === null) {
|
||||
throw new BadRequestException('title must be provided');
|
||||
}
|
||||
|
||||
if (mb_strlen($title) > Card::TITLE_MAX_LENGTH) {
|
||||
throw new BadRequestException('The title cannot exceed 255 characters');
|
||||
}
|
||||
|
||||
if (is_numeric($stackId) === false) {
|
||||
throw new BadRequestException('stack id must be a number');
|
||||
}
|
||||
|
||||
if ($type === 'false' || $type === null) {
|
||||
throw new BadRequestException('type must be provided');
|
||||
}
|
||||
|
||||
if (is_numeric($order) === false) {
|
||||
throw new BadRequestException('order must be a number');
|
||||
}
|
||||
|
||||
if ($owner === false || $owner === null) {
|
||||
throw new BadRequestException('owner must be provided');
|
||||
}
|
||||
|
||||
$this->permissionService->checkPermission($this->stackMapper, $stackId, Acl::PERMISSION_EDIT);
|
||||
if ($this->boardService->isArchived($this->stackMapper, $stackId)) {
|
||||
@@ -262,9 +279,31 @@ class CardService {
|
||||
* @throws BadRequestException
|
||||
*/
|
||||
public function update($id, $title, $stackId, $type, $owner, $description = '', $order = 0, $duedate = null, $deletedAt = null, $archived = null) {
|
||||
$this->cardServiceValidator->check(compact('id', 'title', 'stackId', 'type', 'owner', 'order'));
|
||||
if (is_numeric($id) === false) {
|
||||
throw new BadRequestException('card id must be a number');
|
||||
}
|
||||
|
||||
$this->permissionService->checkPermission($this->cardMapper, $id, Acl::PERMISSION_EDIT, null, true);
|
||||
if ($title === false || $title === null) {
|
||||
throw new BadRequestException('title must be provided');
|
||||
}
|
||||
|
||||
if (mb_strlen($title) > Card::TITLE_MAX_LENGTH) {
|
||||
throw new BadRequestException('The title cannot exceed 255 characters');
|
||||
}
|
||||
|
||||
if (is_numeric($stackId) === false) {
|
||||
throw new BadRequestException('stack id must be a number $$$');
|
||||
}
|
||||
|
||||
if ($type === false || $type === null) {
|
||||
throw new BadRequestException('type must be provided');
|
||||
}
|
||||
|
||||
if ($owner === false || $owner === null) {
|
||||
throw new BadRequestException('owner must be provided');
|
||||
}
|
||||
|
||||
$this->permissionService->checkPermission($this->cardMapper, $id, Acl::PERMISSION_EDIT);
|
||||
$this->permissionService->checkPermission($this->stackMapper, $stackId, Acl::PERMISSION_EDIT);
|
||||
|
||||
if ($this->boardService->isArchived($this->cardMapper, $id)) {
|
||||
@@ -274,14 +313,6 @@ class CardService {
|
||||
if ($archived !== null && $card->getArchived() && $archived === true) {
|
||||
throw new StatusException('Operation not allowed. This card is archived.');
|
||||
}
|
||||
|
||||
if ($card->getDeletedAt() !== 0) {
|
||||
if ($deletedAt === null || $deletedAt > 0) {
|
||||
// Only allow operations when restoring the card
|
||||
throw new NoPermissionException('Operation not allowed. This card was deleted.');
|
||||
}
|
||||
}
|
||||
|
||||
$changes = new ChangeSet($card);
|
||||
if ($card->getLastEditor() !== $this->currentUser && $card->getLastEditor() !== null) {
|
||||
$this->activityManager->triggerEvent(
|
||||
@@ -353,7 +384,17 @@ class CardService {
|
||||
* @throws BadRequestException
|
||||
*/
|
||||
public function rename($id, $title) {
|
||||
$this->cardServiceValidator->check(compact('id', 'title'));
|
||||
if (is_numeric($id) === false) {
|
||||
throw new BadRequestException('id must be a number');
|
||||
}
|
||||
|
||||
if ($title === false || $title === null) {
|
||||
throw new BadRequestException('title must be provided');
|
||||
}
|
||||
|
||||
if (mb_strlen($title) > Card::TITLE_MAX_LENGTH) {
|
||||
throw new BadRequestException('The title cannot exceed 255 characters');
|
||||
}
|
||||
|
||||
$this->permissionService->checkPermission($this->cardMapper, $id, Acl::PERMISSION_EDIT);
|
||||
if ($this->boardService->isArchived($this->cardMapper, $id)) {
|
||||
@@ -384,8 +425,17 @@ class CardService {
|
||||
* @throws BadRequestException
|
||||
*/
|
||||
public function reorder($id, $stackId, $order) {
|
||||
$this->cardServiceValidator->check(compact('id', 'stackId', 'order'));
|
||||
if (is_numeric($id) === false) {
|
||||
throw new BadRequestException('card id must be a number');
|
||||
}
|
||||
|
||||
if (is_numeric($stackId) === false) {
|
||||
throw new BadRequestException('stack id must be a number');
|
||||
}
|
||||
|
||||
if (is_numeric($order) === false) {
|
||||
throw new BadRequestException('order must be a number');
|
||||
}
|
||||
|
||||
$this->permissionService->checkPermission($this->cardMapper, $id, Acl::PERMISSION_EDIT);
|
||||
$this->permissionService->checkPermission($this->stackMapper, $stackId, Acl::PERMISSION_EDIT);
|
||||
@@ -440,8 +490,9 @@ class CardService {
|
||||
* @throws BadRequestException
|
||||
*/
|
||||
public function archive($id) {
|
||||
$this->cardServiceValidator->check(compact('id'));
|
||||
|
||||
if (is_numeric($id) === false) {
|
||||
throw new BadRequestException('id must be a number');
|
||||
}
|
||||
|
||||
$this->permissionService->checkPermission($this->cardMapper, $id, Acl::PERMISSION_EDIT);
|
||||
if ($this->boardService->isArchived($this->cardMapper, $id)) {
|
||||
@@ -469,8 +520,9 @@ class CardService {
|
||||
* @throws BadRequestException
|
||||
*/
|
||||
public function unarchive($id) {
|
||||
$this->cardServiceValidator->check(compact('id'));
|
||||
|
||||
if (is_numeric($id) === false) {
|
||||
throw new BadRequestException('id must be a number');
|
||||
}
|
||||
|
||||
$this->permissionService->checkPermission($this->cardMapper, $id, Acl::PERMISSION_EDIT);
|
||||
if ($this->boardService->isArchived($this->cardMapper, $id)) {
|
||||
@@ -497,8 +549,13 @@ class CardService {
|
||||
* @throws BadRequestException
|
||||
*/
|
||||
public function assignLabel($cardId, $labelId) {
|
||||
$this->cardServiceValidator->check(compact('cardId', 'labelId'));
|
||||
if (is_numeric($cardId) === false) {
|
||||
throw new BadRequestException('card id must be a number');
|
||||
}
|
||||
|
||||
if (is_numeric($labelId) === false) {
|
||||
throw new BadRequestException('label id must be a number');
|
||||
}
|
||||
|
||||
$this->permissionService->checkPermission($this->cardMapper, $cardId, Acl::PERMISSION_EDIT);
|
||||
if ($this->boardService->isArchived($this->cardMapper, $cardId)) {
|
||||
@@ -526,8 +583,13 @@ class CardService {
|
||||
* @throws BadRequestException
|
||||
*/
|
||||
public function removeLabel($cardId, $labelId) {
|
||||
$this->cardServiceValidator->check(compact('cardId', 'labelId'));
|
||||
if (is_numeric($cardId) === false) {
|
||||
throw new BadRequestException('card id must be a number');
|
||||
}
|
||||
|
||||
if (is_numeric($labelId) === false) {
|
||||
throw new BadRequestException('label id must be a number');
|
||||
}
|
||||
|
||||
$this->permissionService->checkPermission($this->cardMapper, $cardId, Acl::PERMISSION_EDIT);
|
||||
if ($this->boardService->isArchived($this->cardMapper, $cardId)) {
|
||||
|
||||
@@ -40,8 +40,6 @@ use Throwable;
|
||||
class CirclesService {
|
||||
private $circlesEnabled;
|
||||
|
||||
private $userCircleCache = [];
|
||||
|
||||
public function __construct(IAppManager $appManager) {
|
||||
$this->circlesEnabled = $appManager->isEnabledForUser('circles');
|
||||
}
|
||||
@@ -72,10 +70,6 @@ class CirclesService {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset($this->userCircleCache[$circleId][$userId])) {
|
||||
return $this->userCircleCache[$circleId][$userId];
|
||||
}
|
||||
|
||||
try {
|
||||
/** @var CirclesManager $circlesManager */
|
||||
$circlesManager = \OC::$server->get(CirclesManager::class);
|
||||
@@ -83,14 +77,7 @@ class CirclesService {
|
||||
$circlesManager->startSession($federatedUser);
|
||||
$circle = $circlesManager->getCircle($circleId);
|
||||
$member = $circle->getInitiator();
|
||||
$isUserInCircle = $member !== null && $member->getLevel() >= Member::LEVEL_MEMBER;
|
||||
|
||||
if (!isset($this->userCircleCache[$circleId])) {
|
||||
$this->userCircleCache[$circleId] = [];
|
||||
}
|
||||
$this->userCircleCache[$circleId][$userId] = $isUserInCircle;
|
||||
|
||||
return $isUserInCircle;
|
||||
return $member !== null && $member->getLevel() >= Member::LEVEL_MEMBER;
|
||||
} catch (Throwable $e) {
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -83,17 +83,24 @@ class CommentService {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $cardId
|
||||
* @param string $message
|
||||
* @param string $replyTo
|
||||
* @return DataResponse
|
||||
* @throws BadRequestException
|
||||
* @throws NotFoundException|NoPermissionException
|
||||
*/
|
||||
public function create(int $cardId, string $message, string $replyTo = '0'): DataResponse {
|
||||
public function create(string $cardId, string $message, string $replyTo = '0'): DataResponse {
|
||||
if (!is_numeric($cardId)) {
|
||||
throw new BadRequestException('A valid card id must be provided');
|
||||
}
|
||||
$this->permissionService->checkPermission($this->cardMapper, $cardId, Acl::PERMISSION_READ);
|
||||
|
||||
// Check if parent is a comment on the same card
|
||||
if ($replyTo !== '0') {
|
||||
try {
|
||||
$comment = $this->commentsManager->get($replyTo);
|
||||
if ($comment->getObjectType() !== Application::COMMENT_ENTITY_TYPE || (int)$comment->getObjectId() !== $cardId) {
|
||||
if ($comment->getObjectType() !== Application::COMMENT_ENTITY_TYPE || $comment->getObjectId() !== $cardId) {
|
||||
throw new CommentNotFoundException();
|
||||
}
|
||||
} catch (CommentNotFoundException $e) {
|
||||
@@ -102,7 +109,7 @@ class CommentService {
|
||||
}
|
||||
|
||||
try {
|
||||
$comment = $this->commentsManager->create('users', $this->userId, Application::COMMENT_ENTITY_TYPE, (string)$cardId);
|
||||
$comment = $this->commentsManager->create('users', $this->userId, Application::COMMENT_ENTITY_TYPE, $cardId);
|
||||
$comment->setMessage($message);
|
||||
$comment->setVerb('comment');
|
||||
$comment->setParentId($replyTo);
|
||||
@@ -138,7 +145,7 @@ class CommentService {
|
||||
throw new NoPermissionException('Only authors are allowed to edit their comment.');
|
||||
}
|
||||
if ($comment->getParentId() !== '0') {
|
||||
$this->permissionService->checkPermission($this->cardMapper, (int)$comment->getParentId(), Acl::PERMISSION_READ);
|
||||
$this->permissionService->checkPermission($this->cardMapper, $comment->getParentId(), Acl::PERMISSION_READ);
|
||||
}
|
||||
|
||||
$comment->setMessage($message);
|
||||
|
||||
@@ -176,12 +176,4 @@ class ConfigService {
|
||||
|
||||
return $this->config->getUserValue($userId ?? $this->getUserId(), 'deck', 'attachment_folder', '/Deck');
|
||||
}
|
||||
|
||||
public function setAttachmentFolder(?string $userId = null, string $path): void {
|
||||
if ($userId === null && $this->getUserId() === null) {
|
||||
throw new NoPermissionException('Must be logged in get the attachment folder');
|
||||
}
|
||||
|
||||
$this->config->setUserValue($userId ?? $this->getUserId(), 'deck', 'attachment_folder', $path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@ use OCA\Deck\Sharing\DeckShareProvider;
|
||||
use OCA\Deck\StatusException;
|
||||
use OCP\AppFramework\Http\StreamResponse;
|
||||
use OCP\Constants;
|
||||
use OCP\Files\Folder;
|
||||
use OCP\Files\IMimeTypeDetector;
|
||||
use OCP\Files\IRootFolder;
|
||||
use OCP\Files\NotFoundException;
|
||||
@@ -138,7 +137,7 @@ class FilesAppService implements IAttachmentService, ICustomAttachmentService {
|
||||
|
||||
public function extendData(Attachment $attachment) {
|
||||
$userFolder = $this->rootFolder->getUserFolder($this->userId);
|
||||
$share = $this->getShareForAttachment($attachment);
|
||||
$share = $this->shareProvider->getShareById($attachment->getId());
|
||||
$files = $userFolder->getById($share->getNode()->getId());
|
||||
if (count($files) === 0) {
|
||||
return $attachment;
|
||||
@@ -161,7 +160,7 @@ class FilesAppService implements IAttachmentService, ICustomAttachmentService {
|
||||
// Problem: Folders
|
||||
/** @psalm-suppress InvalidCatch */
|
||||
try {
|
||||
$share = $this->getShareForAttachment($attachment);
|
||||
$share = $this->shareProvider->getShareById($attachment->getId());
|
||||
} catch (ShareNotFound $e) {
|
||||
throw new NotFoundException('File not found');
|
||||
}
|
||||
@@ -190,16 +189,6 @@ class FilesAppService implements IAttachmentService, ICustomAttachmentService {
|
||||
$folder = $userFolder->newFolder($this->configService->getAttachmentFolder());
|
||||
}
|
||||
|
||||
if ($folder->isShared()) {
|
||||
$folderName = $userFolder->getNonExistingName($this->configService->getAttachmentFolder());
|
||||
$folder = $userFolder->newFolder($folderName);
|
||||
$this->configService->setAttachmentFolder($this->userId, $folderName);
|
||||
}
|
||||
|
||||
if (!$folder instanceof Folder || $folder->isShared()) {
|
||||
throw new NotFoundException('No target folder found');
|
||||
}
|
||||
|
||||
$fileName = $folder->getNonExistingName($fileName);
|
||||
$target = $folder->newFile($fileName);
|
||||
$content = fopen($file['tmp_name'], 'rb');
|
||||
@@ -251,7 +240,7 @@ class FilesAppService implements IAttachmentService, ICustomAttachmentService {
|
||||
}
|
||||
|
||||
public function update(Attachment $attachment) {
|
||||
$share = $this->getShareForAttachment($attachment);
|
||||
$share = $this->shareProvider->getShareById($attachment->getId());
|
||||
$target = $share->getNode();
|
||||
$file = $this->getUploadedFile();
|
||||
$fileName = $file['name'];
|
||||
@@ -268,13 +257,8 @@ class FilesAppService implements IAttachmentService, ICustomAttachmentService {
|
||||
return $attachment;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NoPermissionException
|
||||
* @throws NotFoundException
|
||||
* @throws ShareNotFound
|
||||
*/
|
||||
public function delete(Attachment $attachment) {
|
||||
$share = $this->getShareForAttachment($attachment);
|
||||
$share = $this->shareProvider->getShareById($attachment->getId());
|
||||
$file = $share->getNode();
|
||||
$attachment->setData($file->getName());
|
||||
|
||||
@@ -297,21 +281,4 @@ class FilesAppService implements IAttachmentService, ICustomAttachmentService {
|
||||
public function markAsDeleted(Attachment $attachment) {
|
||||
throw new \Exception('Not implemented');
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NoPermissionException
|
||||
*/
|
||||
private function getShareForAttachment(Attachment $attachment): IShare {
|
||||
try {
|
||||
$share = $this->shareProvider->getShareById($attachment->getId());
|
||||
} catch (ShareNotFound $e) {
|
||||
throw new NoPermissionException('No permission to access the attachment from the card');
|
||||
}
|
||||
|
||||
if ((int)$share->getSharedWith() !== (int)$attachment->getCardId()) {
|
||||
throw new NoPermissionException('No permission to access the attachment from the card');
|
||||
}
|
||||
|
||||
return $share;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ class FullTextSearchService {
|
||||
|
||||
/** @var CardMapper */
|
||||
private $cardMapper;
|
||||
|
||||
|
||||
public function __construct(
|
||||
BoardMapper $boardMapper, StackMapper $stackMapper, CardMapper $cardMapper
|
||||
) {
|
||||
@@ -187,6 +187,6 @@ class FullTextSearchService {
|
||||
* @return Board[]
|
||||
*/
|
||||
private function getBoardsFromUser(string $userId): array {
|
||||
return $this->boardMapper->findAllByUser($userId, null, null, null);
|
||||
return $this->boardMapper->findAllByUser($userId, null, null, -1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ use OCA\Deck\Db\Acl;
|
||||
use OCA\Deck\Db\LabelMapper;
|
||||
use OCA\Deck\StatusException;
|
||||
use OCA\Deck\BadRequestException;
|
||||
use OCA\Deck\Validators\LabelServiceValidator;
|
||||
|
||||
class LabelService {
|
||||
|
||||
@@ -41,21 +40,12 @@ class LabelService {
|
||||
private $boardService;
|
||||
/** @var ChangeHelper */
|
||||
private $changeHelper;
|
||||
/** @var LabelServiceValidator */
|
||||
private $labelServiceValidator;
|
||||
|
||||
public function __construct(
|
||||
LabelMapper $labelMapper,
|
||||
PermissionService $permissionService,
|
||||
BoardService $boardService,
|
||||
ChangeHelper $changeHelper,
|
||||
LabelServiceValidator $labelServiceValidator
|
||||
) {
|
||||
public function __construct(LabelMapper $labelMapper, PermissionService $permissionService, BoardService $boardService, ChangeHelper $changeHelper) {
|
||||
$this->labelMapper = $labelMapper;
|
||||
$this->permissionService = $permissionService;
|
||||
$this->boardService = $boardService;
|
||||
$this->changeHelper = $changeHelper;
|
||||
$this->labelServiceValidator = $labelServiceValidator;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -86,7 +76,17 @@ class LabelService {
|
||||
* @throws BadRequestException
|
||||
*/
|
||||
public function create($title, $color, $boardId) {
|
||||
$this->labelServiceValidator->check(compact('title', 'color', 'boardId'));
|
||||
if ($title === false || $title === null) {
|
||||
throw new BadRequestException('title must be provided');
|
||||
}
|
||||
|
||||
if ($color === false || $color === null) {
|
||||
throw new BadRequestException('color must be provided');
|
||||
}
|
||||
|
||||
if (is_numeric($boardId) === false) {
|
||||
throw new BadRequestException('board id must be a number');
|
||||
}
|
||||
|
||||
$this->permissionService->checkPermission(null, $boardId, Acl::PERMISSION_MANAGE);
|
||||
|
||||
@@ -121,7 +121,9 @@ class LabelService {
|
||||
* @throws BadRequestException
|
||||
*/
|
||||
public function delete($id) {
|
||||
$this->labelServiceValidator->check(compact('id'));
|
||||
if (is_numeric($id) === false) {
|
||||
throw new BadRequestException('label id must be a number');
|
||||
}
|
||||
|
||||
$this->permissionService->checkPermission($this->labelMapper, $id, Acl::PERMISSION_MANAGE);
|
||||
if ($this->boardService->isArchived($this->labelMapper, $id)) {
|
||||
@@ -144,7 +146,17 @@ class LabelService {
|
||||
* @throws BadRequestException
|
||||
*/
|
||||
public function update($id, $title, $color) {
|
||||
$this->labelServiceValidator->check(compact('title', 'color', 'id'));
|
||||
if (is_numeric($id) === false) {
|
||||
throw new BadRequestException('label id must be a number');
|
||||
}
|
||||
|
||||
if ($title === false || $title === null || $title === "") {
|
||||
throw new BadRequestException('title must be provided');
|
||||
}
|
||||
|
||||
if ($color === false || $color === null) {
|
||||
throw new BadRequestException('color must be provided');
|
||||
}
|
||||
|
||||
$this->permissionService->checkPermission($this->labelMapper, $id, Acl::PERMISSION_MANAGE);
|
||||
|
||||
|
||||
@@ -29,11 +29,11 @@ use OCA\Deck\Db\Acl;
|
||||
use OCA\Deck\Db\AclMapper;
|
||||
use OCA\Deck\Db\Board;
|
||||
use OCA\Deck\Db\BoardMapper;
|
||||
use OCA\Deck\Db\CardMapper;
|
||||
use OCA\Deck\Db\IPermissionMapper;
|
||||
use OCA\Deck\Db\User;
|
||||
use OCA\Deck\NoPermissionException;
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
use OCP\AppFramework\Db\Entity;
|
||||
use OCP\AppFramework\Db\MultipleObjectsReturnedException;
|
||||
use OCP\IConfig;
|
||||
use OCP\IGroupManager;
|
||||
@@ -65,7 +65,6 @@ class PermissionService {
|
||||
private $users = [];
|
||||
|
||||
private $boardCache;
|
||||
private $permissionCache;
|
||||
|
||||
public function __construct(
|
||||
ILogger $logger,
|
||||
@@ -89,7 +88,6 @@ class PermissionService {
|
||||
$this->userId = $userId;
|
||||
|
||||
$this->boardCache = new CappedMemoryCache();
|
||||
$this->permissionCache = new CappedMemoryCache();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -98,27 +96,16 @@ class PermissionService {
|
||||
* @param $boardId
|
||||
* @return bool|array
|
||||
*/
|
||||
public function getPermissions($boardId, ?string $userId = null) {
|
||||
if ($userId === null) {
|
||||
$userId = $this->userId;
|
||||
}
|
||||
|
||||
if ($cached = $this->permissionCache->get($boardId)) {
|
||||
return $cached;
|
||||
}
|
||||
|
||||
$board = $this->getBoard($boardId);
|
||||
$owner = $this->userIsBoardOwner($boardId, $userId);
|
||||
$acls = $board->getDeletedAt() === 0 ? $this->aclMapper->findAll($boardId) : [];
|
||||
$permissions = [
|
||||
public function getPermissions($boardId) {
|
||||
$owner = $this->userIsBoardOwner($boardId);
|
||||
$acls = $this->aclMapper->findAll($boardId);
|
||||
return [
|
||||
Acl::PERMISSION_READ => $owner || $this->userCan($acls, Acl::PERMISSION_READ),
|
||||
Acl::PERMISSION_EDIT => $owner || $this->userCan($acls, Acl::PERMISSION_EDIT),
|
||||
Acl::PERMISSION_MANAGE => $owner || $this->userCan($acls, Acl::PERMISSION_MANAGE),
|
||||
Acl::PERMISSION_SHARE => ($owner || $this->userCan($acls, Acl::PERMISSION_SHARE))
|
||||
&& (!$this->shareManager->sharingDisabledForUser($this->userId))
|
||||
];
|
||||
$this->permissionCache->set((string)$boardId, $permissions);
|
||||
return $permissions;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -130,7 +117,7 @@ class PermissionService {
|
||||
*/
|
||||
public function matchPermissions(Board $board) {
|
||||
$owner = $this->userIsBoardOwner($board->getId());
|
||||
$acls = $board->getAcl() ?? [];
|
||||
$acls = $board->getAcl();
|
||||
return [
|
||||
Acl::PERMISSION_READ => $owner || $this->userCan($acls, Acl::PERMISSION_READ),
|
||||
Acl::PERMISSION_EDIT => $owner || $this->userCan($acls, Acl::PERMISSION_EDIT),
|
||||
@@ -143,10 +130,13 @@ class PermissionService {
|
||||
/**
|
||||
* check permissions for replacing dark magic middleware
|
||||
*
|
||||
* @param numeric $id
|
||||
* @param $mapper IPermissionMapper|null null if $id is a boardId
|
||||
* @param $id int unique identifier of the Entity
|
||||
* @param $permission int
|
||||
* @return bool
|
||||
* @throws NoPermissionException
|
||||
*/
|
||||
public function checkPermission($mapper, $id, $permission, $userId = null, bool $allowDeletedCard = false) {
|
||||
public function checkPermission($mapper, $id, $permission, $userId = null) {
|
||||
$boardId = $id;
|
||||
if ($mapper instanceof IPermissionMapper && !($mapper instanceof BoardMapper)) {
|
||||
$boardId = $mapper->findBoardId($id);
|
||||
@@ -160,20 +150,12 @@ class PermissionService {
|
||||
throw new NoPermissionException('Permission denied');
|
||||
}
|
||||
|
||||
if ($this->userIsBoardOwner($boardId, $userId)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
$permissions = $this->getPermissions($boardId, $userId);
|
||||
if ($permissions[$permission] === true) {
|
||||
if (!$allowDeletedCard && $mapper instanceof CardMapper) {
|
||||
$card = $mapper->find($id);
|
||||
if ($card->getDeletedAt() > 0) {
|
||||
throw new NoPermissionException('Card is deleted');
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
$acls = $this->getBoard((int)$boardId)->getAcl() ?? [];
|
||||
$acls = $this->getBoard($boardId)->getAcl();
|
||||
$result = $this->userCan($acls, $permission, $userId);
|
||||
if ($result) {
|
||||
return true;
|
||||
@@ -205,11 +187,11 @@ class PermissionService {
|
||||
* @throws MultipleObjectsReturnedException
|
||||
* @throws DoesNotExistException
|
||||
*/
|
||||
private function getBoard(int $boardId): Board {
|
||||
if (!isset($this->boardCache[(string)$boardId])) {
|
||||
$this->boardCache[(string)$boardId] = $this->boardMapper->find($boardId, false, true);
|
||||
private function getBoard($boardId): Board {
|
||||
if (!isset($this->boardCache[$boardId])) {
|
||||
$this->boardCache[$boardId] = $this->boardMapper->find($boardId, false, true);
|
||||
}
|
||||
return $this->boardCache[(string)$boardId];
|
||||
return $this->boardCache[$boardId];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -361,6 +343,5 @@ class PermissionService {
|
||||
*/
|
||||
public function setUserId(string $userId): void {
|
||||
$this->userId = $userId;
|
||||
$this->permissionCache->clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,19 +90,25 @@ class SearchService {
|
||||
}
|
||||
|
||||
public function searchBoards(string $term, ?int $limit, ?int $cursor): array {
|
||||
$boards = $this->boardService->getUserBoards(null, true, $cursor, mb_strtolower($term));
|
||||
|
||||
$boards = $this->boardService->getUserBoards();
|
||||
// get boards that have a lastmodified date which is lower than the cursor
|
||||
// and which match the search term
|
||||
$filteredBoards = array_filter($boards, static function (Board $board) use ($term, $cursor) {
|
||||
return (
|
||||
($cursor === null || $board->getLastModified() < $cursor)
|
||||
&& mb_stripos(mb_strtolower($board->getTitle()), mb_strtolower($term)) > -1
|
||||
);
|
||||
});
|
||||
// sort the boards, recently modified first
|
||||
usort($boards, function ($boardA, $boardB) {
|
||||
usort($filteredBoards, function ($boardA, $boardB) {
|
||||
$ta = $boardA->getLastModified();
|
||||
$tb = $boardB->getLastModified();
|
||||
return $ta === $tb
|
||||
? 0
|
||||
: ($ta > $tb ? -1 : 1);
|
||||
});
|
||||
|
||||
// limit the number of results
|
||||
return array_slice($boards, 0, $limit);
|
||||
return array_slice($filteredBoards, 0, $limit);
|
||||
}
|
||||
|
||||
public function searchComments(string $term, ?int $limit = null, ?int $cursor = null): array {
|
||||
|
||||
@@ -37,7 +37,6 @@ use OCA\Deck\Db\Stack;
|
||||
use OCA\Deck\Db\StackMapper;
|
||||
use OCA\Deck\NoPermissionException;
|
||||
use OCA\Deck\StatusException;
|
||||
use OCA\Deck\Validators\StackServiceValidator;
|
||||
|
||||
class StackService {
|
||||
private $stackMapper;
|
||||
@@ -51,7 +50,6 @@ class StackService {
|
||||
private $attachmentService;
|
||||
private $activityManager;
|
||||
private $changeHelper;
|
||||
private $stackServiceValidator;
|
||||
|
||||
public function __construct(
|
||||
StackMapper $stackMapper,
|
||||
@@ -64,7 +62,6 @@ class StackService {
|
||||
AssignmentMapper $assignedUsersMapper,
|
||||
AttachmentService $attachmentService,
|
||||
ActivityManager $activityManager,
|
||||
StackServiceValidator $stackServiceValidator,
|
||||
ChangeHelper $changeHelper
|
||||
) {
|
||||
$this->stackMapper = $stackMapper;
|
||||
@@ -78,7 +75,6 @@ class StackService {
|
||||
$this->attachmentService = $attachmentService;
|
||||
$this->activityManager = $activityManager;
|
||||
$this->changeHelper = $changeHelper;
|
||||
$this->stackServiceValidator = $stackServiceValidator;
|
||||
}
|
||||
|
||||
private function enrichStackWithCards($stack, $since = -1) {
|
||||
@@ -206,7 +202,17 @@ class StackService {
|
||||
* @throws BadRequestException
|
||||
*/
|
||||
public function create($title, $boardId, $order) {
|
||||
$this->stackServiceValidator->check(compact('title', 'boardId', 'order'));
|
||||
if ($title === false || $title === null) {
|
||||
throw new BadRequestException('title must be provided');
|
||||
}
|
||||
|
||||
if (is_numeric($order) === false) {
|
||||
throw new BadRequestException('order must be a number');
|
||||
}
|
||||
|
||||
if (is_numeric($boardId) === false) {
|
||||
throw new BadRequestException('board id must be a number');
|
||||
}
|
||||
|
||||
$this->permissionService->checkPermission(null, $boardId, Acl::PERMISSION_MANAGE);
|
||||
if ($this->boardService->isArchived(null, $boardId)) {
|
||||
@@ -269,7 +275,21 @@ class StackService {
|
||||
* @throws BadRequestException
|
||||
*/
|
||||
public function update($id, $title, $boardId, $order, $deletedAt) {
|
||||
$this->stackServiceValidator->check(compact('id', 'title', 'boardId', 'order'));
|
||||
if (is_numeric($id) === false) {
|
||||
throw new BadRequestException('stack id must be a number');
|
||||
}
|
||||
|
||||
if ($title === false || $title === null) {
|
||||
throw new BadRequestException('title must be provided');
|
||||
}
|
||||
|
||||
if (is_numeric($boardId) === false) {
|
||||
throw new BadRequestException('board id must be a number');
|
||||
}
|
||||
|
||||
if (is_numeric($order) === false) {
|
||||
throw new BadRequestException('order must be a number');
|
||||
}
|
||||
|
||||
$this->permissionService->checkPermission($this->stackMapper, $id, Acl::PERMISSION_MANAGE);
|
||||
$this->permissionService->checkPermission($this->boardMapper, $boardId, Acl::PERMISSION_MANAGE);
|
||||
@@ -305,7 +325,13 @@ class StackService {
|
||||
* @throws BadRequestException
|
||||
*/
|
||||
public function reorder($id, $order) {
|
||||
$this->stackServiceValidator->check(compact('id', 'order'));
|
||||
if (is_numeric($id) === false) {
|
||||
throw new BadRquestException('id must be a number');
|
||||
}
|
||||
|
||||
if ($order === false || $order === null) {
|
||||
throw new BadRequestException('order must be provided');
|
||||
}
|
||||
|
||||
$this->permissionService->checkPermission($this->stackMapper, $id, Acl::PERMISSION_MANAGE);
|
||||
$stackToSort = $this->stackMapper->find($id);
|
||||
|
||||
@@ -115,7 +115,7 @@ class ShareAPIHelper {
|
||||
*/
|
||||
public function canAccessShare(IShare $share, string $user): bool {
|
||||
try {
|
||||
$this->permissionService->checkPermission($this->cardMapper, (int)$share->getSharedWith(), Acl::PERMISSION_READ, $user);
|
||||
$this->permissionService->checkPermission($this->cardMapper, $share->getSharedWith(), Acl::PERMISSION_READ, $user);
|
||||
} catch (NoPermissionException $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
|
||||
*
|
||||
* @author Julius Härtl <jus@bitgrid.net>
|
||||
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||
* @author Luka Trovic <luka.trovic@nextcloud.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OCA\Deck\Validators;
|
||||
|
||||
class AssignmentServiceValidator extends BaseValidator {
|
||||
public function rules() {
|
||||
return [
|
||||
'cardId' => ['numeric'],
|
||||
'userId' => ['not_empty', 'not_null', 'not_false', 'max:64'],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
|
||||
*
|
||||
* @author Julius Härtl <jus@bitgrid.net>
|
||||
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||
* @author Luka Trovic <luka.trovic@nextcloud.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OCA\Deck\Validators;
|
||||
|
||||
class AttachmentServiceValidator extends BaseValidator {
|
||||
public function rules() {
|
||||
return [
|
||||
'cardId' => ['numeric'],
|
||||
'type' => ['not_empty', 'not_null', 'not_false'],
|
||||
'data' => ['not_empty', 'not_null', 'not_false', 'max:255'],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,182 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
|
||||
*
|
||||
* @author Julius Härtl <jus@bitgrid.net>
|
||||
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||
* @author Luka Trovic <luka.trovic@nextcloud.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OCA\Deck\Validators;
|
||||
|
||||
use Exception;
|
||||
use OCA\Deck\BadRequestException;
|
||||
|
||||
abstract class BaseValidator {
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
abstract public function rules();
|
||||
|
||||
/**
|
||||
* Validate given entries
|
||||
*
|
||||
* @param array $data
|
||||
* @return void
|
||||
* @throws BadRequestException
|
||||
*/
|
||||
private function validate($data) {
|
||||
$rules = $this->rules();
|
||||
|
||||
foreach ($data as $field => $value) {
|
||||
$field_rule = $rules[$field];
|
||||
|
||||
if (is_array($field_rule)) {
|
||||
foreach ($field_rule as $rule) {
|
||||
// The format for specifying validation rules and parameters follows an
|
||||
// easy {rule}:{parameters} formatting convention. For instance the
|
||||
// rule "Max:3" states that the value may only be three letters.
|
||||
if (strpos($rule, ':') !== false) {
|
||||
[$rule, $parameter] = explode(':', $rule, 2);
|
||||
if (!$this->{$rule}($value, $parameter)) {
|
||||
throw new BadRequestException(
|
||||
$this->getErrorMessage($rule, $field, $parameter));
|
||||
}
|
||||
} else {
|
||||
if (!$this->{$rule}($value)) {
|
||||
throw new BadRequestException(
|
||||
$field . ' must be provided and must be '. str_replace("_", " ", $rule));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_callable($field_rule) && !$field_rule($value)) {
|
||||
throw new BadRequestException($field . ' must be provided');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @return void
|
||||
* @throws BadRequestException
|
||||
*/
|
||||
public function check(array $data) {
|
||||
$this->validate($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @return bool
|
||||
*/
|
||||
private function numeric($value): bool {
|
||||
return is_numeric($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @return bool
|
||||
*/
|
||||
private function bool($value): bool {
|
||||
return is_bool($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @return bool
|
||||
*/
|
||||
private function not_false($value): bool {
|
||||
return ($value !== false) && ($value !== 'false');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @return bool
|
||||
*/
|
||||
private function not_null($value): bool {
|
||||
return !is_null($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @return bool
|
||||
*/
|
||||
private function not_empty($value): bool {
|
||||
return !empty($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
private function max($value, $limit): bool {
|
||||
if (!$limit || !is_numeric($limit)) {
|
||||
throw new Exception("Validation rule max requires at least 1 parameter. " . json_encode($limit));
|
||||
}
|
||||
return $this->getSize($value) <= $limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
private function min($value, $limit): bool {
|
||||
if (!$limit || !is_numeric($limit)) {
|
||||
throw new Exception("Validation rule max requires at least 1 parameter.");
|
||||
}
|
||||
return $this->getSize($value) >= $limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the size of an attribute.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return int
|
||||
*/
|
||||
protected function getSize($value): int {
|
||||
// This method will determine if the attribute is a number or string and
|
||||
// return the proper size accordingly. If it is a number, then number itself
|
||||
// is the size.
|
||||
if (is_int($value)) {
|
||||
return $value;
|
||||
} elseif (is_array($value)) {
|
||||
return count($value);
|
||||
}
|
||||
|
||||
return mb_strlen($value ?? '');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $rule
|
||||
* @param $field
|
||||
* @param $parameter
|
||||
* @return string
|
||||
*/
|
||||
protected function getErrorMessage($rule, $field, $parameter = null): string {
|
||||
if (in_array($rule, ['max', 'min'])) {
|
||||
return $rule === 'max'
|
||||
? $field . ' cannot be longer than '. $parameter . ' characters '
|
||||
: $field . ' must be at least '. $parameter . ' characters long ';
|
||||
}
|
||||
|
||||
return $field . ' must be provided and must be '. str_replace("_", " ", $rule);
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
|
||||
*
|
||||
* @author Julius Härtl <jus@bitgrid.net>
|
||||
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||
* @author Luka Trovic <luka.trovic@nextcloud.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OCA\Deck\Validators;
|
||||
|
||||
class BoardServiceValidator extends BaseValidator {
|
||||
public function rules() {
|
||||
return [
|
||||
'id' => ['numeric'],
|
||||
'boardId' => ['numeric'],
|
||||
'type' => ['numeric'],
|
||||
'mapper' => ['not_empty', 'not_null', 'not_false'],
|
||||
'title' => ['not_empty', 'not_null', 'not_false', 'max:100'],
|
||||
'userId' => ['not_empty', 'not_null', 'not_false', 'max:64'],
|
||||
'color' => ['not_empty', 'not_null', 'not_false', 'max:6'],
|
||||
'participant' => ['not_empty', 'not_null', 'not_false', 'max:64'],
|
||||
'edit' => ['not_null'],
|
||||
'share' => ['not_null'],
|
||||
'manage' => ['not_null'],
|
||||
'archived' => ['bool']
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
|
||||
*
|
||||
* @author Julius Härtl <jus@bitgrid.net>
|
||||
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||
* @author Luka Trovic <luka.trovic@nextcloud.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OCA\Deck\Validators;
|
||||
|
||||
class CardServiceValidator extends BaseValidator {
|
||||
public function rules() {
|
||||
return [
|
||||
'id' => ['numeric'],
|
||||
'title' => ['not_empty', 'not_null', 'not_false', 'max:255'],
|
||||
'cardId' => ['numeric'],
|
||||
'stackId' => ['numeric'],
|
||||
'boardId' => ['numeric'],
|
||||
'labelId' => ['numeric'],
|
||||
'type' => ['not_empty', 'not_null', 'not_false', 'max:64'],
|
||||
'order' => ['numeric'],
|
||||
'owner' => ['not_empty', 'not_null', 'not_false', 'max:64'],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
|
||||
*
|
||||
* @author Julius Härtl <jus@bitgrid.net>
|
||||
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||
* @author Luka Trovic <luka.trovic@nextcloud.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OCA\Deck\Validators;
|
||||
|
||||
class LabelServiceValidator extends BaseValidator {
|
||||
public function rules() {
|
||||
return [
|
||||
'id' => ['numeric'],
|
||||
'title' => ['not_empty', 'not_null', 'not_false', 'max:100'],
|
||||
'boardId' => ['numeric', 'not_null'],
|
||||
'color' => ['not_empty', 'not_null', 'not_false', 'max:6']
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
|
||||
*
|
||||
* @author Julius Härtl <jus@bitgrid.net>
|
||||
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||
* @author Luka Trovic <luka.trovic@nextcloud.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OCA\Deck\Validators;
|
||||
|
||||
class StackServiceValidator extends BaseValidator {
|
||||
public function rules() {
|
||||
return [
|
||||
'id' => ['numeric'],
|
||||
'title' => ['not_empty', 'not_null', 'not_false', 'max:100'],
|
||||
'boardId' => ['numeric', 'not_null'],
|
||||
'order' => ['numeric', 'not_null']
|
||||
];
|
||||
}
|
||||
}
|
||||
18003
package-lock.json
generated
18003
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
195
package.json
195
package.json
@@ -1,100 +1,99 @@
|
||||
{
|
||||
"name": "deck",
|
||||
"description": "",
|
||||
"version": "1.6.7",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Julius Härtl",
|
||||
"email": "jus@bitgrid.net",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Michael Weimann",
|
||||
"email": "mail@michael-weimann.eu",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"license": "agpl",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "NODE_ENV=production webpack --progress --config webpack.js",
|
||||
"dev": "NODE_ENV=development webpack --progress --config webpack.js",
|
||||
"watch": "NODE_ENV=development webpack --progress --watch --config webpack.js",
|
||||
"lint": "eslint --ext .js,.vue src",
|
||||
"lint:fix": "eslint --ext .js,.vue src --fix",
|
||||
"stylelint": "stylelint src",
|
||||
"stylelint:fix": "stylelint src --fix",
|
||||
"test": "jest",
|
||||
"test:coverage": "jest --coverage"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/polyfill": "^7.12.1",
|
||||
"@babel/runtime": "^7.16.0",
|
||||
"@juliushaertl/vue-richtext": "^1.0.1",
|
||||
"@nextcloud/auth": "^1.3.0",
|
||||
"@nextcloud/axios": "^1.7.0",
|
||||
"@nextcloud/dialogs": "^3.1.2",
|
||||
"@nextcloud/event-bus": "^2.1.1",
|
||||
"@nextcloud/files": "^2.1.0",
|
||||
"@nextcloud/initial-state": "^1.2.1",
|
||||
"@nextcloud/l10n": "^1.4.1",
|
||||
"@nextcloud/moment": "^1.1.1",
|
||||
"@nextcloud/router": "^2.0.0",
|
||||
"@nextcloud/vue": "^4.2.0",
|
||||
"@nextcloud/vue-dashboard": "^2.0.1",
|
||||
"blueimp-md5": "^2.19.0",
|
||||
"dompurify": "^2.3.3",
|
||||
"lodash": "^4.17.21",
|
||||
"markdown-it": "^12.2.0",
|
||||
"markdown-it-link-attributes": "^3.0.0",
|
||||
"markdown-it-task-checkbox": "^1.0.6",
|
||||
"moment": "^2.29.1",
|
||||
"nextcloud-vue-collections": "^0.9.0",
|
||||
"p-queue": "^6.6.2",
|
||||
"url-search-params-polyfill": "^8.1.1",
|
||||
"vue": "^2.6.14",
|
||||
"vue-at": "^2.5.0-beta.2",
|
||||
"vue-click-outside": "^1.1.0",
|
||||
"vue-easymde": "^2.0.0",
|
||||
"vue-infinite-loading": "^2.4.5",
|
||||
"vue-router": "^3.5.3",
|
||||
"vue-smooth-dnd": "^0.8.1",
|
||||
"vuex": "^3.6.2",
|
||||
"vuex-router-sync": "^5.0.0"
|
||||
},
|
||||
"browserslist": [
|
||||
"extends @nextcloud/browserslist-config"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^14.0.0",
|
||||
"npm": "^7.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nextcloud/babel-config": "^1.0.0",
|
||||
"@nextcloud/browserslist-config": "^2.2.0",
|
||||
"@nextcloud/eslint-config": "^6.1.0",
|
||||
"@nextcloud/stylelint-config": "^1.0.0-beta.0",
|
||||
"@nextcloud/webpack-vue-config": "^4.1.2",
|
||||
"@relative-ci/agent": "^3.0.0",
|
||||
"@vue/test-utils": "^1.2.2",
|
||||
"jest": "^27.3.1",
|
||||
"jest-serializer-vue": "^2.0.2",
|
||||
"vue-jest": "^3.0.7"
|
||||
},
|
||||
"jest": {
|
||||
"moduleFileExtensions": [
|
||||
"js",
|
||||
"vue"
|
||||
],
|
||||
"moduleNameMapper": {
|
||||
"^@/(.*)$": "<rootDir>/src/$1"
|
||||
},
|
||||
"transform": {
|
||||
"^.+\\.js$": "<rootDir>/node_modules/babel-jest",
|
||||
".*\\.(vue)$": "<rootDir>/node_modules/vue-jest"
|
||||
},
|
||||
"snapshotSerializers": [
|
||||
"<rootDir>/node_modules/jest-serializer-vue"
|
||||
]
|
||||
}
|
||||
"name": "deck",
|
||||
"description": "",
|
||||
"version": "1.5.8",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Julius Härtl",
|
||||
"email": "jus@bitgrid.net",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Michael Weimann",
|
||||
"email": "mail@michael-weimann.eu",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"license": "agpl",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "NODE_ENV=production webpack --progress --config webpack.js",
|
||||
"dev": "NODE_ENV=development webpack --progress --config webpack.js",
|
||||
"watch": "NODE_ENV=development webpack --progress --watch --config webpack.js",
|
||||
"lint": "eslint --ext .js,.vue src",
|
||||
"lint:fix": "eslint --ext .js,.vue src --fix",
|
||||
"stylelint": "stylelint src",
|
||||
"stylelint:fix": "stylelint src --fix",
|
||||
"test": "jest",
|
||||
"test:coverage": "jest --coverage"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/polyfill": "^7.12.1",
|
||||
"@babel/runtime": "^7.14.6",
|
||||
"@juliushaertl/vue-richtext": "^1.0.1",
|
||||
"@nextcloud/auth": "^1.3.0",
|
||||
"@nextcloud/axios": "^1.6.0",
|
||||
"@nextcloud/dialogs": "^3.1.2",
|
||||
"@nextcloud/event-bus": "^2.0.0",
|
||||
"@nextcloud/files": "^2.0.0",
|
||||
"@nextcloud/initial-state": "^1.2.0",
|
||||
"@nextcloud/l10n": "^1.4.1",
|
||||
"@nextcloud/moment": "^1.1.1",
|
||||
"@nextcloud/router": "^2.0.0",
|
||||
"@nextcloud/vue": "^3.10.1",
|
||||
"@nextcloud/vue-dashboard": "^2.0.1",
|
||||
"blueimp-md5": "^2.18.0",
|
||||
"dompurify": "^2.2.9",
|
||||
"lodash": "^4.17.21",
|
||||
"markdown-it": "^12.0.6",
|
||||
"markdown-it-task-lists": "^2.1.1",
|
||||
"moment": "^2.29.1",
|
||||
"nextcloud-vue-collections": "^0.9.0",
|
||||
"p-queue": "^6.6.2",
|
||||
"url-search-params-polyfill": "^8.1.1",
|
||||
"vue": "^2.6.14",
|
||||
"vue-at": "^2.5.0-beta.2",
|
||||
"vue-click-outside": "^1.1.0",
|
||||
"vue-easymde": "^1.4.0",
|
||||
"vue-infinite-loading": "^2.4.5",
|
||||
"vue-router": "^3.5.1",
|
||||
"vue-smooth-dnd": "^0.8.1",
|
||||
"vuex": "^3.6.2",
|
||||
"vuex-router-sync": "^5.0.0"
|
||||
},
|
||||
"browserslist": [
|
||||
"extends @nextcloud/browserslist-config"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^14.0.0",
|
||||
"npm": "^7.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nextcloud/babel-config": "^1.0.0-beta.1",
|
||||
"@nextcloud/browserslist-config": "^2.1.0",
|
||||
"@nextcloud/eslint-config": "^5.1.0",
|
||||
"@nextcloud/stylelint-config": "^1.0.0-beta.0",
|
||||
"@nextcloud/webpack-vue-config": "^4.0.3",
|
||||
"@relative-ci/agent": "^2.0.0",
|
||||
"@vue/test-utils": "^1.2.1",
|
||||
"jest": "^27.0.4",
|
||||
"jest-serializer-vue": "^2.0.2",
|
||||
"vue-jest": "^3.0.7"
|
||||
},
|
||||
"jest": {
|
||||
"moduleFileExtensions": [
|
||||
"js",
|
||||
"vue"
|
||||
],
|
||||
"moduleNameMapper": {
|
||||
"^@/(.*)$": "<rootDir>/src/$1"
|
||||
},
|
||||
"transform": {
|
||||
"^.+\\.js$": "<rootDir>/node_modules/babel-jest",
|
||||
".*\\.(vue)$": "<rootDir>/node_modules/vue-jest"
|
||||
},
|
||||
"snapshotSerializers": [
|
||||
"<rootDir>/node_modules/jest-serializer-vue"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
10
src/App.vue
10
src/App.vue
@@ -59,11 +59,6 @@ export default {
|
||||
Content,
|
||||
AppContent,
|
||||
},
|
||||
provide() {
|
||||
return {
|
||||
boardApi,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
addButton: {
|
||||
@@ -117,6 +112,11 @@ export default {
|
||||
this.$router.push({ name: 'board' })
|
||||
},
|
||||
},
|
||||
provide() {
|
||||
return {
|
||||
boardApi,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -137,7 +137,7 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
isBoardAndStackChoosen() {
|
||||
return !(this.selectedBoard === '' || this.selectedStack === '')
|
||||
return !(this.selectedBoard === '')
|
||||
},
|
||||
},
|
||||
beforeMount() {
|
||||
|
||||
@@ -84,20 +84,7 @@ export default {
|
||||
params.append('object_id', '' + this.objectId)
|
||||
params.append('limit', ACTIVITY_FETCH_LIMIT)
|
||||
|
||||
const response = await axios.get(
|
||||
generateOcsUrl(`apps/activity/api/v2/activity/${this.filter}`) + '?' + params,
|
||||
{
|
||||
validateStatus: (status) => {
|
||||
return (status >= 200 && status < 300) || status === 304
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
if (response.status === 304) {
|
||||
this.endReached = true
|
||||
return []
|
||||
}
|
||||
|
||||
const response = await axios.get(generateOcsUrl(`apps/activity/api/v2/activity/${this.filter}`) + '?' + params)
|
||||
let activities = response.data.ocs.data
|
||||
if (this.filter === 'deck') {
|
||||
// We need to manually filter activities here, since currently we use two different types and there is no way
|
||||
@@ -108,7 +95,7 @@ export default {
|
||||
})
|
||||
}
|
||||
this.activities.push(...activities)
|
||||
if (activities.length === 0) {
|
||||
if (response.data.ocs.meta.statuscode === 304 || activities.length === 0) {
|
||||
this.endReached = true
|
||||
return []
|
||||
}
|
||||
|
||||
@@ -76,108 +76,110 @@
|
||||
<ActionButton v-else icon="icon-filter" />
|
||||
</Actions>
|
||||
|
||||
<div v-if="filterVisible" class="filter">
|
||||
<h3>{{ t('deck', 'Filter by tag') }}</h3>
|
||||
<div v-for="label in labelsSorted" :key="label.id" class="filter--item">
|
||||
<input
|
||||
:id="label.id"
|
||||
v-model="filter.tags"
|
||||
type="checkbox"
|
||||
class="checkbox"
|
||||
:value="label.id"
|
||||
@change="setFilter">
|
||||
<label :for="label.id"><span class="label" :style="labelStyle(label)">{{ label.title }}</span></label>
|
||||
</div>
|
||||
<template>
|
||||
<div v-if="filterVisible" class="filter">
|
||||
<h3>{{ t('deck', 'Filter by tag') }}</h3>
|
||||
<div v-for="label in labelsSorted" :key="label.id" class="filter--item">
|
||||
<input
|
||||
:id="label.id"
|
||||
v-model="filter.tags"
|
||||
type="checkbox"
|
||||
class="checkbox"
|
||||
:value="label.id"
|
||||
@change="setFilter">
|
||||
<label :for="label.id"><span class="label" :style="labelStyle(label)">{{ label.title }}</span></label>
|
||||
</div>
|
||||
|
||||
<h3>{{ t('deck', 'Filter by assigned user') }}</h3>
|
||||
<div class="filter--item">
|
||||
<input
|
||||
id="unassigned"
|
||||
v-model="filter.unassigned"
|
||||
type="checkbox"
|
||||
class="checkbox"
|
||||
value="unassigned"
|
||||
@change="setFilter"
|
||||
@click="beforeSetFilter">
|
||||
<label for="unassigned">{{ t('deck', 'Unassigned') }}</label>
|
||||
</div>
|
||||
<div v-for="user in board.users" :key="user.uid" class="filter--item">
|
||||
<input
|
||||
:id="user.uid"
|
||||
v-model="filter.users"
|
||||
type="checkbox"
|
||||
class="checkbox"
|
||||
:value="user.uid"
|
||||
@change="setFilter">
|
||||
<label :for="user.uid"><Avatar :user="user.uid" :size="24" :disable-menu="true" /> {{ user.displayname }}</label>
|
||||
</div>
|
||||
<h3>{{ t('deck', 'Filter by assigned user') }}</h3>
|
||||
<div class="filter--item">
|
||||
<input
|
||||
id="unassigned"
|
||||
v-model="filter.unassigned"
|
||||
type="checkbox"
|
||||
class="checkbox"
|
||||
value="unassigned"
|
||||
@change="setFilter"
|
||||
@click="beforeSetFilter">
|
||||
<label for="unassigned">{{ t('deck', 'Unassigned') }}</label>
|
||||
</div>
|
||||
<div v-for="user in board.users" :key="user.uid" class="filter--item">
|
||||
<input
|
||||
:id="user.uid"
|
||||
v-model="filter.users"
|
||||
type="checkbox"
|
||||
class="checkbox"
|
||||
:value="user.uid"
|
||||
@change="setFilter">
|
||||
<label :for="user.uid"><Avatar :user="user.uid" :size="24" :disable-menu="true" /> {{ user.displayname }}</label>
|
||||
</div>
|
||||
|
||||
<h3>{{ t('deck', 'Filter by due date') }}</h3>
|
||||
<h3>{{ t('deck', 'Filter by due date') }}</h3>
|
||||
|
||||
<div class="filter--item">
|
||||
<input
|
||||
id="overdue"
|
||||
v-model="filter.due"
|
||||
type="radio"
|
||||
class="radio"
|
||||
value="overdue"
|
||||
@change="setFilter"
|
||||
@click="beforeSetFilter">
|
||||
<label for="overdue">{{ t('deck', 'Overdue') }}</label>
|
||||
<div class="filter--item">
|
||||
<input
|
||||
id="overdue"
|
||||
v-model="filter.due"
|
||||
type="radio"
|
||||
class="radio"
|
||||
value="overdue"
|
||||
@change="setFilter"
|
||||
@click="beforeSetFilter">
|
||||
<label for="overdue">{{ t('deck', 'Overdue') }}</label>
|
||||
</div>
|
||||
|
||||
<div class="filter--item">
|
||||
<input
|
||||
id="dueToday"
|
||||
v-model="filter.due"
|
||||
type="radio"
|
||||
class="radio"
|
||||
value="dueToday"
|
||||
@change="setFilter"
|
||||
@click="beforeSetFilter">
|
||||
<label for="dueToday">{{ t('deck', 'Next 24 hours') }}</label>
|
||||
</div>
|
||||
|
||||
<div class="filter--item">
|
||||
<input
|
||||
id="dueWeek"
|
||||
v-model="filter.due"
|
||||
type="radio"
|
||||
class="radio"
|
||||
value="dueWeek"
|
||||
@change="setFilter"
|
||||
@click="beforeSetFilter">
|
||||
<label for="dueWeek">{{ t('deck', 'Next 7 days') }}</label>
|
||||
</div>
|
||||
|
||||
<div class="filter--item">
|
||||
<input
|
||||
id="dueMonth"
|
||||
v-model="filter.due"
|
||||
type="radio"
|
||||
class="radio"
|
||||
value="dueMonth"
|
||||
@change="setFilter"
|
||||
@click="beforeSetFilter">
|
||||
<label for="dueMonth">{{ t('deck', 'Next 30 days') }}</label>
|
||||
</div>
|
||||
|
||||
<div class="filter--item">
|
||||
<input
|
||||
id="noDue"
|
||||
v-model="filter.due"
|
||||
type="radio"
|
||||
class="radio"
|
||||
value="noDue"
|
||||
@change="setFilter"
|
||||
@click="beforeSetFilter">
|
||||
<label for="noDue">{{ t('deck', 'No due date') }}</label>
|
||||
</div>
|
||||
|
||||
<Button :disabled="!isFilterActive" @click="clearFilter">
|
||||
{{ t('deck', 'Clear filter') }}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div class="filter--item">
|
||||
<input
|
||||
id="dueToday"
|
||||
v-model="filter.due"
|
||||
type="radio"
|
||||
class="radio"
|
||||
value="dueToday"
|
||||
@change="setFilter"
|
||||
@click="beforeSetFilter">
|
||||
<label for="dueToday">{{ t('deck', 'Next 24 hours') }}</label>
|
||||
</div>
|
||||
|
||||
<div class="filter--item">
|
||||
<input
|
||||
id="dueWeek"
|
||||
v-model="filter.due"
|
||||
type="radio"
|
||||
class="radio"
|
||||
value="dueWeek"
|
||||
@change="setFilter"
|
||||
@click="beforeSetFilter">
|
||||
<label for="dueWeek">{{ t('deck', 'Next 7 days') }}</label>
|
||||
</div>
|
||||
|
||||
<div class="filter--item">
|
||||
<input
|
||||
id="dueMonth"
|
||||
v-model="filter.due"
|
||||
type="radio"
|
||||
class="radio"
|
||||
value="dueMonth"
|
||||
@change="setFilter"
|
||||
@click="beforeSetFilter">
|
||||
<label for="dueMonth">{{ t('deck', 'Next 30 days') }}</label>
|
||||
</div>
|
||||
|
||||
<div class="filter--item">
|
||||
<input
|
||||
id="noDue"
|
||||
v-model="filter.due"
|
||||
type="radio"
|
||||
class="radio"
|
||||
value="noDue"
|
||||
@change="setFilter"
|
||||
@click="beforeSetFilter">
|
||||
<label for="noDue">{{ t('deck', 'No due date') }}</label>
|
||||
</div>
|
||||
|
||||
<Button :disabled="!isFilterActive" @click="clearFilter">
|
||||
{{ t('deck', 'Clear filter') }}
|
||||
</Button>
|
||||
</div>
|
||||
</template>
|
||||
</Popover>
|
||||
|
||||
<Actions>
|
||||
|
||||
@@ -208,7 +208,7 @@ export default {
|
||||
confirmClasses: 'error',
|
||||
cancel: t('deck', 'Cancel'),
|
||||
},
|
||||
async (result) => {
|
||||
async(result) => {
|
||||
if (result) {
|
||||
try {
|
||||
this.isLoading = true
|
||||
|
||||
@@ -43,22 +43,24 @@
|
||||
|
||||
<li v-if="addLabel" class="editing">
|
||||
<!-- New Tag -->
|
||||
<form class="label-form" @submit.prevent="clickAddLabel">
|
||||
<ColorPicker class="color-picker-wrapper" :value="'#' + addLabelObj.color" @input="updateColor">
|
||||
<div :style="{ backgroundColor: '#' + addLabelObj.color }" class="color0 icon-colorpicker" />
|
||||
</ColorPicker>
|
||||
<input v-model="addLabelObj.title" type="text">
|
||||
<input v-tooltip="{content: missingDataLabel, show: !addLabelObjValidated, trigger: 'manual' }"
|
||||
:disabled="!addLabelObjValidated"
|
||||
type="submit"
|
||||
value=""
|
||||
class="icon-confirm">
|
||||
<Actions>
|
||||
<ActionButton icon="icon-close" @click="addLabel=false">
|
||||
{{ t('deck', 'Cancel') }}
|
||||
</ActionButton>
|
||||
</Actions>
|
||||
</form>
|
||||
<template>
|
||||
<form class="label-form" @submit.prevent="clickAddLabel">
|
||||
<ColorPicker class="color-picker-wrapper" :value="'#' + addLabelObj.color" @input="updateColor">
|
||||
<div :style="{ backgroundColor: '#' + addLabelObj.color }" class="color0 icon-colorpicker" />
|
||||
</ColorPicker>
|
||||
<input v-model="addLabelObj.title" type="text">
|
||||
<input v-tooltip="{content: missingDataLabel, show: !addLabelObjValidated, trigger: 'manual' }"
|
||||
:disabled="!addLabelObjValidated"
|
||||
type="submit"
|
||||
value=""
|
||||
class="icon-confirm">
|
||||
<Actions>
|
||||
<ActionButton icon="icon-close" @click="addLabel=false">
|
||||
{{ t('deck', 'Cancel') }}
|
||||
</ActionButton>
|
||||
</Actions>
|
||||
</form>
|
||||
</template>
|
||||
</li>
|
||||
<button v-if="canManage && !isArchived" @click="clickShowAddLabel()">
|
||||
<span class="icon-add" />{{ t('deck', 'Add a new tag') }}
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
</a>
|
||||
</div>
|
||||
<Actions v-if="selectable">
|
||||
<ActionButton icon="icon-confirm" @click="$emit('select-attachment', attachment)">
|
||||
<ActionButton icon="icon-confirm" @click="$emit('selectAttachment', attachment)">
|
||||
{{ t('deck', 'Add this attachment') }}
|
||||
</ActionButton>
|
||||
</Actions>
|
||||
@@ -89,10 +89,10 @@
|
||||
{{ t('deck', 'Remove attachment') }}
|
||||
</ActionButton>
|
||||
|
||||
<ActionButton v-if="!attachment.extendedData.fileid && attachment.deletedAt === 0" icon="icon-delete" @click="$emit('delete-attachment', attachment)">
|
||||
<ActionButton v-if="!attachment.extendedData.fileid && attachment.deletedAt === 0" icon="icon-delete" @click="$emit('deleteAttachment', attachment)">
|
||||
{{ t('deck', 'Delete Attachment') }}
|
||||
</ActionButton>
|
||||
<ActionButton v-else-if="!attachment.extendedData.fileid" icon="icon-history" @click="$emit('restore-attachment', attachment)">
|
||||
<ActionButton v-else-if="!attachment.extendedData.fileid" icon="icon-history" @click="$emit('restoreAttachment', attachment)">
|
||||
{{ t('deck', 'Restore Attachment') }}
|
||||
</ActionButton>
|
||||
</Actions>
|
||||
@@ -173,7 +173,7 @@ export default {
|
||||
}
|
||||
},
|
||||
attachmentPreview() {
|
||||
return (attachment) => (attachment.extendedData.fileid ? generateUrl(`/core/preview?fileId=${attachment.extendedData.fileid}&x=64&y=64`) : null)
|
||||
return (attachment) => (attachment.extendedData.fileid ? generateUrl(`/core/preview?fileId=${attachment.extendedData.fileid}&x=64&y=64&a=true`) : null)
|
||||
},
|
||||
attachmentUrl() {
|
||||
return (attachment) => generateUrl(`/apps/deck/cards/${attachment.cardId}/attachment/${attachment.id}`)
|
||||
@@ -225,7 +225,7 @@ export default {
|
||||
},
|
||||
shareFromFiles() {
|
||||
picker.pick()
|
||||
.then(async (path) => {
|
||||
.then(async(path) => {
|
||||
console.debug(`path ${path} selected for sharing`)
|
||||
if (!path.startsWith('/')) {
|
||||
throw new Error(t('files', 'Invalid path selected'))
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
<AttachmentList
|
||||
:card-id="card.id"
|
||||
:removable="true"
|
||||
@delete-attachment="deleteAttachment"
|
||||
@restore-attachment="restoreAttachment" />
|
||||
@deleteAttachment="deleteAttachment"
|
||||
@restoreAttachment="restoreAttachment" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
@@ -101,7 +101,6 @@
|
||||
:lang="lang"
|
||||
:formatter="format"
|
||||
:disabled="saving || !canEdit"
|
||||
:shortcuts="shortcuts"
|
||||
confirm />
|
||||
<Actions v-if="canEdit">
|
||||
<ActionButton v-if="copiedCard.duedate" icon="icon-delete" @click="removeDue()">
|
||||
@@ -177,48 +176,6 @@ export default {
|
||||
stringify: this.stringify,
|
||||
parse: this.parse,
|
||||
},
|
||||
shortcuts: [
|
||||
{
|
||||
text: t('deck', 'Today'),
|
||||
onClick() {
|
||||
const date = new Date()
|
||||
date.setDate(date.getDate())
|
||||
date.setHours(23)
|
||||
date.setMinutes(59)
|
||||
return date
|
||||
},
|
||||
},
|
||||
{
|
||||
text: t('deck', 'Tomorrow'),
|
||||
onClick() {
|
||||
const date = new Date()
|
||||
date.setDate(date.getDate() + 1)
|
||||
date.setHours(23)
|
||||
date.setMinutes(59)
|
||||
return date
|
||||
},
|
||||
},
|
||||
{
|
||||
text: t('deck', 'Next week'),
|
||||
onClick() {
|
||||
const date = new Date()
|
||||
date.setDate(date.getDate() + 7)
|
||||
date.setHours(23)
|
||||
date.setMinutes(59)
|
||||
return date
|
||||
},
|
||||
},
|
||||
{
|
||||
text: t('deck', 'Next month'),
|
||||
onClick() {
|
||||
const date = new Date()
|
||||
date.setDate(date.getDate() + 30)
|
||||
date.setHours(23)
|
||||
date.setMinutes(59)
|
||||
return date
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -359,14 +316,6 @@ export default {
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
|
||||
.section-wrapper::v-deep .mx-datepicker-main.mx-datepicker-popup {
|
||||
left: 0 !important;
|
||||
}
|
||||
|
||||
.section-wrapper::v-deep .mx-datepicker-main.mx-datepicker-popup.mx-datepicker-sidebar {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.section-wrapper {
|
||||
display: flex;
|
||||
max-width: 100%;
|
||||
|
||||
@@ -19,45 +19,47 @@
|
||||
</div>
|
||||
</div>
|
||||
<li v-else class="comment">
|
||||
<div class="comment--header">
|
||||
<Avatar :user="comment.actorId" />
|
||||
<span class="has-tooltip username">
|
||||
{{ comment.actorDisplayName }}
|
||||
</span>
|
||||
<Actions v-show="!edit" :force-menu="true">
|
||||
<ActionButton icon="icon-reply" :close-after-click="true" @click="replyTo()">
|
||||
{{ t('deck', 'Reply') }}
|
||||
</ActionButton>
|
||||
<ActionButton v-if="canEdit"
|
||||
icon="icon-rename"
|
||||
:close-after-click="true"
|
||||
@click="showUpdateForm()">
|
||||
{{ t('deck', 'Update') }}
|
||||
</ActionButton>
|
||||
<ActionButton v-if="canEdit"
|
||||
icon="icon-delete"
|
||||
:close-after-click="true"
|
||||
@click="deleteComment()">
|
||||
{{ t('deck', 'Delete') }}
|
||||
</ActionButton>
|
||||
</Actions>
|
||||
<Actions v-if="edit">
|
||||
<ActionButton icon="icon-close" @click="hideUpdateForm" />
|
||||
</Actions>
|
||||
<div class="spacer" />
|
||||
<div class="timestamp">
|
||||
{{ relativeDate(comment.creationDateTime) }}
|
||||
<template>
|
||||
<div class="comment--header">
|
||||
<Avatar :user="comment.actorId" />
|
||||
<span class="has-tooltip username">
|
||||
{{ comment.actorDisplayName }}
|
||||
</span>
|
||||
<Actions v-show="!edit" :force-menu="true">
|
||||
<ActionButton icon="icon-reply" :close-after-click="true" @click="replyTo()">
|
||||
{{ t('deck', 'Reply') }}
|
||||
</ActionButton>
|
||||
<ActionButton v-if="canEdit"
|
||||
icon="icon-rename"
|
||||
:close-after-click="true"
|
||||
@click="showUpdateForm()">
|
||||
{{ t('deck', 'Update') }}
|
||||
</ActionButton>
|
||||
<ActionButton v-if="canEdit"
|
||||
icon="icon-delete"
|
||||
:close-after-click="true"
|
||||
@click="deleteComment()">
|
||||
{{ t('deck', 'Delete') }}
|
||||
</ActionButton>
|
||||
</Actions>
|
||||
<Actions v-if="edit">
|
||||
<ActionButton icon="icon-close" @click="hideUpdateForm" />
|
||||
</Actions>
|
||||
<div class="spacer" />
|
||||
<div class="timestamp">
|
||||
{{ relativeDate(comment.creationDateTime) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<CommentItem v-if="comment.replyTo" :reply="true" :comment="comment.replyTo" />
|
||||
<div v-show="!edit" ref="richTextElement">
|
||||
<RichText
|
||||
class="comment--content"
|
||||
:text="richText(comment)"
|
||||
:arguments="richArgs(comment)"
|
||||
:autolink="true" />
|
||||
</div>
|
||||
<CommentForm v-if="edit" v-model="commentMsg" @submit="updateComment" />
|
||||
<CommentItem v-if="comment.replyTo" :reply="true" :comment="comment.replyTo" />
|
||||
<div v-show="!edit" ref="richTextElement">
|
||||
<RichText
|
||||
class="comment--content"
|
||||
:text="richText(comment)"
|
||||
:arguments="richArgs(comment)"
|
||||
:autolink="true" />
|
||||
</div>
|
||||
<CommentForm v-if="edit" v-model="commentMsg" @submit="updateComment" />
|
||||
</template>
|
||||
</li>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
ref="markdownEditor"
|
||||
v-model="description"
|
||||
:configs="mdeConfig"
|
||||
@update:modelValue="updateDescription"
|
||||
@input="updateDescription"
|
||||
@blur="saveDescription" />
|
||||
|
||||
<Modal v-if="modalShow" :title="t('deck', 'Choose attachment')" @close="modalShow=false">
|
||||
@@ -66,7 +66,7 @@
|
||||
<AttachmentList
|
||||
:card-id="card.id"
|
||||
:selectable="true"
|
||||
@select-attachment="addAttachment" />
|
||||
@selectAttachment="addAttachment" />
|
||||
</div>
|
||||
</Modal>
|
||||
</div>
|
||||
@@ -74,8 +74,7 @@
|
||||
|
||||
<script>
|
||||
import MarkdownIt from 'markdown-it'
|
||||
import MarkdownItTaskCheckbox from 'markdown-it-task-checkbox'
|
||||
import MarkdownItLinkAttributes from 'markdown-it-link-attributes'
|
||||
import MarkdownItTaskLists from 'markdown-it-task-lists'
|
||||
import AttachmentList from './AttachmentList'
|
||||
import { Actions, ActionButton, Modal } from '@nextcloud/vue'
|
||||
import { formatFileSize } from '@nextcloud/files'
|
||||
@@ -85,14 +84,7 @@ import { mapState, mapGetters } from 'vuex'
|
||||
const markdownIt = new MarkdownIt({
|
||||
linkify: true,
|
||||
})
|
||||
markdownIt.use(MarkdownItTaskCheckbox, { disabled: false, idPrefix: 'task-item-', ulClass: 'contains-task-list' })
|
||||
|
||||
markdownIt.use(MarkdownItLinkAttributes, {
|
||||
attrs: {
|
||||
target: '_blank',
|
||||
rel: 'noreferrer noopener',
|
||||
},
|
||||
})
|
||||
markdownIt.use(MarkdownItTaskLists, { enabled: true, label: true, labelAfter: true })
|
||||
|
||||
export default {
|
||||
name: 'Description',
|
||||
@@ -231,7 +223,7 @@ export default {
|
||||
updateDescription() {
|
||||
this.descriptionLastEdit = Date.now()
|
||||
clearTimeout(this.descriptionSaveTimeout)
|
||||
this.descriptionSaveTimeout = setTimeout(async () => {
|
||||
this.descriptionSaveTimeout = setTimeout(async() => {
|
||||
await this.saveDescription()
|
||||
}, 2500)
|
||||
},
|
||||
|
||||
@@ -53,19 +53,6 @@
|
||||
<PopoverMenu :menu="popover" />
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
<div class="avatar-print-list">
|
||||
<div v-for="user in avatarUsers" :key="user.id" class="avatar-print-list-item">
|
||||
<Avatar
|
||||
class="avatar-print-list-avatar"
|
||||
:user="user.participant.uid"
|
||||
:display-name="user.participant.displayname"
|
||||
:disable-menu="true"
|
||||
:is-no-user="user.type !== 0"
|
||||
:size="24" />
|
||||
{{ user.participant.displayname }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -129,15 +116,6 @@ export default {
|
||||
}),
|
||||
]
|
||||
},
|
||||
avatarUsers() {
|
||||
if (!this.users) {
|
||||
return []
|
||||
}
|
||||
|
||||
return this.users.filter((user) => {
|
||||
return [0, 1, 7].includes(user.type)
|
||||
})
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
togglePopover() {
|
||||
@@ -198,26 +176,4 @@ export default {
|
||||
display: block;
|
||||
margin: 40px -6px;
|
||||
}
|
||||
|
||||
.avatar-print-list {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media print {
|
||||
.avatar-list {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.avatar-print-list-item {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.avatar-print-list {
|
||||
display: block;
|
||||
padding-top: 5px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
|
||||
<AvatarList :users="card.assignedUsers" />
|
||||
|
||||
<CardMenu class="card-menu" :card="card" />
|
||||
<CardMenu :card="card" />
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
@@ -150,15 +150,4 @@ export default {
|
||||
.fade-enter, .fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
@media print {
|
||||
.badges {
|
||||
align-items: flex-start;
|
||||
max-height: none !important;
|
||||
}
|
||||
|
||||
.card-menu {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -51,7 +51,6 @@
|
||||
<input v-model="copiedCard.title"
|
||||
v-focus
|
||||
type="text"
|
||||
autocomplete="off"
|
||||
required
|
||||
pattern=".*\S+.*">
|
||||
<input type="submit" value="" class="icon-confirm">
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<template>
|
||||
<div v-if="card" class="duedate">
|
||||
<transition name="zoom">
|
||||
<div v-if="card.duedate" :class="dueIcon" :title="absoluteDate">
|
||||
<div v-if="card.duedate" :class="dueIcon">
|
||||
<span>{{ relativeDate }}</span>
|
||||
</div>
|
||||
</transition>
|
||||
@@ -62,14 +62,14 @@ export default {
|
||||
}
|
||||
return moment(this.card.duedate).fromNow()
|
||||
},
|
||||
absoluteDate() {
|
||||
return moment(this.card.duedate).format('L')
|
||||
dueDateTooltip() {
|
||||
return moment(this.card.duedate).format('LLLL')
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<style lang="scss" coped>
|
||||
.icon.due {
|
||||
background-position: 4px center;
|
||||
border-radius: 3px;
|
||||
@@ -105,7 +105,6 @@ export default {
|
||||
padding: 3px 4px;
|
||||
}
|
||||
|
||||
&::before,
|
||||
span {
|
||||
margin-left: 20px;
|
||||
white-space: nowrap;
|
||||
@@ -113,18 +112,4 @@ export default {
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
@media print {
|
||||
.icon.due {
|
||||
background-color: transparent !important;
|
||||
|
||||
span {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: attr(title);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -39,9 +39,6 @@
|
||||
<script>
|
||||
import { ColorPicker, ActionButton, Actions, AppNavigationItem } from '@nextcloud/vue'
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function randomColor() {
|
||||
let randomHexColor = ((1 << 24) * Math.random() | 0).toString(16)
|
||||
while (randomHexColor.length < 6) {
|
||||
@@ -70,9 +67,9 @@ export default {
|
||||
startCreateBoard(e) {
|
||||
this.editing = true
|
||||
},
|
||||
async createBoard(e) {
|
||||
createBoard(e) {
|
||||
const title = e.currentTarget.childNodes[0].value
|
||||
await this.$store.dispatch('createBoard', {
|
||||
this.$store.dispatch('createBoard', {
|
||||
title,
|
||||
color: this.color.substring(1),
|
||||
})
|
||||
|
||||
@@ -63,15 +63,10 @@ import { Actions, ActionButton } from '@nextcloud/vue'
|
||||
|
||||
const createCancelToken = () => axios.CancelToken.source()
|
||||
|
||||
/**
|
||||
* @param root0
|
||||
* @param root0.query
|
||||
* @param root0.cursor
|
||||
*/
|
||||
function search({ query, cursor }) {
|
||||
const cancelToken = createCancelToken()
|
||||
|
||||
const request = async () => axios.get(generateOcsUrl('apps/deck/api/v1.0/search'), {
|
||||
const request = async() => axios.get(generateOcsUrl('apps/deck/api/v1.0/search'), {
|
||||
cancelToken: cancelToken.token,
|
||||
params: {
|
||||
term: query,
|
||||
|
||||
@@ -21,11 +21,6 @@ ul {
|
||||
|
||||
ul {
|
||||
list-style-type: disc;
|
||||
|
||||
.task-list-item {
|
||||
margin-left: -20px;
|
||||
list-style-type: none;
|
||||
}
|
||||
}
|
||||
|
||||
h1 {
|
||||
@@ -72,7 +67,7 @@ img {
|
||||
}
|
||||
|
||||
input[type=checkbox] {
|
||||
margin: 0px 3px 0px 0px;
|
||||
margin: 0px 10px 0px 0px;
|
||||
line-height: 10px;
|
||||
font-size: 10px;
|
||||
display: inline-block;
|
||||
|
||||
@@ -25,8 +25,9 @@ const buildSelector = (selector, propsData = {}) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const container = document.createElement('div')
|
||||
document.getElementById('body-user').append(container)
|
||||
const ComponentVM = new Vue({
|
||||
render: (h) => h(selector, propsData),
|
||||
const View = Vue.extend(selector)
|
||||
const ComponentVM = new View({
|
||||
propsData,
|
||||
}).$mount(container)
|
||||
ComponentVM.$root.$on('close', () => {
|
||||
ComponentVM.$el.remove()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user