Compare commits

...

141 Commits

Author SHA1 Message Date
Julius Härtl
452f9a3312 Update CHANGELOG.md for 0.1.4
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2017-05-04 22:02:56 +02:00
Julius Härtl
95b0f49739 Bump version to 0.1.4
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2017-05-04 14:15:43 +02:00
Julius Härtl
b330f03a32 Merge pull request #118 from nextcloud/fix-acl-nonexisting
Do not fail on nonexisting acl users/groups
2017-05-04 14:12:28 +02:00
Julius Härtl
12ebffb885 Do not use getDisplayName for groups
it is not supported in Nextcloud 11

https://github.com/nextcloud/server/pull/4690
https://github.com/nextcloud/server/pull/2833
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2017-05-04 12:10:17 +02:00
Julius Härtl
860cbab1d3 Add proper error handling when user/group cannot be found
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2017-05-04 11:26:45 +02:00
Julius Härtl
c08455e11b Merge pull request #113 from nextcloud/delete-fix-and-undo
Fix deleting boards and add a simple undo function
2017-05-04 08:37:05 +02:00
Julius Härtl
a6b6842e2b No not fail on nonexisting acl users/groups
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2017-05-03 13:25:58 +02:00
Julius Härtl
588252d949 Fix deleting boards and add a simple undo function
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2017-05-03 13:22:30 +02:00
Julius Härtl
3b0390f50f Merge pull request #114 from nextcloud/firefox-red-input
Remove firefox invalid box shadow
2017-05-03 09:35:44 +02:00
Julius Härtl
c8389fbcb0 Remove firefox invalid box shadow
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2017-05-02 09:05:11 +02:00
Julius Härtl
94788bed39 Add IRC channel to README 2017-05-01 14:16:10 +02:00
Julius Härtl
8b4e7ec2bf Merge pull request #107 from nextcloud/release-0.1.3
Prepare 0.1.3 release
2017-05-01 10:04:13 +02:00
Julius Härtl
111a98ce88 Prepare 0.1.3 release
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2017-05-01 08:44:26 +02:00
Artem Anufrij
7fb0d2374d better behavior for comment field (#105)
* better behavior for comment field
* removed min-height

Signed-off-by: Artem Anufrij <artem.anufrij@live.de>
2017-05-01 08:35:31 +02:00
Nextcloud bot
491a73456b [tx-robot] updated from transifex 2017-05-01 00:10:29 +00:00
artemanufrij
62d671bdd5 hide sidebar when clicked outside (#102)
* hide sidebar when clicked outside

* fixed show/hide behavior

Signed-off-by: Artem Anufrij <artem.anufrij@live.de>
2017-04-30 21:23:48 +02:00
Julius Härtl
955c5eb864 Merge pull request #99 from nextcloud/bump-dependencies
Bump bower dependencies
2017-04-30 13:13:38 +02:00
Julius Härtl
49cd271cbc Add link to nightly builds 2017-04-30 13:07:49 +02:00
Julius Härtl
37bdbecdc2 Merge pull request #103 from nextcloud/nightly
Fix paths to use local bower/grunt installation
2017-04-30 13:03:25 +02:00
Julius Härtl
62af080e78 Fix paths to use local bower/grunt installation
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2017-04-30 12:57:10 +02:00
Julius Härtl
84d4b87bb8 Bump bower dependencies
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2017-04-30 09:37:04 +02:00
Julius Härtl
5ad515f42a Merge pull request #96 from nextcloud/fix-db-columns
Move text fields to clob
2017-04-29 13:20:16 +02:00
Julius Härtl
98b57fe0a4 Merge pull request #65 from nextcloud/test-behat
Add integration tests with behat
2017-04-29 13:08:18 +02:00
Julius Härtl
b961206da3 Include App integration test
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2017-04-29 13:04:00 +02:00
artemanufrij
d8d8137300 description marker (#98)
* description marker
* removed unused content
* removed unused content
* Changed Icon and removen unused .svg

Signed-off-by: Artem Anufrij <artem.anufrij@live.de>
2017-04-29 12:52:53 +02:00
Julius Haertl
56fcb081a4 Fix tests
Signed-off-by: Julius Haertl <jus@bitgrid.net>
2017-04-29 12:36:38 +02:00
Julius Haertl
2b9b22f2f2 Add behat tests to drone
Signed-off-by: Julius Haertl <jus@bitgrid.net>
2017-04-29 11:57:54 +02:00
Julius Haertl
084d892ce6 Add basic behat test structure
Signed-off-by: Julius Haertl <jus@bitgrid.net>
2017-04-29 11:57:54 +02:00
Julius Härtl
11610f306a Merge pull request #58 from nextcloud/displaynames
Implement relational mapping for users and groups to show displaynames
2017-04-29 11:57:21 +02:00
Julius Härtl
60e9cf7088 Apply maxlength to input fields and fix card header height
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2017-04-29 11:55:00 +02:00
Julius Härtl
7e345256cb Move text fields to clob
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2017-04-29 11:53:20 +02:00
Julius Härtl
52a7b8d560 Merge pull request #97 from pixelipo/fix-readme
Change app name in README.md
2017-04-28 15:31:47 +02:00
Marin Treselj
d98db33a02 Change app name in README.md
Signed-off-by: Marin Treselj <marin@pixelipo.com>
2017-04-28 13:26:13 +02:00
Julius Härtl
04f5e2c2e1 Don't show own user account
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2017-04-27 13:14:58 +02:00
Julius Härtl
74c8a6e848 Fix board acl type
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2017-04-27 13:08:25 +02:00
Julius Härtl
02eecb3a3f Use mapper classes for relational data
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2017-04-27 13:08:25 +02:00
Julius Haertl
1e9c86e158 Code cleaup
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2017-04-27 13:08:25 +02:00
Julius Haertl
2b05227f4b Add Group class
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2017-04-27 13:08:10 +02:00
Julius Haertl
3e304a9ff2 Use display name for users and groups
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2017-04-27 13:08:10 +02:00
Julius Härtl
000e447801 Merge pull request #95 from nextcloud/add-stack-header
Moved "Add a new Stack" into the top Bar [rebased]
2017-04-27 13:01:24 +02:00
Julius Härtl
1b6531e748 Fix positioning on Nextcloud 12
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2017-04-27 12:48:25 +02:00
artemanufrij
e2012dd2c5 Fixed css
Signed-off-by: Artem Anufrij <artem.anufrij@live.de>
2017-04-27 12:25:56 +02:00
artemanufrij
5346cc4042 Move add stack input to the header
Signed-off-by: Artem Anufrij <artem.anufrij@live.de>
2017-04-27 12:25:17 +02:00
Julius Härtl
22438f8f3e Merge pull request #94 from nextcloud/use-ocs-api
Use OCS API to search for users/groups
2017-04-27 12:18:52 +02:00
Julius Härtl
6033baca23 Remove old search endpoint
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2017-04-26 14:54:56 +02:00
Julius Härtl
c1ff005710 Use OCS API to search for users/groups
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2017-04-26 14:42:11 +02:00
Nextcloud bot
05adda1e03 [tx-robot] updated from transifex 2017-04-26 00:10:41 +00:00
Lukas Reschke
6ae6bdf74a Update issue_template.md 2017-04-18 12:40:53 +02:00
Nextcloud bot
35ea7255cb [tx-robot] updated from transifex 2017-04-15 00:10:36 +00:00
Nextcloud bot
c80deaaaee [tx-robot] updated from transifex 2017-04-14 00:10:39 +00:00
Nextcloud bot
ab60f4e3ab [tx-robot] updated from transifex 2017-04-07 00:12:08 +00:00
Nextcloud bot
965708e784 [tx-robot] updated from transifex 2017-04-06 00:11:00 +00:00
Nextcloud bot
1b364b4f85 [tx-robot] updated from transifex 2017-04-05 00:11:20 +00:00
Nextcloud bot
aad1cb4fb5 [tx-robot] updated from transifex 2017-04-04 00:10:27 +00:00
Nextcloud bot
99725765fc [tx-robot] updated from transifex 2017-03-31 00:11:14 +00:00
Nextcloud bot
f313a9ba6b [tx-robot] updated from transifex 2017-03-30 00:10:28 +00:00
Julius Härtl
6bbe0a3161 Merge pull request #80 from nextcloud/drone-only-master
Only build master branch
2017-03-28 14:02:26 +02:00
Julius Härtl
4414fdebd4 Only build master branch
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2017-03-28 13:49:19 +02:00
Julius Härtl
0c0b663b9e Merge pull request #77 from nextcloud/release-0.1.2
Bump version to 0.1.2
2017-03-27 20:29:31 +02:00
Julius Haertl
b6645cfaa1 Bump version to 0.1.2
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2017-03-27 20:16:15 +02:00
Nextcloud bot
9351a04eb3 [tx-robot] updated from transifex 2017-03-25 01:10:30 +00:00
Nextcloud bot
c1f828b894 [tx-robot] updated from transifex 2017-03-23 01:10:22 +00:00
Julius Härtl
cb233ba35b Merge pull request #75 from nextcloud/emoji-fix
Fix info.xml emoji usage
2017-03-22 17:04:16 +01:00
Marius Blüm
f09ce32f2b Fix info.xml emoji usage
Signed-off-by: Marius Blüm <marius@lineone.io>
2017-03-22 13:57:28 +01:00
Julius Härtl
1e359adf18 Merge pull request #66 from nextcloud/default-json
Add jsonSerialize method to RelationalEntity
2017-03-20 14:37:16 +01:00
Julius Haertl
34c1a681b1 Add jsonSerialize method to RelationalEntity
Signed-off-by: Julius Haertl <jus@bitgrid.net>
2017-03-20 14:26:03 +01:00
Julius Härtl
3324556542 Merge pull request #72 from nextcloud/fix-travis
Use phpunit 5.7
2017-03-20 09:57:08 +01:00
Julius Härtl
7dba354767 Remove npm install 2017-03-20 09:39:10 +01:00
Julius Härtl
8444a00bdf Travis fix
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2017-03-20 09:28:24 +01:00
Julius Härtl
021b186424 Use phpunit 5.7
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2017-03-20 08:53:17 +01:00
Nextcloud bot
3e38ed7108 [tx-robot] updated from transifex 2017-03-17 01:10:07 +00:00
Julius Härtl
5d95dbf1ff Merge pull request #68 from nextcloud/travis
Disable email notifications for travis
2017-03-16 11:54:24 +01:00
Nextcloud bot
f17b046cb1 [tx-robot] updated from transifex 2017-03-12 01:10:43 +00:00
Nextcloud bot
7d55d22d42 [tx-robot] updated from transifex 2017-03-11 01:10:04 +00:00
Nextcloud bot
138c03160e [tx-robot] updated from transifex 2017-03-06 01:10:03 +00:00
Julius Haertl
286d4d7900 Disable email notifications for travis
Signed-off-by: Julius Haertl <jus@bitgrid.net>
2017-03-05 14:21:21 +01:00
Julius Härtl
3f6f80ce44 Merge pull request #67 from nextcloud/debug-js
Include source js files when debug is enabled
2017-03-05 14:14:13 +01:00
Julius Härtl
7d7c605d36 Merge pull request #62 from SpaceCafe/master
Fixed SQL statements without prefixes
2017-03-05 14:00:01 +01:00
Julius Haertl
1d966033ec Update javascript section in README
Signed-off-by: Julius Haertl <jus@bitgrid.net>
2017-03-05 13:53:05 +01:00
Julius Haertl
9de4051803 Include source js files when debug is enabled
Signed-off-by: Julius Haertl <jus@bitgrid.net>
2017-03-05 13:46:38 +01:00
SpaceCafe
a2a3d8cae7 Merge branch 'master' into master
Signed-off-by: Lars Thoms <lars.thoms@spacecafe.org>
2017-03-04 20:48:12 +01:00
Lars Thoms
873e7cb1cf Fixed SQL statements without prefixes
Signed-off-by: Lars Thoms <lars.thoms@spacecafe.org>
2017-03-04 20:40:23 +01:00
Julius Härtl
4766195872 Merge pull request #64 from nextcloud/contribution-guidelines
Add contribution guidelines to README
2017-03-04 12:49:01 +01:00
Julius Härtl
c35f6aa9ef Add contribution guidelines to README 2017-03-04 12:47:26 +01:00
Julius Härtl
59ec9a15ff Merge pull request #61 from nextcloud/fix-legacy-code
use non-deprecated code in tests
2017-03-03 15:04:42 +01:00
Julius Härtl
81cd17cf3a Merge branch 'master' into fix-legacy-code 2017-03-03 13:07:15 +01:00
Julius Härtl
7ce44deb91 Merge pull request #59 from nextcloud/drone
Use drone for testing
2017-03-03 13:04:57 +01:00
Morris Jobke
96f5f5fe45 use non-deprecated code in tests
Signed-off-by: Morris Jobke <hey@morrisjobke.de>
2017-03-03 01:30:44 -06:00
Nextcloud bot
5c8d7b7644 [tx-robot] updated from transifex 2017-03-03 01:09:45 +00:00
Nextcloud bot
5136615650 [tx-robot] updated from transifex 2017-03-02 16:51:02 +00:00
Julius Haertl
3e3b120175 Add js build and remove tests from travis
Signed-off-by: Julius Haertl <jus@bitgrid.net>
2017-03-02 11:32:12 +01:00
Julius Härtl
fef35d3929 Merge pull request #60 from nextcloud/transifex-update
Update transifex config
2017-03-02 11:04:22 +01:00
Morris Jobke
2a483b6f92 Update transifex config
Signed-off-by: Morris Jobke <hey@morrisjobke.de>
2017-03-01 22:48:17 -06:00
Nextcloud bot
f34250ca67 [tx-robot] updated from transifex 2017-03-02 01:09:30 +00:00
Nextcloud bot
308ade1b6e [tx-robot] updated from transifex 2017-03-01 01:09:42 +00:00
Julius Haertl
cf03e08d1e Use drone for testing
Signed-off-by: Julius Haertl <jus@bitgrid.net>
2017-02-28 18:35:32 +01:00
Julius Härtl
90e0c57224 Merge pull request #57 from nextcloud/exception-logging
Improve logging of exceptions catched by SharingMiddleware
2017-02-27 11:45:38 +01:00
Julius Haertl
15e5a432b6 Improve logging of exceptions catched by SharingMiddleware 2017-02-27 11:27:49 +01:00
Julius Härtl
5372458288 Merge pull request #56 from roipoussiere/label_title
Add on label tiles a tooltip with the label name.
2017-02-27 09:59:26 +01:00
Nathanaël Jourdane
2d7e6f2efa Add on label tiles a tooltip with the label name. 2017-02-26 14:17:26 +01:00
Nextcloud bot
67f26ef9b2 [tx-robot] updated from transifex 2017-02-25 01:27:26 +00:00
Nextcloud bot
153fb6a0f0 [tx-robot] updated from transifex 2017-02-24 01:23:55 +00:00
Nextcloud bot
61b7228fb6 [tx-robot] updated from transifex 2017-02-23 01:21:00 +00:00
Julius Härtl
d2a2d7a63a Merge pull request #55 from nextcloud/move-repo
Move repo to nextcloud org
2017-02-22 10:36:17 +01:00
Julius Haertl
db90911e5e Move repo to nextcloud org
Signed-off-by: Julius Haertl <jus@bitgrid.net>
2017-02-22 10:12:25 +01:00
Nextcloud bot
a636b106c8 [tx-robot] updated from transifex 2017-02-22 01:14:29 +00:00
Morris Jobke
1e19c44665 Merge pull request #54 from nextcloud/transifex
add transifex config
2017-02-21 10:31:19 -06:00
Morris Jobke
c308087c4a add transifex config
Signed-off-by: Morris Jobke <hey@morrisjobke.de>
2017-02-21 10:20:49 -06:00
Julius Härtl
cb5cfe1c73 Merge pull request #51 from juliushaertl/safari-fix
Remove duplicate endtag and fix layout in safari
2017-02-15 07:44:38 +01:00
Julius Haertl
3a311197a8 Remove duplicate endtag and fix layout in safari 2017-02-14 22:11:15 +01:00
Julius Haertl
b5feeeaee3 Fix group acl entries being interpreted as users 2017-02-13 22:06:27 +01:00
Julius Härtl
8e890df7ab Add issue template 2017-02-10 10:45:21 +01:00
Julius Haertl
d88f561adb Require the correct css file 2017-02-07 00:16:54 +01:00
Julius Haertl
65eb63d742 Bump version to 0.1.1 2017-02-06 23:44:08 +01:00
Julius Härtl
cde350decf Merge pull request #42 from juliushaertl/prepare-appstore-release
Release preparations for 0.1.1
2017-02-06 23:42:17 +01:00
Julius Härtl
ba3d98a8e4 Merge pull request #41 from juliushaertl/styling-improvements
Design improvements on select2 boxes and css cleanup
2017-02-06 23:37:21 +01:00
Julius Härtl
3b7a83d2a4 Merge branch 'master' into styling-improvements 2017-02-06 23:27:19 +01:00
Julius Haertl
eaf8402d31 Update changelog 2017-02-06 23:26:33 +01:00
Julius Härtl
b710bd00a7 Merge pull request #40 from juliushaertl/fix-card-dragging
Add ng-sortable css to fix #38
2017-02-06 23:19:20 +01:00
Julius Haertl
bf94f787c3 More CSS cleanup 2017-02-06 23:17:42 +01:00
Julius Haertl
d74b9f68d9 Use select2 styles from Nextcloud server 2017-02-06 22:57:35 +01:00
Julius Härtl
198e443a24 Merge pull request #33 from juliushaertl/fix-acl-create
Use integer values for Acl type
2017-02-06 22:53:05 +01:00
Julius Haertl
cb073897c3 Prepare for appstore release 2017-02-06 13:14:02 +01:00
Julius Haertl
cba8112ff6 Add ng-sortable css to fix #38 2017-02-05 23:41:21 +01:00
Julius Härtl
f8c2d86e4f Merge pull request #38 from juliushaertl/cleanup-debug
Remove debug logging and unused function
2017-02-05 23:04:25 +01:00
Julius Härtl
dd612a0c5e Merge pull request #23 from juliushaertl/styling-fixes
Styling fixes
2017-02-05 22:55:38 +01:00
Julius Haertl
8342e1f99a Remove debug logging and unused function 2017-02-05 22:53:28 +01:00
Julius Haertl
f604f2f779 Remove another string representation 2017-02-05 22:46:29 +01:00
Julius Haertl
2fd10f9201 CSS cleanup 2017-02-03 18:41:26 +01:00
Julius Haertl
0333f31b9a Move to int values for permission type checks 2017-02-03 18:38:01 +01:00
Julius Haertl
dfe8bad832 Do not return string on Acl type getter 2017-02-03 18:35:41 +01:00
Julius Härtl
161a6715da Merge pull request #26 from juliushaertl/select-first-color
Always select the first color when creating a board
2017-02-02 18:46:32 +01:00
Julius Härtl
929ed247c9 Merge pull request #24 from juliushaertl/fix-acl-permissioncheck
Fix check for acl permissions
2017-02-02 18:40:05 +01:00
Julius Härtl
54c6d669f5 Merge branch 'master' into select-first-color 2017-02-02 18:33:00 +01:00
Julius Härtl
fdb7b7fb98 Merge branch 'master' into fix-acl-permissioncheck 2017-02-02 18:31:15 +01:00
Julius Haertl
8375108412 Run js stuff only once on travis 2017-02-02 18:30:59 +01:00
Julius Haertl
b6d057a284 Always select first color fixes #19 2017-02-01 19:10:38 +01:00
Julius Haertl
37437c1d76 Fix check for acl permissions 2017-02-01 18:52:34 +01:00
Julius Haertl
9f61417a58 Use server select2 styles 2017-02-01 18:51:47 +01:00
Julius Haertl
e05c2469b4 Add active class to appmenu 2017-02-01 18:51:09 +01:00
Julius Haertl
2085e9b300 Remove unneeded stuff 2017-02-01 16:32:21 +01:00
116 changed files with 4300 additions and 857 deletions

173
.drone.yml Normal file
View File

@@ -0,0 +1,173 @@
pipeline:
clone:
image: plugins/git
depth: 1
check-app-compatbility:
image: nextcloudci/php5.6:php5.6-3
environment:
- APP_NAME=deck
- CORE_BRANCH=master
- DB=sqlite
commands:
# Pre-setup steps
- wget https://raw.githubusercontent.com/nextcloud/travis_ci/master/before_install.sh
- bash ./before_install.sh $APP_NAME $CORE_BRANCH $DB
- cd ../server
# Code checker
- ./occ app:check-code $APP_NAME -c strong-comparison
- ./occ app:check-code $APP_NAME -c deprecation
- cd apps/$APP_NAME/
when:
matrix:
TESTS: check-app-compatbility
signed-off-check:
image: nextcloudci/php7.0:php7.0-2
environment:
- APP_NAME=deck
- CORE_BRANCH=master
- DB=sqlite
commands:
- wget https://raw.githubusercontent.com/nextcloud/travis_ci/master/before_install.sh
- bash ./before_install.sh $APP_NAME $CORE_BRANCH $DB
- cd ../server
- php ./build/signed-off-checker.php
when:
matrix:
TESTS: signed-off-check
syntax-php5.6:
image: nextcloudci/php5.6:php5.6-3
environment:
- APP_NAME=deck
- CORE_BRANCH=master
- DB=sqlite
commands:
# Pre-setup steps
- wget https://raw.githubusercontent.com/nextcloud/travis_ci/master/before_install.sh
- bash ./before_install.sh $APP_NAME $CORE_BRANCH $DB
- cd ../server
- composer install
- ./lib/composer/bin/parallel-lint --exclude lib/composer/jakub-onderka/ --exclude 3rdparty/symfony/polyfill-php70/Resources/stubs/ --exclude 3rdparty/patchwork/utf8/src/Patchwork/Utf8/Bootup/ --exclude 3rdparty/paragonie/random_compat/lib/ --exclude lib/composer/composer/autoload_static.php --exclude 3rdparty/composer/autoload_static.php .
when:
matrix:
TESTS: syntax-php5.6
syntax-php7.0:
image: nextcloudci/php7.0:php7.0-2
environment:
- APP_NAME=deck
- CORE_BRANCH=master
- DB=sqlite
commands:
# Pre-setup steps
- wget https://raw.githubusercontent.com/nextcloud/travis_ci/master/before_install.sh
- bash ./before_install.sh $APP_NAME $CORE_BRANCH $DB
- cd ../server
- composer install
- ./lib/composer/bin/parallel-lint --exclude lib/composer/jakub-onderka/ --exclude 3rdparty/symfony/polyfill-php70/Resources/stubs/ --exclude 3rdparty/patchwork/utf8/src/Patchwork/Utf8/Bootup/ --exclude 3rdparty/paragonie/random_compat/lib/ --exclude lib/composer/composer/autoload_static.php --exclude 3rdparty/composer/autoload_static.php .
when:
matrix:
TESTS: syntax-php7.0
php5.6:
image: nextcloudci/php5.6:php5.6-3
environment:
- APP_NAME=deck
- CORE_BRANCH=master
- DB=sqlite
commands:
- apt update && apt-get -y install php5-xdebug
# Pre-setup steps
- wget https://raw.githubusercontent.com/nextcloud/travis_ci/master/before_install.sh
- bash ./before_install.sh $APP_NAME $CORE_BRANCH $DB
- cd ../server/
- ./occ app:enable $APP_NAME
- cd apps/$APP_NAME
- phpunit -c tests/phpunit.xml --coverage-clover build/php-unit.coverage.xml
- phpunit -c tests/phpunit.integration.xml --coverage-clover build/php-integration.coverage.xml
# Create coverage report
- wget https://codecov.io/bash -O codecov.sh
- sh -c "if [ '$DRONE_BUILD_EVENT' = 'pull_request' ]; then bash codecov.sh -B $DRONE_BRANCH -C $DRONE_COMMIT -P $DRONE_PULL_REQUEST -t f6375299-4832-487e-b831-091772ab0384; fi"
- sh -c "if [ '$DRONE_BUILD_EVENT' != 'pull_request' ]; then bash codecov.sh -B $DRONE_BRANCH -C $DRONE_COMMIT -t f6375299-4832-487e-b831-091772ab0384; fi"
when:
matrix:
TESTS: php5.6
php7.0:
image: nextcloudci/php7.0:php7.0-7
environment:
- APP_NAME=deck
- CORE_BRANCH=master
- DB=sqlite
commands:
# Pre-setup steps
- wget https://raw.githubusercontent.com/nextcloud/travis_ci/master/before_install.sh
- bash ./before_install.sh $APP_NAME $CORE_BRANCH $DB
- cd ../server/
- php occ app:enable deck
- cd apps/$APP_NAME
# Run phpunit tests
- phpunit -c tests/phpunit.xml --coverage-clover build/php-unit.coverage.xml
- phpunit -c tests/phpunit.integration.xml --coverage-clover build/php-integration.coverage.xml
when:
matrix:
TESTS: php7.0
php7.1:
image: nextcloudci/php7.1:php7.1-11
environment:
- APP_NAME=deck
- CORE_BRANCH=master
- DB=sqlite
commands:
# Pre-setup steps
- yum -y install wget
- wget https://raw.githubusercontent.com/nextcloud/travis_ci/master/before_install.sh
- bash ./before_install.sh $APP_NAME $CORE_BRANCH $DB
- cd ../server/
- php occ app:enable deck
- cd apps/$APP_NAME
- phpunit -c tests/phpunit.xml --coverage-clover build/php-unit.coverage.xml
- phpunit -c tests/phpunit.integration.xml --coverage-clover build/php-integration.coverage.xml
when:
matrix:
TESTS: php7.1
integration:
image: nextcloudci/integration-php7.0:integration-php7.0-3
environment:
- APP_NAME=deck
- CORE_BRANCH=master
- DB=sqlite
commands:
# Pre-setup steps
- wget https://raw.githubusercontent.com/nextcloud/travis_ci/master/before_install.sh
- bash ./before_install.sh $APP_NAME $CORE_BRANCH $DB
- cd ../server/
- php occ app:enable deck
- cd apps/$APP_NAME
- cd tests/integration
- ./run.sh
when:
matrix:
TESTS: integration
jsbuild:
image: mhart/alpine-node:6.8.0
commands:
- apk add --no-cache git
- cd js
- npm install --deps
- ./node_modules/.bin/bower --allow-root install
when:
matrix:
TESTS: jsbuild
matrix:
include:
- TESTS: check-app-compatbility
- TESTS: signed-off-check
- TESTS: syntax-php5.6
- TESTS: syntax-php7.0
- TESTS: php5.6
- TESTS: php7.0
- TESTS: php7.1
- TESTS: jsbuild
- TESTS: integration
branches: [ master, stable* ]

3
.gitignore vendored
View File

@@ -1,3 +1,6 @@
js/node_modules/*
js/vendor/
build/
js/public/
tests/integration/vendor/
tests/integration/composer.lock

View File

@@ -6,31 +6,30 @@ php:
- 7
env:
matrix:
- CORE_BRANCH=master DB=sqlite
- CORE_BRANCH=master DB=mysql
- CORE_BRANCH=stable11 DB=sqlite
- CORE_BRANCH=stable11 DB=mysql
before_install:
- wget https://phar.phpunit.de/phpunit-5.7.phar
- chmod +x phpunit-5.7.phar
- mkdir bin
- sudo mv phpunit-5.7.phar bin/phpunit
- export PATH="$PWD/bin:$PATH"
- phpunit --version
- wget https://raw.githubusercontent.com/nextcloud/travis_ci/master/before_install.sh
- bash ./before_install.sh deck $CORE_BRANCH $DB
- cd ../server
- ./occ app:enable deck
- ./occ app:check-code deck
- php -S localhost:8080 &
before_script:
- cd apps/deck
- make install-deps
script:
- node --version
- npm --version
- make build-js
- make test
- make test-unit
after_failure:
- cat ../../data/nextcloud.log
after_success:
- bash <(curl -s https://codecov.io/bash)
notifications:
email: false

View File

@@ -1,3 +1,52 @@
# Changelog
All notable changes to this project will be documented in this file.
## 0.1.4
### Fixed
- Avoid red shadow on input in firefox
- Fix broken delete function for boards
- Fix broken board loading when groups were used for sharing
- Fix bug when users/groups got deleted
## 0.1.3 - 2017-05-01
### Added
- Icon to show if a card has a description
### Changed
- Use OCS API to get users/groups for sharing
- Various UI improvements
- Show display name instead of uid
- Fix bugs with limited field length
- Automatically hide sidebar when clicking the board view
- Start editing from everywhere in the description section
## 0.1.2
### Added
- Add translations
### Fixed
- Fix issues with Acl checks
- Always select first color fixes
- Add active class to appmenu
- Use server select2 styles
- Remove debug logging and unused function
- Fix issue while sorting cards
- Improve logging of exceptions
- Fixed SQL statements without prefixes
## 0.1.1
### Fixed
- Various styling improvements
- Fix problems with MySQL and PostgreSQL
- Select first color by default when creating boards
- Fix error when changing board permissions
## 0.1.0
### Added
- Sharing boards with other users

View File

@@ -23,7 +23,7 @@ clean-dist:
install-deps:
cd js && npm install --deps
cd js && bower install
cd js && ./node_modules/.bin/bower install
build: build-js
@@ -69,17 +69,24 @@ appstore: clean-build build
echo $(appstore_package_name).tar.gz
test: test-unit test-integration
test:
test-unit:
mkdir -p build/
cd js && $(npm) run test
ifeq (, $(shell which phpunit 2> /dev/null))
@echo "No phpunit command available, downloading a copy from the web"
mkdir -p $(build_tools_directory)
curl -sSL https://phar.phpunit.de/phpunit.phar -o $(build_tools_directory)/phpunit.phar
curl -sSL https://phar.phpunit.de/phpunit-5.7.phar -o $(build_tools_directory)/phpunit.phar
php $(build_tools_directory)/phpunit.phar -c tests/phpunit.xml --coverage-clover build/php-unit.coverage.xml
php $(build_tools_directory)/phpunit.phar -c tests/phpunit.integration.xml --coverage-clover build/php-integration.coverage.xml
else
phpunit -c tests/phpunit.xml --coverage-clover build/php-unit.coverage.xml
phpunit -c tests/phpunit.integration.xml --coverage-clover build/php-integration.coverage.xml
endif
test-integration:
cd tests/integration && ./run.sh
test-js: install-deps
cd js && run test

View File

@@ -1,6 +1,7 @@
# Deck
[![Build Status](https://travis-ci.org/juliushaertl/deck.svg?branch=master)](https://travis-ci.org/juliushaertl/deck) [![CodeCov](https://codecov.io/github/juliushaertl/deck/coverage.svg?branch=master)](https://codecov.io/github/juliushaertl/deck) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/juliushaertl/deck/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/juliushaertl/deck/?branch=master) [![Dependency Status](https://www.versioneye.com/user/projects/58908fc0a23e810038c34e0a/badge.svg?style=flat)](https://www.versioneye.com/user/projects/58908fc0a23e810038c34e0a)
[![Build Status](https://travis-ci.org/nextcloud/deck.svg?branch=master)](https://travis-ci.org/nextcloud/deck) [![CodeCov](https://codecov.io/github/nextcloud/deck/coverage.svg?branch=master)](https://codecov.io/github/nextcloud/deck) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/nextcloud/deck/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/nextcloud/deck/?branch=master) [![Dependency Status](https://www.versioneye.com/user/projects/58ad558f4ca76f004ed475b3/badge.svg?style=flat)](https://www.versioneye.com/user/projects/58ad558f4ca76f004ed475b3) [![#nextcloud-deck](https://img.shields.io/badge/IRC-%23nextcloud--deck%20on%20freenode-blue.svg)](https://webchat.freenode.net/?channels=nextcloud-deck)
Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.
@@ -11,9 +12,9 @@ Deck is a kanban style organization tool aimed at personal planning and project
- :rocket: Get your project organized
![Deck - Manage cards on your board](https://bitgrid.net/~jus/deck.png)
![Deck - Manage cards on your board](https://bitgrid.net/~jus/deck_1.png)
:boom: This is still alpha software: it may not be stable enough for production
:boom: This is still alpha software: it may not be stable enough for production
### Planned features
@@ -29,14 +30,14 @@ This app is supposed to work on Nextcloud version 11 or later.
### Install latest release
Grab the latest release over here, extract it to your Nextcloud apps folder and enable the app.
You can download and install the latest release from the [Nextcloud app store](https://apps.nextcloud.com/apps/deck)
### Install from git
### Install from git
If you want to run the latest development version from git source, you need to clone the repo to your apps folder:
```
git clone https://github.com/juliushaertl/deck.git
git clone https://github.com/nextcloud/deck.git
cd deck
make install-deps
make
@@ -44,6 +45,10 @@ make
Please make sure you have installed the following dependencies: `make, which, tar, npm, curl`
### Install the nightly builds
Instead of setting everything up manually, you can just [download the nightly builds](https://download.bitgrid.net/nextcloud/deck/nightly/) instead. These builds are updated every 24 hours, and are pre-configured with all the needed dependencies.
## Developing
### PHP
@@ -52,9 +57,54 @@ Nothing to prepare, just dig into the code.
### JavaScript
Make sure you have installed the dependencies with ```make install-deps```. After that you can run ```make``` to build the javascript code once or run ```make watch``` to run in on every file change.
When `'debug'=>true` is set in your config.php files will get loaded automatically. Otherwise you need to ensure that `public/app.js` is generated by running `make` or `make watch` to regenerate it on every change.
Make sure you have installed the dependencies with ```make install-deps```.
### Running tests
You can use the provided Makefile to run all tests by using:
make test
## Contribution Guidelines
Please read the [Code of Conduct](https://nextcloud.com/community/code-of-conduct/). This document offers some guidance to ensure Nextcloud participants can cooperate effectively in a positive and inspiring atmosphere, and to explain how together we can strengthen and support each other.
For more information please review the [guidelines for contributing](https://github.com/nextcloud/server/blob/master/CONTRIBUTING.md) to this repository.
### Apply a license
All contributions to this repository are considered to be licensed under
the GNU AGPLv3 or any later version.
Contributors to the Deck app retain their copyright. Therefore we recommend
to add following line to the header of a file, if you changed it substantially:
```
@copyright Copyright (c) <year>, <your name> (<your email address>)
```
For further information on how to add or update the license header correctly please have a look at [our licensing HowTo][applyalicense].
### Sign your work
We use the Developer Certificate of Origin (DCO) as a additional safeguard
for the Nextcloud project. This is a well established and widely used
mechanism to assure contributors have confirmed their right to license
their contribution under the project's license.
Please read [developer-certificate-of-origin][dcofile].
If you can certify it, then just add a line to every git commit message:
````
Signed-off-by: Random J Developer <random@developer.example.org>
````
Use your real name (sorry, no pseudonyms or anonymous contributions).
If you set your `user.name` and `user.email` git configs, you can sign your
commit automatically with `git commit -s`. You can also use git [aliases](https://git-scm.com/book/tr/v2/Git-Basics-Git-Aliases)
like `git config --global alias.ci 'commit -s'`. Now you can commit with
`git ci` and the commit will be signed.
[dcofile]: https://github.com/nextcloud/server/blob/master/contribute/developer-certificate-of-origin
[applyalicense]: https://github.com/nextcloud/server/blob/master/contribute/HowToApplyALicense.md

View File

@@ -19,7 +19,7 @@
<name>title</name>
<type>text</type>
<notnull>true</notnull>
<length>64</length>
<length>100</length>
</field>
<field>
<name>owner</name>
@@ -55,7 +55,7 @@
<name>title</name>
<type>text</type>
<notnull>true</notnull>
<length>64</length>
<length>100</length>
</field>
<field>
<name>board_id</name>
@@ -97,14 +97,13 @@
<field>
<name>title</name>
<type>text</type>
<length>100</length>
<notnull>true</notnull>
<length>64</length>
</field>
<field>
<name>description</name>
<type>text</type>
<type>clob</type>
<notnull>false</notnull>
<length>4096</length>
</field>
<field>
<name>stack_id</name>
@@ -187,7 +186,7 @@
<name>title</name>
<type>text</type>
<notnull>true</notnull>
<length>64</length>
<length>100</length>
</field>
<field>
<name>card_id</name>
@@ -239,7 +238,7 @@
<name>title</name>
<type>text</type>
<notnull>false</notnull>
<length>64</length>
<length>100</length>
</field>
<field>
<name>color</name>

View File

@@ -7,25 +7,32 @@
<description>Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.
- :inbox_tray: Add your tasks to cards and put them in order
- :page_facing_up: Write down additional notes in markdown
- :bookmark: Assign labels for even better organization
- :busts_in_silhouette: Share with your team, friends or family
- :rocket: Get your project organized
- 📥 Add your tasks to cards and put them in order
- 📄 Write down additional notes in markdown
- 🔖 Assign labels for even better organization
- 👥 Share with your team, friends or family
- 🚀 Get your project organized
:boom: This is still alpha software: it may not be stable enough for production!
💥 This is still alpha software: it may not be stable enough for production!
</description>
<version>0.1.4</version>
<licence>agpl</licence>
<author>Julius Härtl</author>
<version>0.1.0</version>
<namespace>Deck</namespace>
<category>organization</category>
<category>office</category>
<bugs>https://github.com/nextcloud/deck/issues</bugs>
<repository type="git">https://github.com/nextcloud/deck.git</repository>
<screenshot>https://bitgrid.net/~jus/deck_1.png</screenshot>
<screenshot>https://bitgrid.net/~jus/deck_2.png</screenshot>
<screenshot>https://bitgrid.net/~jus/deck_3.png</screenshot>
<dependencies>
<nextcloud min-version="11" max-version="12" />
</dependencies>
<repository type="git">https://github.com/juliushaertl/deck.git</repository>
<bugs>https://github.com/juliushaertl/deck/issues</bugs>
<screenshot>https://bitgrid.net/~jus/deck.png</screenshot>
<repair-steps>
<post-migration>
<step>OCA\Deck\Migration\UnknownUsers</step>
</post-migration>
</repair-steps>
</info>

View File

@@ -25,9 +25,6 @@ return [
'routes' => [
['name' => 'page#index', 'url' => '/', 'verb' => 'GET'],
// share
['name' => 'share#searchUser', 'url' => '/share/search/{search}', 'verb' => 'GET'],
// boards
['name' => 'board#index', 'url' => '/boards', 'verb' => 'GET'],
['name' => 'board#create', 'url' => '/boards', 'verb' => 'POST'],

View File

@@ -2,6 +2,7 @@
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
* @author Artem Anufrij <artem.anufrij@live.de>
*
* @license GNU AGPL version 3 or any later version
*
@@ -20,10 +21,44 @@
*
*/
/**
* General styles
*/
.app-deck .icon {
display: inline-block;
}
input.input-inline {
font-size: inherit !important;
font-weight: inherit;
background-color: transparent;
padding: 0;
border: none;
width: 100%;
border-bottom: 1px solid #333333;
-webkit-border-radius: 0;
line-height: 100%;
margin: -4px 0;
}
button {
border: 0;
background-color: transparent;
}
button:hover {
border: 0;
background-color: transparent;
}
#searchbox {
display: block !important;
}
/**
* Navigation sidebar
*/
.app-navigation-entry-utils-menu-button {
display: block !important;
}
@@ -40,16 +75,6 @@
height: auto;
}
#app-navigation .active,
#app-navigation .active a,
#app-navigation li:hover > a,
#app-navigation li:focus > a,
#app-navigation a:focus,
#app-navigation .selected,
#app-navigation .selected a {
background-color: #fafafa;
}
#app-navigation .board-bullet {
position: absolute;
margin-left: 17px;
@@ -61,16 +86,17 @@
cursor: pointer;
}
#app-view {
position: relative;
height: 100%;
white-space: nowrap;
overflow: none;
padding: 0;
z-index: 100;
width: 100%;
#app-navigation .app-navigation-entry-utils li.board-delete-undo {
background-color: #aa0000;
color: #fff;
cursor: pointer;
width: auto !important;
}
/**
* Board view
*/
#board-status {
position: absolute;
z-index: 999;
@@ -82,11 +108,10 @@
#board {
position: relative;
height: 100%;
white-space: nowrap; /* important */
white-space: nowrap;
overflow: auto;
padding: 0;
top: -40px;
padding-top: 40px;
padding: 40px 0 0;
z-index: 100;
width: 100%;
}
@@ -108,7 +133,7 @@
font-size: 14pt;
margin: 0;
padding: 12px;
float: left;
float: left;
}
#board-actions {
@@ -116,8 +141,7 @@
float: right;
position: relative;
color: #888;
margin:8px;
margin: 8px;
}
#board-actions .filter .filter-button {
@@ -130,9 +154,6 @@
cursor: pointer;
}
.filter {
}
.filter-select {
position: absolute;
right: auto;
@@ -162,7 +183,6 @@
.board-actions button {
border: none;
background-color: transparent;
color: #fff;
}
.board-action-button {
@@ -172,6 +192,40 @@
margin-left: 10px;
}
#stack-add {
float: right;
margin: 8px;
background-color: #ffffff;
border: 1px solid #bbb;
border-radius: 4px;
}
#stack-add input {
padding: 4px 5px;
margin: 0px;
border: 0px none transparent;
display: table-cell;
vertical-align: middle;
min-height: initial;
}
#stack-add input:invalid {
box-shadow: none;
}
#stack-add input:-moz-submit-invalid {
box-shadow: none;
}
#stack-add input:-moz-ui-invalid {
box-shadow:none;
}
#stack-add button {
display: table-cell;
vertical-align: middle;
}
.stack {
width: 320px;
margin-right: 10px;
@@ -181,8 +235,7 @@
}
.stack h2 {
padding:10px;
padding-bottom: 8px;
padding: 10px 10px 8px;
margin: 0;
font-size: 12pt;
font-weight: 700;
@@ -191,7 +244,7 @@
}
.stack h2 input {
padding: 0px;
padding: 0;
width: 80%;
margin: 0;
font-size: 12pt;
@@ -199,6 +252,7 @@
border: 0;
background-color: transparent;
float: left;
min-height: initial;
}
.stack h2 button,
@@ -225,7 +279,7 @@
white-space: normal;
position: relative;
opacity: 1.0;
-webkit-box-shadow: 0px 0px 5px #bbb;
-webkit-box-shadow: 0 0 5px #bbb;
}
.card.archived .card-upper {
@@ -275,7 +329,6 @@
.card h3 {
font-weight: bold;
font-size: 10pt;
margin: 0;
padding: 0;
margin: 5px;
display: inline-block;
@@ -286,12 +339,6 @@
margin-top: 15px;
}
.card h3 .fa {
font-size: 18pt;
line-height: 10pt;
vertical-align: middle;
}
.card .labels {
position: absolute;
top: -5px;
@@ -300,13 +347,12 @@
}
.card .labels li {
padding: 0px;
padding: 0;
width: 15px;
height: 20px;
-webkit-border-radius: 3px;
font-size: 80%;
border-color: transparent;
border: none;
border: none transparent;
float: left;
}
@@ -346,12 +392,10 @@
.card.create {
text-align: center;
margin: 0;
padding: 0;
padding: 10px;
margin: 10px;
border: none;
overflow: hidden;
margin: 10px;
-webkit-box-shadow: none;
}
@@ -361,56 +405,45 @@
}
.card.create h3 {
margin: 0;
padding: 0;
width: 100%;
padding: 0;
margin: 0 0 1px;
}
.card.create h3 input {
width: 100%;
border: 0px;
padding: 0px;
margin: 0px;
border: 0;
font-weight: bold;
font-size: 10pt;
margin: 0;
padding: 0;
border-bottom: 1px solid #ffffff;
border-radius: 0px;
border-radius: 0;
color: #ffffff;
background-color: transparent !important;
}
.card.create .fa {
color: #ffffff;
width: 100%;
}
.card.create .fa:hover {
opacity: 0.5;
cursor: pointer;
min-height: initial;
}
.due {
background-color: #eee;
color: #aaa;
padding: 1px;
padding-left: 3px;
padding-right: 3px;
padding: 1px 3px;
border-radius: 4px;
margin-right: 2px;
}
/**
* Card view right sidebar
*/
#card-header {
height: 44px;
}
#card-header h2 {
font-size: 14pt;
padding: 10px;
padding-bottom: 9px;
padding: 10px 10px 9px;
overflow: hidden;
margin-bottom: 0px;
margin-bottom: 0;
background-color: #f0f0f0;
}
@@ -421,7 +454,9 @@
}
#card-meta {
padding-top: 0px;
height: 100%;
display: flex;
flex-direction: column;
}
#card-dates {
@@ -437,6 +472,12 @@
#card-dates span {
}
#card-description {
height: 100%;
display: flex;
flex-direction: column;
}
#card-description > h3 {
border-bottom: 1px solid #333333;
font-weight: 600;
@@ -444,40 +485,30 @@
padding: 5px;
}
.save-indicator {
background-color: #009900;
color: #ffffff;
border-radius: 3px;
float:right;
padding:1px 10px;
font-size: 8pt !important;
display:none;
#card-description > div {
height: 100%;
}
#card-description textarea {
width: 100%;
height: 200px;
border: none;
margin: 0px;
padding: 0px;
margin: 0;
padding: 0;
}
#card-description .container {
background-color: white;
}
#card-description .container.ng-hide-remove {
animation: fade 1s forwards;
background-color: rgba(255, 255, 100, 1);
}
@keyframes fade {
from {
background-color: rgba(255, 255, 100, 1);
}
to {
background-color: rgba(255, 255, 255, 0);
}
.save-indicator {
background-color: #009900;
color: #ffffff;
border-radius: 3px;
float: right;
padding: 1px 10px;
font-size: 8pt !important;
display: none;
}
#sidebar-header,
@@ -504,13 +535,13 @@
max-width: 100%;
border-left: none;
width: 500px;
/*box-shadow: 0px 0px 5px 0px #aaa;*/
border-left: 1px solid #eeeeee;
display:flex;
flex-direction: column;
}
#app-sidebar.details-visible {
right: 0px;
right: 0;
}
#app-content {
@@ -539,10 +570,6 @@
text-align: center;
}
.labels li span {
}
.avatardiv {
float: left;
background-color: #eee;
@@ -558,14 +585,17 @@
display: block !important;
}
/* color selector */
/**
* Color selection
*/
.colorselect {
overflow: hidden;
clear:both;
padding-top:4px;
clear: both;
padding-top: 4px;
padding-left: 4px;
}
.colorselect .color {
opacity: 0.7;
width: 27px;
@@ -585,11 +615,15 @@
clear: none;
overflow: visible;
}
.labels .colorselect .color {
width:26px;
height:26px;
width: 26px;
height: 26px;
}
/**
* Board list main screen area
*/
#boardlist {
width: 100%;
height: 100%;
@@ -635,33 +669,47 @@
margin-top: 5px;
}
input.input-inline {
font-size: inherit !important;
font-weight: inherit;
background-color: transparent;
/**
* Board details
*/
#shareWithList {
list-style-type: none;
padding: 0 0 16px;
}
#shareWithList li {
padding-top: 5px;
padding-bottom: 5px;
font-weight: bold;
white-space: normal;
display: flex;
align-items: center;
}
#shareWithList .username {
padding-right: 8px;
padding-left: 8px;
white-space: nowrap;
text-overflow: ellipsis;
display: inline-block;
overflow: hidden;
vertical-align: middle;
}
.shareWithList .icon-delete {
display: inline-block;
background-size: 16px 16px;
width: 16px;
height: 16px;
padding: 0;
margin: 0;
border: none;
width: 100%;
border-bottom: 1px solid #333333;
-webkit-border-radius: 0;
margin-top: -4px;
line-height: 100%;
margin-bottom: -4px;
margin-top: 5px;
}
button {
border: 0;
background-color: transparent;
.shareOption {
margin-top: 4px;
}
button:hover {
border: 0;
background-color: transparent;
}
/* board detail */
#board-detail-labels {
padding: 10px;
}
@@ -719,75 +767,33 @@ button:hover {
margin-right: 10px;
}
.ui-select-container.dropdown {
background: #ffffff;
border-radius: 0px;
box-shadow: none;
display: block;
margin-right: 0;
position: static;
width: 100%;
z-index: auto;
padding: 3px;
.ui-select-offscreen {
display: none;
}
.ui-select-match-close {
float: right;
left: -20px;
margin-top: 3px;
z-index: 100;
position: relative;
display: inline-block !important;
margin-right: 7px;
}
.ui-select-match-item {
padding: 2px;
float: left;
padding: 0;
float: left !important;
display: block;
margin-right: -17px !important;
}
.ui-select-match-item .select-label {
padding: 4px;
color: #fff;
padding-right: 23px;
padding: 6px 23px 6px 6px;
margin-right: -23px !important;
}
.ui-select-container {
background-color: #fafafa !important;
border: 1px solid #fafafa;
}
.ui-select-container.open {
border: 1px solid #aaaaaa;
}
.ui-select-container input.ui-select-search {
padding: 0px !important;
margin: 2px !important;
background-color: transparent;
border: none;
}
.ui-select-bootstrap .ui-select-choices-row > a {
padding: 3px !important;
}
.ui-select-choices-row-inner {
margin-bottom: 2px;
width: 100%;
padding: 0;
}
.ui-select-choices-row-inner span {
padding: 3px;
padding-left: 10px;
padding-right: 10px;
width: 100%;
}
/* ui-select disabled */
.ui-select-container[disabled] {
.select2-container-multi .select2-choices .select2-search-choice {
padding: 3px 0 !important;
border: 0 !important;
overflow: hidden;
}
@@ -799,9 +805,17 @@ button:hover {
}
.ui-select-container[disabled] .ui-select-match-item {
margin-right: 0px !important;
margin-right: 0 !important;
}
.select2-search input {
width:100% !important;
}
/**
* Mobile optimizations
*/
@media (max-width: 480px) {
/* hide board actions on mobile */
#board-actions {
@@ -815,17 +829,22 @@ button:hover {
}
}
/**
* Markdown rendering
*/
#markdown {
width:100% !important;
width: 100% !important;
}
#markdown p {
margin-bottom: 15px;
}
#markdown * {
white-space: normal;
word-wrap:break-word;
word-wrap: break-word; /* All browsers since IE 5.5+ */
overflow-wrap: break-word; /* Renamed property in CSS3 draft spec */
word-wrap: break-word;
overflow-wrap: break-word;
}
#markdown a {
@@ -873,46 +892,43 @@ button:hover {
padding: 3px;
}
.shareWithList .username {
min-width: 100px;
}
.shareWithList .icon {
display: inline-block;
background-size: 16px 16px;
width: 16px;
height: 16px;
}
.shareWithList .fa {
font-size: 12pt;
width: 16px;
text-align: center;
}
.shareOption {
margin-top: 4px;
}
.app-deck .icon {
display: inline-block;
}
/**
* Custom icons
*/
.icon-group {
background-image: url('../../../settings/img/users.svg');
}
.icon-add-white {
background-image: url('../img/add-white.svg');
}
.icon-archive {
background-image: url('../img/archive.svg');
}
.icon-archive-white {
background-image: url('../img/archive-white.svg');
}
.icon-details {
background-image: url('../img/details.svg');
}
.icon-details-white {
background-image: url('../img/details-white.svg');
}
.icon-description-marker {
position: absolute;
top: 2px;
right: 2px;
}
/**
* Hotfix for https://github.com/angular-ui/ui-select/issues/1652
*/
.ui-select-dropdown.select2-drop-active {
opacity: 1 !important;
}

79
issue_template.md Normal file
View File

@@ -0,0 +1,79 @@
### Steps to reproduce
1.
2.
3.
### Expected behaviour
Tell us what should happen
### Actual behaviour
Tell us what happens instead
### Server configuration
<!--
You can use the Issue Template application to prefill most of the required information: https://apps.nextcloud.com/apps/issuetemplate
-->
**Operating system**:
**Web server:**
**Database:**
**PHP version:**
**Nextcloud version:** (see Nextcloud admin page)
**Where did you install Nextcloud from:**
**Signing status:**
```
Login as admin user into your Nextcloud and access
http://example.com/index.php/settings/integrity/failed
paste the results here.
```
**List of activated apps:**
```
If you have access to your command line run e.g.:
sudo -u www-data php occ app:list
from within your Nextcloud installation folder
```
**Nextcloud configuration:**
```
If you have access to your command line run e.g.:
sudo -u www-data php occ config:list system
from within your Nextcloud installation folder
or
Insert your config.php content here
Make sure to remove all sensitive content such as passwords. (e.g. database password, passwordsalt, secret, smtp password, …)
```
**Are you using an external user-backend, if yes which one:** LDAP/ActiveDirectory/Webdav/...
### Client configuration
**Browser:**
**Operating system:**
### Logs
#### Nextcloud log (data/nextcloud.log)
```
Insert your Nextcloud log here
```
#### Browser log
```
Insert your browser log here, this could for example include:
a) The javascript console log
b) The network log
c) ...
```

View File

@@ -1,10 +1,10 @@
build:
grunt build
./node_modules/.bin/grunt build
watch:
grunt watch
./node_modules/.bin/grunt watch
install:
npm install
bower install
./node_modules/.bin/bower install

View File

@@ -7,8 +7,8 @@
"angular-mocks": "~1.6.1",
"angular-sanitize": "~1.6.1",
"angular-animate": "~1.6.1",
"ng-sortable": "1.3.6",
"jquery": "3.1.x",
"ng-sortable": "1.3.8",
"jquery": "3.2.x",
"es6-shim": "~0.*",
"js-url": "~2.*",
"angular-ui-select": "~0.19.6",

View File

@@ -119,12 +119,7 @@ app.controller('BoardController', function ($rootScope, $scope, $stateParams, St
$scope.statusservice.setError('Error occured', error);
});
BoardService.searchUsers('%25');
$scope.searchForUser = function (search) {
if (search == "") {
search = "%25";
}
BoardService.searchUsers(search);
};

View File

@@ -21,58 +21,78 @@
*
*/
app.controller('ListController', function ($scope, $location, $filter, BoardService, $element) {
$scope.boards = [];
$scope.newBoard = {};
$scope.status = {};
$scope.colors = ['0082c9', '00c9c6','00c906', 'c92b00', 'F1DB50', '7C31CC', '3A3B3D', 'CACBCD'];
$scope.boardservice = BoardService;
app.controller('ListController', function ($scope, $location, $filter, BoardService, $element, $timeout) {
$scope.boards = [];
$scope.newBoard = {};
$scope.status = {
deleteUndo: []
};
$scope.colors = ['0082c9', '00c9c6','00c906', 'c92b00', 'F1DB50', '7C31CC', '3A3B3D', 'CACBCD'];
$scope.boardservice = BoardService;
$scope.newBoard.color = $scope.colors[0];
// FIXME: not nice, but we want to load this only once
if($element.attr('id') === 'app-navigation') {
BoardService.fetchAll().then(function(data) {
$scope.filterData();
}, function (error) {
// TODO: show error when loading fails
});
}
// FIXME: not nice, but we want to load this only once
if($element.attr('id') === 'app-navigation') {
BoardService.fetchAll().then(function(data) {
$scope.filterData();
}, function (error) {
// TODO: show error when loading fails
});
}
$scope.filterData = function () {
angular.copy($scope.boardservice.getData(), $scope.boardservice.sorted);
$scope.boardservice.sorted = $filter('orderBy')($scope.boardservice.sorted, 'title');
};
$scope.filterData = function () {
angular.copy($scope.boardservice.getData(), $scope.boardservice.sorted);
$scope.boardservice.sorted = $filter('orderBy')($scope.boardservice.sorted, 'title');
};
$scope.selectColor = function(color) {
$scope.newBoard.color = color;
};
$scope.selectColor = function(color) {
$scope.newBoard.color = color;
};
$scope.boardCreate = function() {
if(!$scope.newBoard.title || !$scope.newBoard.color) {
$scope.status.addBoard=false;
return;
}
BoardService.create($scope.newBoard)
.then(function (response) {
$scope.newBoard = {};
$scope.status.addBoard=false;
$scope.filterData();
}, function(error) {
$scope.status.createBoard = 'Unable to insert board: ' + error.message;
});
};
$scope.boardCreate = function() {
if(!$scope.newBoard.title || !$scope.newBoard.color) {
$scope.status.addBoard=false;
return;
}
BoardService.create($scope.newBoard)
.then(function (response) {
$scope.newBoard = {};
$scope.newBoard.color = $scope.colors[0];
$scope.status.addBoard=false;
$scope.filterData();
}, function(error) {
$scope.status.createBoard = 'Unable to insert board: ' + error.message;
});
};
$scope.boardUpdate = function(board) {
BoardService.update(board).then(function(data) {
$scope.filterData();
});
board.status.edit = false;
};
$scope.boardUpdate = function(board) {
BoardService.update(board).then(function(data) {
$scope.filterData();
});
board.status.edit = false;
};
$scope.boardDelete = function(board) {
BoardService.delete(board.id).then(function (data) {
$scope.filterData();
});
};
$scope.boardDelete = function(board) {
var boardId = board.id;
$scope.status.deleteUndo[boardId] = 10;
$scope.boardDeleteCountdown = function () {
console.log($scope.status);
if($scope.status.deleteUndo[boardId] > 0) {
$scope.status.deleteUndo[boardId]--;
$timeout($scope.boardDeleteCountdown, 1000);
}
if($scope.status.deleteUndo[boardId] === 0) {
BoardService.delete(board.id).then(function (data) {
$scope.filterData();
});
}
};
$timeout($scope.boardDeleteCountdown, 1000);
};
$scope.boardDeleteUndo = function (board) {
delete $scope.status.deleteUndo[board.id];
};
});

View File

@@ -26,50 +26,101 @@ app.factory('BoardService', function(ApiService, $http, $q){
};
BoardService.prototype = angular.copy(ApiService.prototype);
BoardService.prototype.searchUsers = function(search) {
var url = OC.generateUrl('/apps/deck/share/search/'+search);
var deferred = $q.defer();
var self = this;
$http.get(url).then(function (response) {
BoardService.prototype.searchUsers = function (search) {
var deferred = $q.defer();
var self = this;
var searchData = {
format: 'json',
perPage: 4,
itemType: [0, 1]
};
if (search !== "") {
searchData.search = search;
}
$http({
method: 'GET',
url: OC.linkToOCS('apps/files_sharing/api/v1') + 'sharees',
params: searchData
})
.then(function (result) {
var response = result.data;
if (response.ocs.meta.statuscode !== 100) {
deferred.reject('Error while searching for sharees');
return;
}
self.sharees = [];
self.sharees = [];
// filter out everyone who is already in the share list
angular.forEach(response.data, function(item) {
var exists = false;
angular.forEach(self.getCurrent().acl, function(acl) {
if (acl.participant === item.participant) {
exists = true;
}
});
if(!exists) {
self.sharees.push(item);
}
});
var users = response.ocs.data.exact.users.concat(response.ocs.data.users);
var groups = response.ocs.data.exact.groups.concat(response.ocs.data.groups);
deferred.resolve(response.data);
}, function (error) {
deferred.reject('Error while update ' + self.endpoint);
});
return deferred.promise;
};
// filter out everyone who is already in the share list
angular.forEach(users, function (item) {
var acl = self.generateAcl('user', item);
var exists = false;
angular.forEach(self.getCurrent().acl, function (acl) {
if (acl.participant.primaryKey === item.value.shareWith) {
exists = true;
}
});
if (!exists && OC.getCurrentUser().uid !== item.value.shareWith) {
self.sharees.push(acl);
}
});
angular.forEach(groups, function (item) {
var acl = self.generateAcl('group', item);
var exists = false;
angular.forEach(self.getCurrent().acl, function (acl) {
if (acl.participant.primaryKey === item.value.shareWith) {
exists = true;
}
});
if (!exists) {
self.sharees.push(acl);
}
});
BoardService.prototype.addAcl = function(acl) {
var board = this.getCurrent();
var deferred = $q.defer();
var self = this;
var _acl = acl;
$http.post(this.baseUrl + '/' + acl.boardId + '/acl', _acl).then(function (response) {
if(!board.acl) {
board.acl = {};
}
board.acl[response.data.id] = response.data;
deferred.resolve(response.data);
}, function (error) {
deferred.reject('Error creating ACL ' + _acl);
});
acl = null;
return deferred.promise;
};
deferred.resolve(self.sharees);
}, function () {
deferred.reject('Error while searching for sharees');
});
return deferred.promise;
};
BoardService.prototype.generateAcl = function(type, ocsItem) {
return {
boardId: null,
id: null,
owner: false,
participant: {
primaryKey: ocsItem.value.shareWith,
uid: ocsItem.value.shareWith,
displayname: ocsItem.label
},
permissionEdit: true,
permissionManage: true,
permissionShare: true,
type: type
}
};
BoardService.prototype.addAcl = function (acl) {
var board = this.getCurrent();
var deferred = $q.defer();
var self = this;
var _acl = acl;
$http.post(this.baseUrl + '/' + acl.boardId + '/acl', _acl).then(function (response) {
if (!board.acl || board.acl.length === 0) {
board.acl = {};
}
board.acl[response.data.id] = response.data;
deferred.resolve(response.data);
}, function (error) {
deferred.reject('Error creating ACL ' + _acl);
});
acl = null;
return deferred.promise;
};
BoardService.prototype.deleteAcl = function(acl) {
var board = this.getCurrent();
@@ -105,7 +156,6 @@ app.factory('BoardService', function(ApiService, $http, $q){
var deferred = $q.defer();
$http.get(this.baseUrl + '/' + board.id + '/permissions').then(function (response) {
board.permissions = response.data;
console.log(board.permissions);
deferred.resolve(response.data);
}, function (error) {
deferred.reject('Error fetching board permissions ' + board);

9
l10n/.tx/config Normal file
View File

@@ -0,0 +1,9 @@
[main]
host = https://www.transifex.com
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
[nextcloud.deck]
file_filter = <lang>/deck.po
source_file = templates/deck.pot
source_lang = en
type = PO

33
l10n/bg.js Normal file
View File

@@ -0,0 +1,33 @@
OC.L10N.register(
"deck",
{
"Finished" : "Завършен",
"To review" : "За преглед",
"Action needed" : "Необходимо е действие",
"Later" : "По-късно",
"Archive" : "Архивиране",
"Unarchive" : "Разархивиране",
"Delete" : "Изтриване",
"Sharing" : "Споделяне",
"Labels" : "Етикети",
"Select users or groups to share with" : "Избор на потребители и групи за споделяне",
"No matching user or group found." : "Не са намерени съвпадащи потребители или групи",
"Share" : "Сподели",
"Edit" : "Редакция",
"Manage" : "Управление",
"Discard share" : "Отхвърляне на споделяне",
"Create a new label" : "Създаване на нов етикет",
"Members" : "Членове",
"Modified:" : "Променен на:",
"Created:" : "Създаден на:",
"by" : "от",
"Saved" : "Запазено",
"Attachments" : "Прикачени файлове",
"Comments" : "Коментари",
"History" : "История",
"Shared with you" : "Споделено с Вас",
"edit" : "редакция",
"delete" : "изтриване",
"remove share" : "премахване на споделяне"
},
"nplurals=2; plural=(n != 1);");

31
l10n/bg.json Normal file
View File

@@ -0,0 +1,31 @@
{ "translations": {
"Finished" : "Завършен",
"To review" : "За преглед",
"Action needed" : "Необходимо е действие",
"Later" : "По-късно",
"Archive" : "Архивиране",
"Unarchive" : "Разархивиране",
"Delete" : "Изтриване",
"Sharing" : "Споделяне",
"Labels" : "Етикети",
"Select users or groups to share with" : "Избор на потребители и групи за споделяне",
"No matching user or group found." : "Не са намерени съвпадащи потребители или групи",
"Share" : "Сподели",
"Edit" : "Редакция",
"Manage" : "Управление",
"Discard share" : "Отхвърляне на споделяне",
"Create a new label" : "Създаване на нов етикет",
"Members" : "Членове",
"Modified:" : "Променен на:",
"Created:" : "Създаден на:",
"by" : "от",
"Saved" : "Запазено",
"Attachments" : "Прикачени файлове",
"Comments" : "Коментари",
"History" : "История",
"Shared with you" : "Споделено с Вас",
"edit" : "редакция",
"delete" : "изтриване",
"remove share" : "премахване на споделяне"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}

26
l10n/ca.js Normal file
View File

@@ -0,0 +1,26 @@
OC.L10N.register(
"deck",
{
"Finished" : "Acabat",
"To review" : "Per revisar",
"Action needed" : "Acció necessaria",
"Later" : "Més tard",
"Archive" : "Arxiu",
"Delete" : "Esborra",
"Sharing" : "Compartir",
"Labels" : "Etiqueta",
"Share" : "Comparteix",
"Edit" : "Edita",
"Create a new label" : "Crea una nova etiqueta",
"Members" : "Membres",
"Modified:" : "Modificat:",
"Created:" : "Creat:",
"by" : "per",
"Saved" : "Desat",
"Comments" : "Comentaris",
"History" : "Història",
"Shared with you" : "Us han compartit",
"edit" : "edita",
"delete" : "esborra"
},
"nplurals=2; plural=(n != 1);");

24
l10n/ca.json Normal file
View File

@@ -0,0 +1,24 @@
{ "translations": {
"Finished" : "Acabat",
"To review" : "Per revisar",
"Action needed" : "Acció necessaria",
"Later" : "Més tard",
"Archive" : "Arxiu",
"Delete" : "Esborra",
"Sharing" : "Compartir",
"Labels" : "Etiqueta",
"Share" : "Comparteix",
"Edit" : "Edita",
"Create a new label" : "Crea una nova etiqueta",
"Members" : "Membres",
"Modified:" : "Modificat:",
"Created:" : "Creat:",
"by" : "per",
"Saved" : "Desat",
"Comments" : "Comentaris",
"History" : "Història",
"Shared with you" : "Us han compartit",
"edit" : "edita",
"delete" : "esborra"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}

44
l10n/cs.js Normal file
View File

@@ -0,0 +1,44 @@
OC.L10N.register(
"deck",
{
"Deck" : "Balík",
"Finished" : "Dokončeno",
"To review" : "K revizi",
"Action needed" : "Nutná akce",
"Later" : "Později",
"Show archived cards" : "Zobrazit archivované karty",
"Hide archived cards" : "Skrýt archivované karty",
"Board details" : "Detaily desky",
"Archive" : "Archiv",
"Unarchive" : "Zrušit archivování",
"Delete" : "Smazat",
"Enter a card title" : "Zadejte nadpis karty",
"Sharing" : "Sdílení",
"Labels" : "Štítky",
"Select users or groups to share with" : "Vyberte uživatele nebo skupiny pro sdílení",
"No matching user or group found." : "Nevyhovuje žádný uživatel ani skupina",
"Share" : "Sdílet",
"Edit" : "Upravit",
"Manage" : "Spravovat",
"Discard share" : "Zrušit sdílení",
"Create a new label" : "Vytvořit nový štítek",
"Board title" : "Nadpis desky",
"Members" : "Členové",
"Create new board" : "VYtvořit ovou desku",
"New board title" : "Nadpis nové desky",
"Modified:" : "Upraveno:",
"Created:" : "Vytvořeno:",
"by" : "od",
"Saved" : "Uloženo",
"Add a card description ..." : "Přidat popis karty...",
"Attachments" : "Přílohy",
"Comments" : "Komentáře",
"History" : "Historie",
"All Boards" : "Všechny desky",
"Shared with you" : "Sdíleno s vámi",
"edit" : "upravit",
"delete" : "smazat",
"remove share" : "odebrat sdílení",
"Create a new board" : "Vytvořit novou desku"
},
"nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;");

42
l10n/cs.json Normal file
View File

@@ -0,0 +1,42 @@
{ "translations": {
"Deck" : "Balík",
"Finished" : "Dokončeno",
"To review" : "K revizi",
"Action needed" : "Nutná akce",
"Later" : "Později",
"Show archived cards" : "Zobrazit archivované karty",
"Hide archived cards" : "Skrýt archivované karty",
"Board details" : "Detaily desky",
"Archive" : "Archiv",
"Unarchive" : "Zrušit archivování",
"Delete" : "Smazat",
"Enter a card title" : "Zadejte nadpis karty",
"Sharing" : "Sdílení",
"Labels" : "Štítky",
"Select users or groups to share with" : "Vyberte uživatele nebo skupiny pro sdílení",
"No matching user or group found." : "Nevyhovuje žádný uživatel ani skupina",
"Share" : "Sdílet",
"Edit" : "Upravit",
"Manage" : "Spravovat",
"Discard share" : "Zrušit sdílení",
"Create a new label" : "Vytvořit nový štítek",
"Board title" : "Nadpis desky",
"Members" : "Členové",
"Create new board" : "VYtvořit ovou desku",
"New board title" : "Nadpis nové desky",
"Modified:" : "Upraveno:",
"Created:" : "Vytvořeno:",
"by" : "od",
"Saved" : "Uloženo",
"Add a card description ..." : "Přidat popis karty...",
"Attachments" : "Přílohy",
"Comments" : "Komentáře",
"History" : "Historie",
"All Boards" : "Všechny desky",
"Shared with you" : "Sdíleno s vámi",
"edit" : "upravit",
"delete" : "smazat",
"remove share" : "odebrat sdílení",
"Create a new board" : "Vytvořit novou desku"
},"pluralForm" :"nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"
}

44
l10n/da.js Normal file
View File

@@ -0,0 +1,44 @@
OC.L10N.register(
"deck",
{
"Deck" : "Tavle",
"Finished" : "Færdiggjort",
"To review" : "Efterse",
"Action needed" : "Handling påkrævet",
"Later" : "Senere",
"Show archived cards" : "Vis arkiverede kort",
"Hide archived cards" : "Skjul arkiverede kort",
"Board details" : "Liste detaljer",
"Archive" : "Arkivér",
"Unarchive" : "Annuller arkivering",
"Delete" : "Slet",
"Enter a card title" : "Angiv titel på kort",
"Sharing" : "Deling",
"Labels" : "Labels",
"Select users or groups to share with" : "Vælg brugere eller grupper og dele med",
"No matching user or group found." : "Ingen bruger eller gruppe fundet",
"Share" : "Del",
"Edit" : "Redigér",
"Manage" : "Administrer ",
"Discard share" : "Kasser deling",
"Create a new label" : "Opret en ny etikette ",
"Board title" : "Titel på liste",
"Members" : "Medlemmer",
"Create new board" : "Opret ny liste",
"New board title" : "Ny titel på liste",
"Modified:" : "Ændret:",
"Created:" : "Oprettet:",
"by" : "af",
"Saved" : "Gemt",
"Add a card description ..." : "Tilføj en kort beskrivelse",
"Attachments" : "Vedhæftede filer",
"Comments" : "Kommentarer",
"History" : "Hostorik",
"All Boards" : "Alle lister",
"Shared with you" : "Delt med dig",
"edit" : "redigér",
"delete" : "slet",
"remove share" : "Fjern deling",
"Create a new board" : "Opret ny liste"
},
"nplurals=2; plural=(n != 1);");

42
l10n/da.json Normal file
View File

@@ -0,0 +1,42 @@
{ "translations": {
"Deck" : "Tavle",
"Finished" : "Færdiggjort",
"To review" : "Efterse",
"Action needed" : "Handling påkrævet",
"Later" : "Senere",
"Show archived cards" : "Vis arkiverede kort",
"Hide archived cards" : "Skjul arkiverede kort",
"Board details" : "Liste detaljer",
"Archive" : "Arkivér",
"Unarchive" : "Annuller arkivering",
"Delete" : "Slet",
"Enter a card title" : "Angiv titel på kort",
"Sharing" : "Deling",
"Labels" : "Labels",
"Select users or groups to share with" : "Vælg brugere eller grupper og dele med",
"No matching user or group found." : "Ingen bruger eller gruppe fundet",
"Share" : "Del",
"Edit" : "Redigér",
"Manage" : "Administrer ",
"Discard share" : "Kasser deling",
"Create a new label" : "Opret en ny etikette ",
"Board title" : "Titel på liste",
"Members" : "Medlemmer",
"Create new board" : "Opret ny liste",
"New board title" : "Ny titel på liste",
"Modified:" : "Ændret:",
"Created:" : "Oprettet:",
"by" : "af",
"Saved" : "Gemt",
"Add a card description ..." : "Tilføj en kort beskrivelse",
"Attachments" : "Vedhæftede filer",
"Comments" : "Kommentarer",
"History" : "Hostorik",
"All Boards" : "Alle lister",
"Shared with you" : "Delt med dig",
"edit" : "redigér",
"delete" : "slet",
"remove share" : "Fjern deling",
"Create a new board" : "Opret ny liste"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}

44
l10n/de.js Normal file
View File

@@ -0,0 +1,44 @@
OC.L10N.register(
"deck",
{
"Deck" : "Deck",
"Finished" : "Abgeschlossen",
"To review" : "Zu bewerten",
"Action needed" : "Aktion erforderlich",
"Later" : "Später",
"Show archived cards" : "Archivierte Karten anzeigen",
"Hide archived cards" : "Archivierte Karten ausblenden",
"Board details" : "Board-Details",
"Archive" : "Archivieren",
"Unarchive" : "Dearchivieren",
"Delete" : "Löschen",
"Enter a card title" : "Kartentitel eingeben",
"Sharing" : "Teilen",
"Labels" : "Beschriftungen",
"Select users or groups to share with" : "Benutzern oder Gruppen auswählen, mit denen es geteilt werden soll",
"No matching user or group found." : "Keine passenden Benutzer oder Gruppen gefunden.",
"Share" : "Share",
"Edit" : "Bearbeiten",
"Manage" : "Verwalten",
"Discard share" : "Teilen aufheben",
"Create a new label" : "Neue Beschriftung erstellen",
"Board title" : "Board-Titel",
"Members" : "Mitglieder",
"Create new board" : "Neues Board erstellen",
"New board title" : "Neuer Board-Titel",
"Modified:" : "Geändert:",
"Created:" : "Erstellt:",
"by" : "von",
"Saved" : "Gespeichert",
"Add a card description ..." : "Eine Beschreibung der Karte hinzufügen…",
"Attachments" : "Anhänge",
"Comments" : "Kommentare",
"History" : "Verlauf",
"All Boards" : "Alle Boards",
"Shared with you" : "Mit Dir geteilt",
"edit" : "Bearbeiten",
"delete" : "Löschen",
"remove share" : "Freigabe löschen",
"Create a new board" : "Neues Board erstellen"
},
"nplurals=2; plural=(n != 1);");

42
l10n/de.json Normal file
View File

@@ -0,0 +1,42 @@
{ "translations": {
"Deck" : "Deck",
"Finished" : "Abgeschlossen",
"To review" : "Zu bewerten",
"Action needed" : "Aktion erforderlich",
"Later" : "Später",
"Show archived cards" : "Archivierte Karten anzeigen",
"Hide archived cards" : "Archivierte Karten ausblenden",
"Board details" : "Board-Details",
"Archive" : "Archivieren",
"Unarchive" : "Dearchivieren",
"Delete" : "Löschen",
"Enter a card title" : "Kartentitel eingeben",
"Sharing" : "Teilen",
"Labels" : "Beschriftungen",
"Select users or groups to share with" : "Benutzern oder Gruppen auswählen, mit denen es geteilt werden soll",
"No matching user or group found." : "Keine passenden Benutzer oder Gruppen gefunden.",
"Share" : "Share",
"Edit" : "Bearbeiten",
"Manage" : "Verwalten",
"Discard share" : "Teilen aufheben",
"Create a new label" : "Neue Beschriftung erstellen",
"Board title" : "Board-Titel",
"Members" : "Mitglieder",
"Create new board" : "Neues Board erstellen",
"New board title" : "Neuer Board-Titel",
"Modified:" : "Geändert:",
"Created:" : "Erstellt:",
"by" : "von",
"Saved" : "Gespeichert",
"Add a card description ..." : "Eine Beschreibung der Karte hinzufügen…",
"Attachments" : "Anhänge",
"Comments" : "Kommentare",
"History" : "Verlauf",
"All Boards" : "Alle Boards",
"Shared with you" : "Mit Dir geteilt",
"edit" : "Bearbeiten",
"delete" : "Löschen",
"remove share" : "Freigabe löschen",
"Create a new board" : "Neues Board erstellen"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}

44
l10n/de_DE.js Normal file
View File

@@ -0,0 +1,44 @@
OC.L10N.register(
"deck",
{
"Deck" : "Deck",
"Finished" : "Abgeschlossen",
"To review" : "Zu bewerten",
"Action needed" : "Aktion erforderlich",
"Later" : "Später",
"Show archived cards" : "Archivierte Karten anzeigen",
"Hide archived cards" : "Archivierte Karten ausblenden",
"Board details" : "Board-Details",
"Archive" : "Archivieren",
"Unarchive" : "Dearchivieren",
"Delete" : "Löschen",
"Enter a card title" : "Kartentitel eingeben",
"Sharing" : "Teilen",
"Labels" : "Beschriftungen",
"Select users or groups to share with" : "Benutzern oder Gruppen auswählen, mit denen es geteilt werden soll",
"No matching user or group found." : "Keine passenden Benutzer oder Gruppen gefunden.",
"Share" : "Teilen",
"Edit" : "Bearbeiten",
"Manage" : "Verwalten",
"Discard share" : "Teilen aufheben",
"Create a new label" : "Neue Beschriftung erstellen",
"Board title" : "Board-Titel",
"Members" : "Mitglieder",
"Create new board" : "Neues Board erstellen",
"New board title" : "Neuer Board-Titel",
"Modified:" : "Geändert:",
"Created:" : "Erstellt:",
"by" : "von",
"Saved" : "Gespeichert",
"Add a card description ..." : "Der Karte eine Beschreibung hinzufügen…",
"Attachments" : "Anhänge",
"Comments" : "Kommentare",
"History" : "Verlauf",
"All Boards" : "Alle Boards",
"Shared with you" : "Mit Ihnen geteilt",
"edit" : "Bearbeiten",
"delete" : "Löschen",
"remove share" : "Freigabe löschen",
"Create a new board" : "Neues Board erstellen"
},
"nplurals=2; plural=(n != 1);");

42
l10n/de_DE.json Normal file
View File

@@ -0,0 +1,42 @@
{ "translations": {
"Deck" : "Deck",
"Finished" : "Abgeschlossen",
"To review" : "Zu bewerten",
"Action needed" : "Aktion erforderlich",
"Later" : "Später",
"Show archived cards" : "Archivierte Karten anzeigen",
"Hide archived cards" : "Archivierte Karten ausblenden",
"Board details" : "Board-Details",
"Archive" : "Archivieren",
"Unarchive" : "Dearchivieren",
"Delete" : "Löschen",
"Enter a card title" : "Kartentitel eingeben",
"Sharing" : "Teilen",
"Labels" : "Beschriftungen",
"Select users or groups to share with" : "Benutzern oder Gruppen auswählen, mit denen es geteilt werden soll",
"No matching user or group found." : "Keine passenden Benutzer oder Gruppen gefunden.",
"Share" : "Teilen",
"Edit" : "Bearbeiten",
"Manage" : "Verwalten",
"Discard share" : "Teilen aufheben",
"Create a new label" : "Neue Beschriftung erstellen",
"Board title" : "Board-Titel",
"Members" : "Mitglieder",
"Create new board" : "Neues Board erstellen",
"New board title" : "Neuer Board-Titel",
"Modified:" : "Geändert:",
"Created:" : "Erstellt:",
"by" : "von",
"Saved" : "Gespeichert",
"Add a card description ..." : "Der Karte eine Beschreibung hinzufügen…",
"Attachments" : "Anhänge",
"Comments" : "Kommentare",
"History" : "Verlauf",
"All Boards" : "Alle Boards",
"Shared with you" : "Mit Ihnen geteilt",
"edit" : "Bearbeiten",
"delete" : "Löschen",
"remove share" : "Freigabe löschen",
"Create a new board" : "Neues Board erstellen"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}

30
l10n/el.js Normal file
View File

@@ -0,0 +1,30 @@
OC.L10N.register(
"deck",
{
"Finished" : "Ολοκληρώθηκε",
"To review" : "Προς επισκόπηση",
"Action needed" : "Απαιτείται ενέργεια",
"Later" : "Αργότερα",
"Show archived cards" : "Εμφάνιση καρτελών που αρχειοθετήθηκαν",
"Hide archived cards" : "Απόκρυψη καρτελών που αρχειοθετήθηκαν",
"Archive" : "Αρχειοθέτηση",
"Unarchive" : "Αναίρεση αρχειοθέτησης",
"Delete" : "Διαγραφή",
"Labels" : "Ετικέτες",
"Share" : "Διαμοιρασμός",
"Edit" : "Επεξεργασία",
"Manage" : "Διαχείριση",
"Create a new label" : "Δημιουργία νέας ετικέτας",
"Members" : "Μέλη",
"Modified:" : "Τροποποιήθηκε:",
"Created:" : "Δημιουργήθηκε:",
"by" : "από",
"Saved" : "Αποθηκεύτηκε",
"Add a card description ..." : "Προσθήκη περιγραφής καρτέλας ...",
"Attachments" : "Συνημμένα",
"Comments" : "Σχόλια",
"History" : "Ιστορικό",
"edit" : "επεξεργασία",
"delete" : "διαγραφή"
},
"nplurals=2; plural=(n != 1);");

28
l10n/el.json Normal file
View File

@@ -0,0 +1,28 @@
{ "translations": {
"Finished" : "Ολοκληρώθηκε",
"To review" : "Προς επισκόπηση",
"Action needed" : "Απαιτείται ενέργεια",
"Later" : "Αργότερα",
"Show archived cards" : "Εμφάνιση καρτελών που αρχειοθετήθηκαν",
"Hide archived cards" : "Απόκρυψη καρτελών που αρχειοθετήθηκαν",
"Archive" : "Αρχειοθέτηση",
"Unarchive" : "Αναίρεση αρχειοθέτησης",
"Delete" : "Διαγραφή",
"Labels" : "Ετικέτες",
"Share" : "Διαμοιρασμός",
"Edit" : "Επεξεργασία",
"Manage" : "Διαχείριση",
"Create a new label" : "Δημιουργία νέας ετικέτας",
"Members" : "Μέλη",
"Modified:" : "Τροποποιήθηκε:",
"Created:" : "Δημιουργήθηκε:",
"by" : "από",
"Saved" : "Αποθηκεύτηκε",
"Add a card description ..." : "Προσθήκη περιγραφής καρτέλας ...",
"Attachments" : "Συνημμένα",
"Comments" : "Σχόλια",
"History" : "Ιστορικό",
"edit" : "επεξεργασία",
"delete" : "διαγραφή"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}

44
l10n/es.js Normal file
View File

@@ -0,0 +1,44 @@
OC.L10N.register(
"deck",
{
"Deck" : "Deck",
"Finished" : "Finalizado",
"To review" : "Para revisar",
"Action needed" : "Se necesita una acción",
"Later" : "Después",
"Show archived cards" : "Mostrar tarjetas archivadas",
"Hide archived cards" : "Ocultar tarjetas archivadas",
"Board details" : "Detalles del tablero",
"Archive" : "Archivar",
"Unarchive" : "Desarchivar",
"Delete" : "Eliminar",
"Enter a card title" : "Introducir un título de tarjeta",
"Sharing" : "Compartir",
"Labels" : "Etiquetas",
"Select users or groups to share with" : "Seleccionar usuarios o grupos con los que compartir",
"No matching user or group found." : "No se encontraron usuarios o grupos coincidentes.",
"Share" : "Compartir",
"Edit" : "Editar",
"Manage" : "Organizar",
"Discard share" : "Descartar compartición",
"Create a new label" : "Crear una nueva etiqueta",
"Board title" : "Título del tablero",
"Members" : "Miembros",
"Create new board" : "Crear nuevo tablero",
"New board title" : "Nuevo título de tablero",
"Modified:" : "Modificado: ",
"Created:" : "Creado: ",
"by" : "por",
"Saved" : "Guardado",
"Add a card description ..." : "Añadir una descripción de la tarjeta...",
"Attachments" : "Adjuntos",
"Comments" : "Comentario",
"History" : "Historia",
"All Boards" : "Todos los tableros",
"Shared with you" : "Compartido contigo",
"edit" : "editar",
"delete" : "eliminar",
"remove share" : "eliminar compartición",
"Create a new board" : "Crear un tablero nuevo"
},
"nplurals=2; plural=(n != 1);");

42
l10n/es.json Normal file
View File

@@ -0,0 +1,42 @@
{ "translations": {
"Deck" : "Deck",
"Finished" : "Finalizado",
"To review" : "Para revisar",
"Action needed" : "Se necesita una acción",
"Later" : "Después",
"Show archived cards" : "Mostrar tarjetas archivadas",
"Hide archived cards" : "Ocultar tarjetas archivadas",
"Board details" : "Detalles del tablero",
"Archive" : "Archivar",
"Unarchive" : "Desarchivar",
"Delete" : "Eliminar",
"Enter a card title" : "Introducir un título de tarjeta",
"Sharing" : "Compartir",
"Labels" : "Etiquetas",
"Select users or groups to share with" : "Seleccionar usuarios o grupos con los que compartir",
"No matching user or group found." : "No se encontraron usuarios o grupos coincidentes.",
"Share" : "Compartir",
"Edit" : "Editar",
"Manage" : "Organizar",
"Discard share" : "Descartar compartición",
"Create a new label" : "Crear una nueva etiqueta",
"Board title" : "Título del tablero",
"Members" : "Miembros",
"Create new board" : "Crear nuevo tablero",
"New board title" : "Nuevo título de tablero",
"Modified:" : "Modificado: ",
"Created:" : "Creado: ",
"by" : "por",
"Saved" : "Guardado",
"Add a card description ..." : "Añadir una descripción de la tarjeta...",
"Attachments" : "Adjuntos",
"Comments" : "Comentario",
"History" : "Historia",
"All Boards" : "Todos los tableros",
"Shared with you" : "Compartido contigo",
"edit" : "editar",
"delete" : "eliminar",
"remove share" : "eliminar compartición",
"Create a new board" : "Crear un tablero nuevo"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}

44
l10n/es_MX.js Normal file
View File

@@ -0,0 +1,44 @@
OC.L10N.register(
"deck",
{
"Deck" : "Deck",
"Finished" : "Terminado",
"To review" : "Para revisar",
"Action needed" : "Acción requerida",
"Later" : "Después",
"Show archived cards" : "Mostrar tarjetas archivadas",
"Hide archived cards" : "Ocultar tarjetas archivadas",
"Board details" : "Detalles del tablero",
"Archive" : "Archivar",
"Unarchive" : "Desarchivar",
"Delete" : "Borrar",
"Enter a card title" : "Ingrese el títilo de la tarjeta",
"Sharing" : "Compartiendo",
"Labels" : "Etiquetas",
"Select users or groups to share with" : "Seleccione los usuarios o grupos con los cuales compartir",
"No matching user or group found." : "No se encontraron coincidencias de usuarios o grupos.",
"Share" : "Compartir",
"Edit" : "Editar",
"Manage" : "Administrar",
"Discard share" : "Descartar elemento compartido",
"Create a new label" : "Crear nueva etiqueta",
"Board title" : "Título del tablero",
"Members" : "Miembros",
"Create new board" : "Crear un nuevo tablero",
"New board title" : "Nuevo título de tablero",
"Modified:" : "Modificado:",
"Created:" : "Creado:",
"by" : "por",
"Saved" : "Guardado",
"Add a card description ..." : "Agregar una descripción de la tarjeta ...",
"Attachments" : "Adjuntos",
"Comments" : "Comentarios",
"History" : "Histórico",
"All Boards" : "Todos los Tablero",
"Shared with you" : "Compartido con usted",
"edit" : "editar",
"delete" : "borrar",
"remove share" : "eliminar elemento compartido",
"Create a new board" : "Crear nuevo tablero"
},
"nplurals=2; plural=(n != 1);");

42
l10n/es_MX.json Normal file
View File

@@ -0,0 +1,42 @@
{ "translations": {
"Deck" : "Deck",
"Finished" : "Terminado",
"To review" : "Para revisar",
"Action needed" : "Acción requerida",
"Later" : "Después",
"Show archived cards" : "Mostrar tarjetas archivadas",
"Hide archived cards" : "Ocultar tarjetas archivadas",
"Board details" : "Detalles del tablero",
"Archive" : "Archivar",
"Unarchive" : "Desarchivar",
"Delete" : "Borrar",
"Enter a card title" : "Ingrese el títilo de la tarjeta",
"Sharing" : "Compartiendo",
"Labels" : "Etiquetas",
"Select users or groups to share with" : "Seleccione los usuarios o grupos con los cuales compartir",
"No matching user or group found." : "No se encontraron coincidencias de usuarios o grupos.",
"Share" : "Compartir",
"Edit" : "Editar",
"Manage" : "Administrar",
"Discard share" : "Descartar elemento compartido",
"Create a new label" : "Crear nueva etiqueta",
"Board title" : "Título del tablero",
"Members" : "Miembros",
"Create new board" : "Crear un nuevo tablero",
"New board title" : "Nuevo título de tablero",
"Modified:" : "Modificado:",
"Created:" : "Creado:",
"by" : "por",
"Saved" : "Guardado",
"Add a card description ..." : "Agregar una descripción de la tarjeta ...",
"Attachments" : "Adjuntos",
"Comments" : "Comentarios",
"History" : "Histórico",
"All Boards" : "Todos los Tablero",
"Shared with you" : "Compartido con usted",
"edit" : "editar",
"delete" : "borrar",
"remove share" : "eliminar elemento compartido",
"Create a new board" : "Crear nuevo tablero"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}

44
l10n/fi.js Normal file
View File

@@ -0,0 +1,44 @@
OC.L10N.register(
"deck",
{
"Deck" : "Kansi",
"Finished" : "Valmistunut",
"To review" : "Arvostella",
"Action needed" : "Toimia vaaditaan",
"Later" : "Myöhemmin",
"Show archived cards" : "Näytä arkistoidut kortit",
"Hide archived cards" : "Piilota arkistoidut kortit",
"Board details" : "Taulun tiedot",
"Archive" : "Arkisto",
"Unarchive" : "Pois arkistosta",
"Delete" : "Poista",
"Enter a card title" : "Anna otsikko",
"Sharing" : "Jakaminen",
"Labels" : "Etiketit",
"Select users or groups to share with" : "Valitse käyttäjiä tai ryhmiä joille haluat jakaa",
"No matching user or group found." : "Käyttäjää tai ryhmää ei löytynyt.",
"Share" : "Jaa",
"Edit" : "Muokkaa",
"Manage" : "Hallitse",
"Discard share" : "Peru jakaminen",
"Create a new label" : "Lisää uusi etiketti",
"Board title" : "Taulun otsikko",
"Members" : "Jäsenet",
"Create new board" : "Luo uusi taulu",
"New board title" : "Uusi taulun otsikko",
"Modified:" : "Muokattu:",
"Created:" : "Luotu:",
"by" : " Kirjoittaja:",
"Saved" : "Tallennettu",
"Add a card description ..." : "Lisää kortille kuvaus",
"Attachments" : "Liitteet",
"Comments" : "Kommentit",
"History" : "Historia",
"All Boards" : "Kaikki Taulut",
"Shared with you" : "Jaetu kanssasi",
"edit" : "muokkaa",
"delete" : "poista",
"remove share" : "poista jako",
"Create a new board" : "Luo uusi taulu"
},
"nplurals=2; plural=(n != 1);");

42
l10n/fi.json Normal file
View File

@@ -0,0 +1,42 @@
{ "translations": {
"Deck" : "Kansi",
"Finished" : "Valmistunut",
"To review" : "Arvostella",
"Action needed" : "Toimia vaaditaan",
"Later" : "Myöhemmin",
"Show archived cards" : "Näytä arkistoidut kortit",
"Hide archived cards" : "Piilota arkistoidut kortit",
"Board details" : "Taulun tiedot",
"Archive" : "Arkisto",
"Unarchive" : "Pois arkistosta",
"Delete" : "Poista",
"Enter a card title" : "Anna otsikko",
"Sharing" : "Jakaminen",
"Labels" : "Etiketit",
"Select users or groups to share with" : "Valitse käyttäjiä tai ryhmiä joille haluat jakaa",
"No matching user or group found." : "Käyttäjää tai ryhmää ei löytynyt.",
"Share" : "Jaa",
"Edit" : "Muokkaa",
"Manage" : "Hallitse",
"Discard share" : "Peru jakaminen",
"Create a new label" : "Lisää uusi etiketti",
"Board title" : "Taulun otsikko",
"Members" : "Jäsenet",
"Create new board" : "Luo uusi taulu",
"New board title" : "Uusi taulun otsikko",
"Modified:" : "Muokattu:",
"Created:" : "Luotu:",
"by" : " Kirjoittaja:",
"Saved" : "Tallennettu",
"Add a card description ..." : "Lisää kortille kuvaus",
"Attachments" : "Liitteet",
"Comments" : "Kommentit",
"History" : "Historia",
"All Boards" : "Kaikki Taulut",
"Shared with you" : "Jaetu kanssasi",
"edit" : "muokkaa",
"delete" : "poista",
"remove share" : "poista jako",
"Create a new board" : "Luo uusi taulu"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}

44
l10n/fr.js Normal file
View File

@@ -0,0 +1,44 @@
OC.L10N.register(
"deck",
{
"Deck" : "Deck",
"Finished" : "Terminé",
"To review" : "A réviser",
"Action needed" : "Action requise",
"Later" : "Plus tard",
"Show archived cards" : "Afficher les cartes archivées",
"Hide archived cards" : "Masquer les cartes archivées",
"Board details" : "Détails du tableau",
"Archive" : "Archiver",
"Unarchive" : "Ne plus archiver",
"Delete" : "Supprimer",
"Enter a card title" : "Saisissez un titre de carte",
"Sharing" : "Partage",
"Labels" : "Étiquettes",
"Select users or groups to share with" : "Sélectionnez des utilisateurs ou des groupes avec qui partager",
"No matching user or group found." : "Aucun utilisateur ou groupe correspondant trouvé",
"Share" : "Partager",
"Edit" : "Modifier",
"Manage" : "Gérer",
"Discard share" : "Supprimer le partage",
"Create a new label" : "Créer une nouvelle étiquette",
"Board title" : "Titre du tableau",
"Members" : "Membres",
"Create new board" : "Créer un nouveau tableau",
"New board title" : "Nouveau titre pour le tableau",
"Modified:" : "Modifié le :",
"Created:" : "Créé le :",
"by" : "par",
"Saved" : "Enregistré",
"Add a card description ..." : "Ajouter une description pour la carte",
"Attachments" : "Pièces jointes",
"Comments" : "Commentaires",
"History" : "Journal",
"All Boards" : "Tous les tableaux",
"Shared with you" : "Partagé avec vous",
"edit" : "modifier",
"delete" : "suppression",
"remove share" : "suppression du partage",
"Create a new board" : "Créer un nouveau tableau"
},
"nplurals=2; plural=(n > 1);");

42
l10n/fr.json Normal file
View File

@@ -0,0 +1,42 @@
{ "translations": {
"Deck" : "Deck",
"Finished" : "Terminé",
"To review" : "A réviser",
"Action needed" : "Action requise",
"Later" : "Plus tard",
"Show archived cards" : "Afficher les cartes archivées",
"Hide archived cards" : "Masquer les cartes archivées",
"Board details" : "Détails du tableau",
"Archive" : "Archiver",
"Unarchive" : "Ne plus archiver",
"Delete" : "Supprimer",
"Enter a card title" : "Saisissez un titre de carte",
"Sharing" : "Partage",
"Labels" : "Étiquettes",
"Select users or groups to share with" : "Sélectionnez des utilisateurs ou des groupes avec qui partager",
"No matching user or group found." : "Aucun utilisateur ou groupe correspondant trouvé",
"Share" : "Partager",
"Edit" : "Modifier",
"Manage" : "Gérer",
"Discard share" : "Supprimer le partage",
"Create a new label" : "Créer une nouvelle étiquette",
"Board title" : "Titre du tableau",
"Members" : "Membres",
"Create new board" : "Créer un nouveau tableau",
"New board title" : "Nouveau titre pour le tableau",
"Modified:" : "Modifié le :",
"Created:" : "Créé le :",
"by" : "par",
"Saved" : "Enregistré",
"Add a card description ..." : "Ajouter une description pour la carte",
"Attachments" : "Pièces jointes",
"Comments" : "Commentaires",
"History" : "Journal",
"All Boards" : "Tous les tableaux",
"Shared with you" : "Partagé avec vous",
"edit" : "modifier",
"delete" : "suppression",
"remove share" : "suppression du partage",
"Create a new board" : "Créer un nouveau tableau"
},"pluralForm" :"nplurals=2; plural=(n > 1);"
}

23
l10n/hu.js Normal file
View File

@@ -0,0 +1,23 @@
OC.L10N.register(
"deck",
{
"Finished" : "Kész",
"Action needed" : "Művelet szükséges",
"Later" : "Később",
"Delete" : "Törlés",
"Sharing" : "Megosztás",
"Labels" : "Címkék",
"Share" : "Megosztás",
"Edit" : "Szerkesztés",
"Manage" : "Kezelés",
"Members" : "Tagok",
"Modified:" : "Módosítva:",
"Created:" : "Létrehozva:",
"Saved" : "Elmentve",
"Comments" : "Hozzászólások",
"History" : "Előzmények",
"Shared with you" : "Megosztva veled",
"edit" : "szerkesztés",
"delete" : "törlés"
},
"nplurals=2; plural=(n != 1);");

21
l10n/hu.json Normal file
View File

@@ -0,0 +1,21 @@
{ "translations": {
"Finished" : "Kész",
"Action needed" : "Művelet szükséges",
"Later" : "Később",
"Delete" : "Törlés",
"Sharing" : "Megosztás",
"Labels" : "Címkék",
"Share" : "Megosztás",
"Edit" : "Szerkesztés",
"Manage" : "Kezelés",
"Members" : "Tagok",
"Modified:" : "Módosítva:",
"Created:" : "Létrehozva:",
"Saved" : "Elmentve",
"Comments" : "Hozzászólások",
"History" : "Előzmények",
"Shared with you" : "Megosztva veled",
"edit" : "szerkesztés",
"delete" : "törlés"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}

27
l10n/ia.js Normal file
View File

@@ -0,0 +1,27 @@
OC.L10N.register(
"deck",
{
"Finished" : "Finite",
"To review" : "A revider",
"Action needed" : "Action necessari",
"Later" : "Depost",
"Delete" : "Deler",
"Labels" : "Etiquettas",
"Select users or groups to share with" : "Selectiona usatores o gruppos pro compartir",
"No matching user or group found." : "Nulle usator o gruppo correspondente trovate.",
"Share" : "Compartir",
"Edit" : "Modificar",
"Manage" : "Administrar",
"Members" : "Membros",
"Modified:" : "Modificate:",
"Created:" : "Create:",
"by" : "per",
"Saved" : "Salveguardate",
"Attachments" : "Attachamentos",
"Comments" : "Commentarios",
"History" : "Historia",
"Shared with you" : "Compartite con te",
"edit" : "modificar",
"delete" : "deler"
},
"nplurals=2; plural=(n != 1);");

25
l10n/ia.json Normal file
View File

@@ -0,0 +1,25 @@
{ "translations": {
"Finished" : "Finite",
"To review" : "A revider",
"Action needed" : "Action necessari",
"Later" : "Depost",
"Delete" : "Deler",
"Labels" : "Etiquettas",
"Select users or groups to share with" : "Selectiona usatores o gruppos pro compartir",
"No matching user or group found." : "Nulle usator o gruppo correspondente trovate.",
"Share" : "Compartir",
"Edit" : "Modificar",
"Manage" : "Administrar",
"Members" : "Membros",
"Modified:" : "Modificate:",
"Created:" : "Create:",
"by" : "per",
"Saved" : "Salveguardate",
"Attachments" : "Attachamentos",
"Comments" : "Commentarios",
"History" : "Historia",
"Shared with you" : "Compartite con te",
"edit" : "modificar",
"delete" : "deler"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}

44
l10n/is.js Normal file
View File

@@ -0,0 +1,44 @@
OC.L10N.register(
"deck",
{
"Deck" : "Dekk",
"Finished" : "Lokið",
"To review" : "Til að yfirfara",
"Action needed" : "Aðgerðar krafist",
"Later" : "Seinna",
"Show archived cards" : "Sýna spjöld í geymslu",
"Hide archived cards" : "Fela spjöld í geymslu",
"Board details" : "Nánar um bretti",
"Archive" : "Setja í safnskrá",
"Unarchive" : "Taka úr geymslu",
"Delete" : "Eyða",
"Enter a card title" : "Sláðu inn titil á spjald",
"Sharing" : "Deiling",
"Labels" : "Skýringar",
"Select users or groups to share with" : "Veldu notendur eða hópa til að deila með",
"No matching user or group found." : "Engir samsvarandi notendur eða hópar fundust.",
"Share" : "Deila",
"Edit" : "Breyta",
"Manage" : "Skipuleggja",
"Discard share" : "Henda sameign",
"Create a new label" : "Búa til nýja skýringu",
"Board title" : "Titill á borði",
"Members" : "Meðlimir",
"Create new board" : "Búa til nýtt borð",
"New board title" : "Nýr titill á borð",
"Modified:" : "Breytt þann:",
"Created:" : "Búið til:",
"by" : "af",
"Saved" : "Vistað",
"Add a card description ..." : "Settu inn lýsingu á spjaldi ...",
"Attachments" : "Viðhengi",
"Comments" : "Athugasemdir",
"History" : "Ferill",
"All Boards" : "Öll borð",
"Shared with you" : "Deilt með þér",
"edit" : "breyta",
"delete" : "eyða",
"remove share" : "fjarlægja sameign...",
"Create a new board" : "Búa til nýtt borð"
},
"nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);");

42
l10n/is.json Normal file
View File

@@ -0,0 +1,42 @@
{ "translations": {
"Deck" : "Dekk",
"Finished" : "Lokið",
"To review" : "Til að yfirfara",
"Action needed" : "Aðgerðar krafist",
"Later" : "Seinna",
"Show archived cards" : "Sýna spjöld í geymslu",
"Hide archived cards" : "Fela spjöld í geymslu",
"Board details" : "Nánar um bretti",
"Archive" : "Setja í safnskrá",
"Unarchive" : "Taka úr geymslu",
"Delete" : "Eyða",
"Enter a card title" : "Sláðu inn titil á spjald",
"Sharing" : "Deiling",
"Labels" : "Skýringar",
"Select users or groups to share with" : "Veldu notendur eða hópa til að deila með",
"No matching user or group found." : "Engir samsvarandi notendur eða hópar fundust.",
"Share" : "Deila",
"Edit" : "Breyta",
"Manage" : "Skipuleggja",
"Discard share" : "Henda sameign",
"Create a new label" : "Búa til nýja skýringu",
"Board title" : "Titill á borði",
"Members" : "Meðlimir",
"Create new board" : "Búa til nýtt borð",
"New board title" : "Nýr titill á borð",
"Modified:" : "Breytt þann:",
"Created:" : "Búið til:",
"by" : "af",
"Saved" : "Vistað",
"Add a card description ..." : "Settu inn lýsingu á spjaldi ...",
"Attachments" : "Viðhengi",
"Comments" : "Athugasemdir",
"History" : "Ferill",
"All Boards" : "Öll borð",
"Shared with you" : "Deilt með þér",
"edit" : "breyta",
"delete" : "eyða",
"remove share" : "fjarlægja sameign...",
"Create a new board" : "Búa til nýtt borð"
},"pluralForm" :"nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);"
}

44
l10n/it.js Normal file
View File

@@ -0,0 +1,44 @@
OC.L10N.register(
"deck",
{
"Deck" : "Deck",
"Finished" : "Finito",
"To review" : "Da revisionare",
"Action needed" : "Azione necessaria",
"Later" : "Dopo",
"Show archived cards" : "Mostra le carte archiviate",
"Hide archived cards" : "Nascondi le carte archiviate",
"Board details" : "Dettaglio lavagna",
"Archive" : "Archivio",
"Unarchive" : "Togli dall'archivio",
"Delete" : "Elimina",
"Enter a card title" : "Inserisci un titolo alla scheda",
"Sharing" : "Condivisione",
"Labels" : "Etichette",
"Select users or groups to share with" : "Seleziona utenti o gruppi con cui condividere",
"No matching user or group found." : "Nessun utente o gruppo trovato.",
"Share" : "Condividi",
"Edit" : "Modifica",
"Manage" : "Gestisci",
"Discard share" : "Annulla condivisione",
"Create a new label" : "Crea una nuova etichetta",
"Board title" : "Titolo della lavagna",
"Members" : "Membri",
"Create new board" : "Crea una nuova lavagna",
"New board title" : "Titolo nuova lavagna",
"Modified:" : "Modificato:",
"Created:" : "Creato:",
"by" : "da",
"Saved" : "Salvato",
"Add a card description ..." : "Aggiungi descrizione della scheda...",
"Attachments" : "Allegati",
"Comments" : "Commenti",
"History" : "Cronologia",
"All Boards" : "Tutte le lavagne",
"Shared with you" : "Condiviso con te",
"edit" : "modifica",
"delete" : "elimina",
"remove share" : "rimuovi condivisione",
"Create a new board" : "Crea una nuova lavagna"
},
"nplurals=2; plural=(n != 1);");

42
l10n/it.json Normal file
View File

@@ -0,0 +1,42 @@
{ "translations": {
"Deck" : "Deck",
"Finished" : "Finito",
"To review" : "Da revisionare",
"Action needed" : "Azione necessaria",
"Later" : "Dopo",
"Show archived cards" : "Mostra le carte archiviate",
"Hide archived cards" : "Nascondi le carte archiviate",
"Board details" : "Dettaglio lavagna",
"Archive" : "Archivio",
"Unarchive" : "Togli dall'archivio",
"Delete" : "Elimina",
"Enter a card title" : "Inserisci un titolo alla scheda",
"Sharing" : "Condivisione",
"Labels" : "Etichette",
"Select users or groups to share with" : "Seleziona utenti o gruppi con cui condividere",
"No matching user or group found." : "Nessun utente o gruppo trovato.",
"Share" : "Condividi",
"Edit" : "Modifica",
"Manage" : "Gestisci",
"Discard share" : "Annulla condivisione",
"Create a new label" : "Crea una nuova etichetta",
"Board title" : "Titolo della lavagna",
"Members" : "Membri",
"Create new board" : "Crea una nuova lavagna",
"New board title" : "Titolo nuova lavagna",
"Modified:" : "Modificato:",
"Created:" : "Creato:",
"by" : "da",
"Saved" : "Salvato",
"Add a card description ..." : "Aggiungi descrizione della scheda...",
"Attachments" : "Allegati",
"Comments" : "Commenti",
"History" : "Cronologia",
"All Boards" : "Tutte le lavagne",
"Shared with you" : "Condiviso con te",
"edit" : "modifica",
"delete" : "elimina",
"remove share" : "rimuovi condivisione",
"Create a new board" : "Crea una nuova lavagna"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}

44
l10n/ko.js Normal file
View File

@@ -0,0 +1,44 @@
OC.L10N.register(
"deck",
{
"Deck" : "덱",
"Finished" : "완료됨",
"To review" : "리뷰할 항목",
"Action needed" : "동작 필요",
"Later" : "나중에",
"Show archived cards" : "보관된 카드 보기",
"Hide archived cards" : "보관된 카드 숨기기",
"Board details" : "게시판 정보",
"Archive" : "보관",
"Unarchive" : "보관 해제",
"Delete" : "삭제",
"Enter a card title" : "카드 제목 입력",
"Sharing" : "공유",
"Labels" : "이름표",
"Select users or groups to share with" : "공유할 사용자나 그룹 선택",
"No matching user or group found." : "일치하는 사용자나 그룹이 없습니다.",
"Share" : "공유",
"Edit" : "편집",
"Manage" : "관리",
"Discard share" : "공유 무시",
"Create a new label" : "새 이름표 만들기",
"Board title" : "게시판 제목",
"Members" : "구성원",
"Create new board" : "새 게시판 만들기",
"New board title" : "새 게시판 제목",
"Modified:" : "수정한 날짜:",
"Created:" : "만든 날짜:",
"by" : "by",
"Saved" : "저장됨",
"Add a card description ..." : "카드 설명 추가 ...",
"Attachments" : "첨부",
"Comments" : "댓글",
"History" : "과거 기록",
"All Boards" : "모든 게시판",
"Shared with you" : "내게 공유됨",
"edit" : "편집",
"delete" : "삭제",
"remove share" : "공유 삭제",
"Create a new board" : "새 게시판 만들기"
},
"nplurals=1; plural=0;");

42
l10n/ko.json Normal file
View File

@@ -0,0 +1,42 @@
{ "translations": {
"Deck" : "덱",
"Finished" : "완료됨",
"To review" : "리뷰할 항목",
"Action needed" : "동작 필요",
"Later" : "나중에",
"Show archived cards" : "보관된 카드 보기",
"Hide archived cards" : "보관된 카드 숨기기",
"Board details" : "게시판 정보",
"Archive" : "보관",
"Unarchive" : "보관 해제",
"Delete" : "삭제",
"Enter a card title" : "카드 제목 입력",
"Sharing" : "공유",
"Labels" : "이름표",
"Select users or groups to share with" : "공유할 사용자나 그룹 선택",
"No matching user or group found." : "일치하는 사용자나 그룹이 없습니다.",
"Share" : "공유",
"Edit" : "편집",
"Manage" : "관리",
"Discard share" : "공유 무시",
"Create a new label" : "새 이름표 만들기",
"Board title" : "게시판 제목",
"Members" : "구성원",
"Create new board" : "새 게시판 만들기",
"New board title" : "새 게시판 제목",
"Modified:" : "수정한 날짜:",
"Created:" : "만든 날짜:",
"by" : "by",
"Saved" : "저장됨",
"Add a card description ..." : "카드 설명 추가 ...",
"Attachments" : "첨부",
"Comments" : "댓글",
"History" : "과거 기록",
"All Boards" : "모든 게시판",
"Shared with you" : "내게 공유됨",
"edit" : "편집",
"delete" : "삭제",
"remove share" : "공유 삭제",
"Create a new board" : "새 게시판 만들기"
},"pluralForm" :"nplurals=1; plural=0;"
}

28
l10n/lv.js Normal file
View File

@@ -0,0 +1,28 @@
OC.L10N.register(
"deck",
{
"Finished" : "Pabeigts",
"Later" : "Vēlāk",
"Show archived cards" : "Rādīt arhivētās kartes",
"Hide archived cards" : "Slēpt arhivētās kartes",
"Archive" : "Arhīvi",
"Delete" : "Dzēst",
"Enter a card title" : "Ievadiet kartes nosaukumu",
"Sharing" : "Koplietošana",
"Select users or groups to share with" : "Atlasiet lietotājus vai grupas ar kuriem koplietot",
"Share" : "Koplietot",
"Edit" : "Rediģēt",
"Discard share" : "Atcelt koplietošanu",
"Members" : "Biedri",
"Modified:" : "Modificēta:",
"Created:" : "Izveidota:",
"Saved" : "Saglabāts",
"Attachments" : "Pielikumi",
"Comments" : "Komentāri",
"History" : "Vēsture",
"Shared with you" : "Koplietots ar tevi",
"edit" : "rediģēt",
"delete" : "dzēst",
"remove share" : "noņemt koplietojumu"
},
"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);");

26
l10n/lv.json Normal file
View File

@@ -0,0 +1,26 @@
{ "translations": {
"Finished" : "Pabeigts",
"Later" : "Vēlāk",
"Show archived cards" : "Rādīt arhivētās kartes",
"Hide archived cards" : "Slēpt arhivētās kartes",
"Archive" : "Arhīvi",
"Delete" : "Dzēst",
"Enter a card title" : "Ievadiet kartes nosaukumu",
"Sharing" : "Koplietošana",
"Select users or groups to share with" : "Atlasiet lietotājus vai grupas ar kuriem koplietot",
"Share" : "Koplietot",
"Edit" : "Rediģēt",
"Discard share" : "Atcelt koplietošanu",
"Members" : "Biedri",
"Modified:" : "Modificēta:",
"Created:" : "Izveidota:",
"Saved" : "Saglabāts",
"Attachments" : "Pielikumi",
"Comments" : "Komentāri",
"History" : "Vēsture",
"Shared with you" : "Koplietots ar tevi",
"edit" : "rediģēt",
"delete" : "dzēst",
"remove share" : "noņemt koplietojumu"
},"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);"
}

44
l10n/nb.js Normal file
View File

@@ -0,0 +1,44 @@
OC.L10N.register(
"deck",
{
"Deck" : "Stokk",
"Finished" : "Fullført",
"To review" : "Til gjennomlesning",
"Action needed" : "Handling påkrevd",
"Later" : "Senere",
"Show archived cards" : "Vis arkiverkte kort",
"Hide archived cards" : "Skjul arkiverte kort",
"Board details" : "Bordetaljer",
"Archive" : "Arkiv",
"Unarchive" : "Dearkivere",
"Delete" : "Slett",
"Enter a card title" : "Skriv inn en kort tittel",
"Sharing" : "Deling",
"Labels" : "Etiketter",
"Select users or groups to share with" : "Velg brukere og grupper du vil dele med",
"No matching user or group found." : "Ingen treff på bruker eller gruppe.",
"Share" : "Del",
"Edit" : "Endre",
"Manage" : "Håndtere",
"Discard share" : "Fjern deling",
"Create a new label" : "Opprett en ny etikett",
"Board title" : "Bordtittel",
"Members" : "Medlemmer",
"Create new board" : "Opprett et nytt bord",
"New board title" : "Ny bord tittel",
"Modified:" : "Endret:",
"Created:" : "Opprettet:",
"by" : "av",
"Saved" : "Lagret",
"Add a card description ..." : "Legg til en beskrivelse av kortet",
"Attachments" : "Vedlegg",
"Comments" : "Kommentarer",
"History" : "Historikk",
"All Boards" : "Alle bord",
"Shared with you" : "Delt med deg",
"edit" : "endre",
"delete" : "slett",
"remove share" : "fjern deling",
"Create a new board" : "Opprett et nytt bord"
},
"nplurals=2; plural=(n != 1);");

42
l10n/nb.json Normal file
View File

@@ -0,0 +1,42 @@
{ "translations": {
"Deck" : "Stokk",
"Finished" : "Fullført",
"To review" : "Til gjennomlesning",
"Action needed" : "Handling påkrevd",
"Later" : "Senere",
"Show archived cards" : "Vis arkiverkte kort",
"Hide archived cards" : "Skjul arkiverte kort",
"Board details" : "Bordetaljer",
"Archive" : "Arkiv",
"Unarchive" : "Dearkivere",
"Delete" : "Slett",
"Enter a card title" : "Skriv inn en kort tittel",
"Sharing" : "Deling",
"Labels" : "Etiketter",
"Select users or groups to share with" : "Velg brukere og grupper du vil dele med",
"No matching user or group found." : "Ingen treff på bruker eller gruppe.",
"Share" : "Del",
"Edit" : "Endre",
"Manage" : "Håndtere",
"Discard share" : "Fjern deling",
"Create a new label" : "Opprett en ny etikett",
"Board title" : "Bordtittel",
"Members" : "Medlemmer",
"Create new board" : "Opprett et nytt bord",
"New board title" : "Ny bord tittel",
"Modified:" : "Endret:",
"Created:" : "Opprettet:",
"by" : "av",
"Saved" : "Lagret",
"Add a card description ..." : "Legg til en beskrivelse av kortet",
"Attachments" : "Vedlegg",
"Comments" : "Kommentarer",
"History" : "Historikk",
"All Boards" : "Alle bord",
"Shared with you" : "Delt med deg",
"edit" : "endre",
"delete" : "slett",
"remove share" : "fjern deling",
"Create a new board" : "Opprett et nytt bord"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}

44
l10n/nl.js Normal file
View File

@@ -0,0 +1,44 @@
OC.L10N.register(
"deck",
{
"Deck" : "Deck",
"Finished" : "Afgerond",
"To review" : "Beoordelen",
"Action needed" : "Actie benodigd",
"Later" : "Later",
"Show archived cards" : "Gearchiveerde kaarten weergeven",
"Hide archived cards" : "Gearchiveerde kaarten verbergen",
"Board details" : "Bord details",
"Archive" : "Archiveer",
"Unarchive" : "Terugzetten uit archief",
"Delete" : "Verwijderen",
"Enter a card title" : "Kaart titel toevoegen",
"Sharing" : "Delen",
"Labels" : "Labels",
"Select users or groups to share with" : "Gebruikers of groepen selecteren om te delen",
"No matching user or group found." : "Geen passende gebruiker of groep gevonden",
"Share" : "Delen",
"Edit" : "Bewerken",
"Manage" : "Beheren",
"Discard share" : "Delen uitzetten",
"Create a new label" : "Nieuw label creëren",
"Board title" : "Bord titel",
"Members" : "Leden",
"Create new board" : "Nieuw bord maken",
"New board title" : "Nieuwe bord titel",
"Modified:" : "Bewerkt:",
"Created:" : "Gemaakt:",
"by" : "door",
"Saved" : "Opgeslagen",
"Add a card description ..." : "Kaart beschrijving toevoegen ...",
"Attachments" : "Bijlage",
"Comments" : "Opmerkingen",
"History" : "Geschiedenis",
"All Boards" : "Alle borden",
"Shared with you" : "Deel met jou",
"edit" : "Bewerk",
"delete" : "verwijder",
"remove share" : "verwijder gedeelde",
"Create a new board" : "Een nieuw bord maken"
},
"nplurals=2; plural=(n != 1);");

42
l10n/nl.json Normal file
View File

@@ -0,0 +1,42 @@
{ "translations": {
"Deck" : "Deck",
"Finished" : "Afgerond",
"To review" : "Beoordelen",
"Action needed" : "Actie benodigd",
"Later" : "Later",
"Show archived cards" : "Gearchiveerde kaarten weergeven",
"Hide archived cards" : "Gearchiveerde kaarten verbergen",
"Board details" : "Bord details",
"Archive" : "Archiveer",
"Unarchive" : "Terugzetten uit archief",
"Delete" : "Verwijderen",
"Enter a card title" : "Kaart titel toevoegen",
"Sharing" : "Delen",
"Labels" : "Labels",
"Select users or groups to share with" : "Gebruikers of groepen selecteren om te delen",
"No matching user or group found." : "Geen passende gebruiker of groep gevonden",
"Share" : "Delen",
"Edit" : "Bewerken",
"Manage" : "Beheren",
"Discard share" : "Delen uitzetten",
"Create a new label" : "Nieuw label creëren",
"Board title" : "Bord titel",
"Members" : "Leden",
"Create new board" : "Nieuw bord maken",
"New board title" : "Nieuwe bord titel",
"Modified:" : "Bewerkt:",
"Created:" : "Gemaakt:",
"by" : "door",
"Saved" : "Opgeslagen",
"Add a card description ..." : "Kaart beschrijving toevoegen ...",
"Attachments" : "Bijlage",
"Comments" : "Opmerkingen",
"History" : "Geschiedenis",
"All Boards" : "Alle borden",
"Shared with you" : "Deel met jou",
"edit" : "Bewerk",
"delete" : "verwijder",
"remove share" : "verwijder gedeelde",
"Create a new board" : "Een nieuw bord maken"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}

44
l10n/pl.js Normal file
View File

@@ -0,0 +1,44 @@
OC.L10N.register(
"deck",
{
"Deck" : "Deck",
"Finished" : "Ukończone",
"To review" : "Do sprawdzenia",
"Action needed" : "Wymagające akcji",
"Later" : "Później",
"Show archived cards" : "Pokaż zarchiwizowane karty",
"Hide archived cards" : "Ukryj zarchiwizowane karty",
"Board details" : "Szczegóły tablicy",
"Archive" : "Archiwizuj",
"Unarchive" : "Nie archiwizuj",
"Delete" : "Usuń",
"Enter a card title" : "Wprowadź tytuł karty",
"Sharing" : "Współdzielenie",
"Labels" : "Etykiety",
"Select users or groups to share with" : "Wybierz użytkowników lub grupy, żeby współdzielić z nimi",
"No matching user or group found." : "Nie znaleziono pasujących użytkowników lub grup",
"Share" : "Współdziel",
"Edit" : "Edycja",
"Manage" : "Zarządzanie",
"Discard share" : "Usuń współdzielenie",
"Create a new label" : "Utwórz nową etykietę",
"Board title" : "Tytuł tablicy",
"Members" : "Członkowie",
"Create new board" : "Utwórz nową tablicę",
"New board title" : "Tytuł nowej tablicy",
"Modified:" : "Zmodyfikowano:",
"Created:" : "Utworzono:",
"by" : "przez",
"Saved" : "Zapisano",
"Add a card description ..." : "Dodaj opis karty",
"Attachments" : "Załączniki",
"Comments" : "Komentarze",
"History" : "Historia",
"All Boards" : "Tablice",
"Shared with you" : "Współdzielone z tobą",
"edit" : "edytuj",
"delete" : "usuń",
"remove share" : "usuń współdzielenie",
"Create a new board" : "Utwórz nową tablicę"
},
"nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>=14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);");

42
l10n/pl.json Normal file
View File

@@ -0,0 +1,42 @@
{ "translations": {
"Deck" : "Deck",
"Finished" : "Ukończone",
"To review" : "Do sprawdzenia",
"Action needed" : "Wymagające akcji",
"Later" : "Później",
"Show archived cards" : "Pokaż zarchiwizowane karty",
"Hide archived cards" : "Ukryj zarchiwizowane karty",
"Board details" : "Szczegóły tablicy",
"Archive" : "Archiwizuj",
"Unarchive" : "Nie archiwizuj",
"Delete" : "Usuń",
"Enter a card title" : "Wprowadź tytuł karty",
"Sharing" : "Współdzielenie",
"Labels" : "Etykiety",
"Select users or groups to share with" : "Wybierz użytkowników lub grupy, żeby współdzielić z nimi",
"No matching user or group found." : "Nie znaleziono pasujących użytkowników lub grup",
"Share" : "Współdziel",
"Edit" : "Edycja",
"Manage" : "Zarządzanie",
"Discard share" : "Usuń współdzielenie",
"Create a new label" : "Utwórz nową etykietę",
"Board title" : "Tytuł tablicy",
"Members" : "Członkowie",
"Create new board" : "Utwórz nową tablicę",
"New board title" : "Tytuł nowej tablicy",
"Modified:" : "Zmodyfikowano:",
"Created:" : "Utworzono:",
"by" : "przez",
"Saved" : "Zapisano",
"Add a card description ..." : "Dodaj opis karty",
"Attachments" : "Załączniki",
"Comments" : "Komentarze",
"History" : "Historia",
"All Boards" : "Tablice",
"Shared with you" : "Współdzielone z tobą",
"edit" : "edytuj",
"delete" : "usuń",
"remove share" : "usuń współdzielenie",
"Create a new board" : "Utwórz nową tablicę"
},"pluralForm" :"nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>=14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);"
}

44
l10n/pt_BR.js Normal file
View File

@@ -0,0 +1,44 @@
OC.L10N.register(
"deck",
{
"Deck" : "Mesa",
"Finished" : "Terminado",
"To review" : "Para revisão",
"Action needed" : "Ação necessária",
"Later" : "Depois",
"Show archived cards" : "Mostrar cartões arquivados",
"Hide archived cards" : "Ocultar cartões arquivados",
"Board details" : "Detalhes do quadro",
"Archive" : "Arquivar",
"Unarchive" : "Desarquivar",
"Delete" : "Excluir",
"Enter a card title" : "Digite um título de cartão",
"Sharing" : "Compartilhar",
"Labels" : "Etiquetas",
"Select users or groups to share with" : "Selecionar usuários ou grupos para compartilhar",
"No matching user or group found." : "Uusuário ou grupo não encontrado.",
"Share" : "Compartilhar",
"Edit" : "Editar",
"Manage" : "Gerenciar",
"Discard share" : "Descartar compartilhamento",
"Create a new label" : "Criar uma nova etiqueta",
"Board title" : "Título do quadro",
"Members" : "Membros",
"Create new board" : "Criar novo quadro",
"New board title" : "Título do novo quadro",
"Modified:" : "Modificado:",
"Created:" : "Criado:",
"by" : "por",
"Saved" : "Salvo",
"Add a card description ..." : "Adicionar uma descrição de cartão...",
"Attachments" : "Anexos",
"Comments" : "Comentários",
"History" : "Histórico",
"All Boards" : "Todos os quadros",
"Shared with you" : "Compartilhado com você",
"edit" : "editar",
"delete" : "excluir",
"remove share" : "excluir compartilhamento",
"Create a new board" : "Criar um novo quadro"
},
"nplurals=2; plural=(n > 1);");

42
l10n/pt_BR.json Normal file
View File

@@ -0,0 +1,42 @@
{ "translations": {
"Deck" : "Mesa",
"Finished" : "Terminado",
"To review" : "Para revisão",
"Action needed" : "Ação necessária",
"Later" : "Depois",
"Show archived cards" : "Mostrar cartões arquivados",
"Hide archived cards" : "Ocultar cartões arquivados",
"Board details" : "Detalhes do quadro",
"Archive" : "Arquivar",
"Unarchive" : "Desarquivar",
"Delete" : "Excluir",
"Enter a card title" : "Digite um título de cartão",
"Sharing" : "Compartilhar",
"Labels" : "Etiquetas",
"Select users or groups to share with" : "Selecionar usuários ou grupos para compartilhar",
"No matching user or group found." : "Uusuário ou grupo não encontrado.",
"Share" : "Compartilhar",
"Edit" : "Editar",
"Manage" : "Gerenciar",
"Discard share" : "Descartar compartilhamento",
"Create a new label" : "Criar uma nova etiqueta",
"Board title" : "Título do quadro",
"Members" : "Membros",
"Create new board" : "Criar novo quadro",
"New board title" : "Título do novo quadro",
"Modified:" : "Modificado:",
"Created:" : "Criado:",
"by" : "por",
"Saved" : "Salvo",
"Add a card description ..." : "Adicionar uma descrição de cartão...",
"Attachments" : "Anexos",
"Comments" : "Comentários",
"History" : "Histórico",
"All Boards" : "Todos os quadros",
"Shared with you" : "Compartilhado com você",
"edit" : "editar",
"delete" : "excluir",
"remove share" : "excluir compartilhamento",
"Create a new board" : "Criar um novo quadro"
},"pluralForm" :"nplurals=2; plural=(n > 1);"
}

44
l10n/ru.js Normal file
View File

@@ -0,0 +1,44 @@
OC.L10N.register(
"deck",
{
"Deck" : "Deck",
"Finished" : "Завершено",
"To review" : "Просмотреть",
"Action needed" : "Требуется действие",
"Later" : "Позже",
"Show archived cards" : "Показать архивные карточки",
"Hide archived cards" : "Скрыть архивные карточки",
"Board details" : "Подробности доски",
"Archive" : "Архивировать",
"Unarchive" : "Разархивировать",
"Delete" : "Удалить",
"Enter a card title" : "Введите заголовок карточки",
"Sharing" : "Общий доступ",
"Labels" : "Метки",
"Select users or groups to share with" : "Поделиться с пользователями или группами",
"No matching user or group found." : "Соответствующей группы или пользователей не найдено",
"Share" : "Поделиться",
"Edit" : "Редактировать",
"Manage" : "Управлять",
"Discard share" : "Отказаться от предложения общего доступа",
"Create a new label" : "Создать новую метку",
"Board title" : "Заголовок доски",
"Members" : "Участники",
"Create new board" : "Создать новую доску",
"New board title" : "Заголовок новой доски",
"Modified:" : "Изменён:",
"Created:" : "Создан:",
"by" : "автор",
"Saved" : "Сохранено",
"Add a card description ..." : "Добавить описание карточки…",
"Attachments" : "Вложения",
"Comments" : "Комментарии",
"History" : "История",
"All Boards" : "Все доски",
"Shared with you" : "Поделились с вами",
"edit" : "редактировать",
"delete" : "удалить",
"remove share" : "закрыть общий доступ",
"Create a new board" : "Создать новую доску"
},
"nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);");

42
l10n/ru.json Normal file
View File

@@ -0,0 +1,42 @@
{ "translations": {
"Deck" : "Deck",
"Finished" : "Завершено",
"To review" : "Просмотреть",
"Action needed" : "Требуется действие",
"Later" : "Позже",
"Show archived cards" : "Показать архивные карточки",
"Hide archived cards" : "Скрыть архивные карточки",
"Board details" : "Подробности доски",
"Archive" : "Архивировать",
"Unarchive" : "Разархивировать",
"Delete" : "Удалить",
"Enter a card title" : "Введите заголовок карточки",
"Sharing" : "Общий доступ",
"Labels" : "Метки",
"Select users or groups to share with" : "Поделиться с пользователями или группами",
"No matching user or group found." : "Соответствующей группы или пользователей не найдено",
"Share" : "Поделиться",
"Edit" : "Редактировать",
"Manage" : "Управлять",
"Discard share" : "Отказаться от предложения общего доступа",
"Create a new label" : "Создать новую метку",
"Board title" : "Заголовок доски",
"Members" : "Участники",
"Create new board" : "Создать новую доску",
"New board title" : "Заголовок новой доски",
"Modified:" : "Изменён:",
"Created:" : "Создан:",
"by" : "автор",
"Saved" : "Сохранено",
"Add a card description ..." : "Добавить описание карточки…",
"Attachments" : "Вложения",
"Comments" : "Комментарии",
"History" : "История",
"All Boards" : "Все доски",
"Shared with you" : "Поделились с вами",
"edit" : "редактировать",
"delete" : "удалить",
"remove share" : "закрыть общий доступ",
"Create a new board" : "Создать новую доску"
},"pluralForm" :"nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);"
}

44
l10n/sk.js Normal file
View File

@@ -0,0 +1,44 @@
OC.L10N.register(
"deck",
{
"Deck" : "Tabuľa",
"Finished" : "Ukončené",
"To review" : "Na posúdenie",
"Action needed" : "Potrebná akcia",
"Later" : "Neskôr",
"Show archived cards" : "Zobraziť archivované karty",
"Hide archived cards" : "Skryť archivované karty",
"Board details" : "Podrobnosti tabule",
"Archive" : "Archivovať",
"Unarchive" : "Vybrať z archívu",
"Delete" : "Zmazať",
"Enter a card title" : "Zmeniť názov karty",
"Sharing" : "Sprístupnenie",
"Labels" : "Značky",
"Select users or groups to share with" : "Vyberte používateľov albo skupiny pre sprístupnenie",
"No matching user or group found." : "Neboli nájdení vyhovujúci používatelia alebo skupiny.",
"Share" : "Sprístupniť",
"Edit" : "Upraviť",
"Manage" : "Spravovať",
"Discard share" : "Zrušiť sprístupnenie",
"Create a new label" : "Vytvoriť novú značku",
"Board title" : "Názov tabule",
"Members" : "Členovia",
"Create new board" : "Vytvoriť novú tabuľu",
"New board title" : "Názov novej tabule",
"Modified:" : "Upravené:",
"Created:" : "Vytvorené:",
"by" : "-",
"Saved" : "Uložené",
"Add a card description ..." : "Pridať popis karty ...",
"Attachments" : "Prílohy",
"Comments" : "Komentáre",
"History" : "História",
"All Boards" : "Všetky Tabule",
"Shared with you" : "Sprístupnené vám",
"edit" : "upraviť",
"delete" : "zmazať",
"remove share" : "zrušiť sprístupnenie",
"Create a new board" : "Vytvoriť novú tabuľu"
},
"nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;");

42
l10n/sk.json Normal file
View File

@@ -0,0 +1,42 @@
{ "translations": {
"Deck" : "Tabuľa",
"Finished" : "Ukončené",
"To review" : "Na posúdenie",
"Action needed" : "Potrebná akcia",
"Later" : "Neskôr",
"Show archived cards" : "Zobraziť archivované karty",
"Hide archived cards" : "Skryť archivované karty",
"Board details" : "Podrobnosti tabule",
"Archive" : "Archivovať",
"Unarchive" : "Vybrať z archívu",
"Delete" : "Zmazať",
"Enter a card title" : "Zmeniť názov karty",
"Sharing" : "Sprístupnenie",
"Labels" : "Značky",
"Select users or groups to share with" : "Vyberte používateľov albo skupiny pre sprístupnenie",
"No matching user or group found." : "Neboli nájdení vyhovujúci používatelia alebo skupiny.",
"Share" : "Sprístupniť",
"Edit" : "Upraviť",
"Manage" : "Spravovať",
"Discard share" : "Zrušiť sprístupnenie",
"Create a new label" : "Vytvoriť novú značku",
"Board title" : "Názov tabule",
"Members" : "Členovia",
"Create new board" : "Vytvoriť novú tabuľu",
"New board title" : "Názov novej tabule",
"Modified:" : "Upravené:",
"Created:" : "Vytvorené:",
"by" : "-",
"Saved" : "Uložené",
"Add a card description ..." : "Pridať popis karty ...",
"Attachments" : "Prílohy",
"Comments" : "Komentáre",
"History" : "História",
"All Boards" : "Všetky Tabule",
"Shared with you" : "Sprístupnené vám",
"edit" : "upraviť",
"delete" : "zmazať",
"remove share" : "zrušiť sprístupnenie",
"Create a new board" : "Vytvoriť novú tabuľu"
},"pluralForm" :"nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"
}

29
l10n/sv.js Normal file
View File

@@ -0,0 +1,29 @@
OC.L10N.register(
"deck",
{
"Finished" : "Färdig",
"Action needed" : "Åtgärd behövs",
"Later" : "Senare",
"Archive" : "Arkivera",
"Unarchive" : "Ta bort ur arkivet",
"Delete" : "Radera",
"Sharing" : "Delning",
"Select users or groups to share with" : "Välj användare och grupper att dela med",
"No matching user or group found." : "Ingen matchande användare eller grupp hittades.",
"Share" : "Dela",
"Edit" : "Redigera",
"Manage" : "Hantera",
"Members" : "Medlemmar",
"Modified:" : "Ändrad:",
"Created:" : "Skapad:",
"by" : "av",
"Saved" : "Sparad",
"Attachments" : "Bifogade filer",
"Comments" : "Kommentarer",
"History" : "Historik",
"Shared with you" : "Delade med dig",
"edit" : "redigera",
"delete" : "radera",
"remove share" : "ta bort delning"
},
"nplurals=2; plural=(n != 1);");

27
l10n/sv.json Normal file
View File

@@ -0,0 +1,27 @@
{ "translations": {
"Finished" : "Färdig",
"Action needed" : "Åtgärd behövs",
"Later" : "Senare",
"Archive" : "Arkivera",
"Unarchive" : "Ta bort ur arkivet",
"Delete" : "Radera",
"Sharing" : "Delning",
"Select users or groups to share with" : "Välj användare och grupper att dela med",
"No matching user or group found." : "Ingen matchande användare eller grupp hittades.",
"Share" : "Dela",
"Edit" : "Redigera",
"Manage" : "Hantera",
"Members" : "Medlemmar",
"Modified:" : "Ändrad:",
"Created:" : "Skapad:",
"by" : "av",
"Saved" : "Sparad",
"Attachments" : "Bifogade filer",
"Comments" : "Kommentarer",
"History" : "Historik",
"Shared with you" : "Delade med dig",
"edit" : "redigera",
"delete" : "radera",
"remove share" : "ta bort delning"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}

44
l10n/tr.js Normal file
View File

@@ -0,0 +1,44 @@
OC.L10N.register(
"deck",
{
"Deck" : "Tahta",
"Finished" : "Tamamlandı",
"To review" : "İncelenecek",
"Action needed" : "İşlem yapılması gerekiyor",
"Later" : "Sonra",
"Show archived cards" : "Arşivlenmiş kartları görüntüle",
"Hide archived cards" : "Arşivlenmiş kartları gizle",
"Board details" : "Pano ayrıntıları",
"Archive" : "Arşivle",
"Unarchive" : "Arşivden Çıkar",
"Delete" : "Sil",
"Enter a card title" : "Bir kart başlığı yazın",
"Sharing" : "Paylaşım",
"Labels" : "Etiketler",
"Select users or groups to share with" : "Paylaşılacak kullanıcı ya da grupları seçin",
"No matching user or group found." : "Eşleşen bir kullanıcı ya da grup bulunamadı.",
"Share" : "Paylaş",
"Edit" : "Düzenle",
"Manage" : "Yönetim",
"Discard share" : "Paylaşımı kaldır",
"Create a new label" : "Yeni bir etiket ekle",
"Board title" : "Pano başlığı",
"Members" : "Üyeler",
"Create new board" : "Yeni pano ekle",
"New board title" : "Yeni pano başlığı",
"Modified:" : "Değiştirilme:",
"Created:" : "Oluşturulma:",
"by" : "Kişi:",
"Saved" : "Kaydedildi",
"Add a card description ..." : "Bir kart açıklaması ekle...",
"Attachments" : "Ek dosyalar",
"Comments" : "Yorumlar",
"History" : "Geçmiş",
"All Boards" : "Tüm Panolar",
"Shared with you" : "Sizinle paylaşılan",
"edit" : "düzenle",
"delete" : "sil",
"remove share" : "paylaşımı kaldır",
"Create a new board" : "Yeni bir pano ekle"
},
"nplurals=2; plural=(n > 1);");

42
l10n/tr.json Normal file
View File

@@ -0,0 +1,42 @@
{ "translations": {
"Deck" : "Tahta",
"Finished" : "Tamamlandı",
"To review" : "İncelenecek",
"Action needed" : "İşlem yapılması gerekiyor",
"Later" : "Sonra",
"Show archived cards" : "Arşivlenmiş kartları görüntüle",
"Hide archived cards" : "Arşivlenmiş kartları gizle",
"Board details" : "Pano ayrıntıları",
"Archive" : "Arşivle",
"Unarchive" : "Arşivden Çıkar",
"Delete" : "Sil",
"Enter a card title" : "Bir kart başlığı yazın",
"Sharing" : "Paylaşım",
"Labels" : "Etiketler",
"Select users or groups to share with" : "Paylaşılacak kullanıcı ya da grupları seçin",
"No matching user or group found." : "Eşleşen bir kullanıcı ya da grup bulunamadı.",
"Share" : "Paylaş",
"Edit" : "Düzenle",
"Manage" : "Yönetim",
"Discard share" : "Paylaşımı kaldır",
"Create a new label" : "Yeni bir etiket ekle",
"Board title" : "Pano başlığı",
"Members" : "Üyeler",
"Create new board" : "Yeni pano ekle",
"New board title" : "Yeni pano başlığı",
"Modified:" : "Değiştirilme:",
"Created:" : "Oluşturulma:",
"by" : "Kişi:",
"Saved" : "Kaydedildi",
"Add a card description ..." : "Bir kart açıklaması ekle...",
"Attachments" : "Ek dosyalar",
"Comments" : "Yorumlar",
"History" : "Geçmiş",
"All Boards" : "Tüm Panolar",
"Shared with you" : "Sizinle paylaşılan",
"edit" : "düzenle",
"delete" : "sil",
"remove share" : "paylaşımı kaldır",
"Create a new board" : "Yeni bir pano ekle"
},"pluralForm" :"nplurals=2; plural=(n > 1);"
}

44
l10n/zh_CN.js Normal file
View File

@@ -0,0 +1,44 @@
OC.L10N.register(
"deck",
{
"Deck" : "面板",
"Finished" : "完成",
"To review" : "回顾",
"Action needed" : "需要操作",
"Later" : "稍后",
"Show archived cards" : "显示已存档的卡片",
"Hide archived cards" : "隐藏已存档的卡片",
"Board details" : "面板详情",
"Archive" : "归档",
"Unarchive" : "取消归档",
"Delete" : "删除",
"Enter a card title" : "输入卡片标题",
"Sharing" : "分享",
"Labels" : "标签",
"Select users or groups to share with" : "选择要共享的用户或组",
"No matching user or group found." : "未找到匹配的用户或组。",
"Share" : "分享",
"Edit" : "编辑",
"Manage" : "管理",
"Discard share" : "取消分享",
"Create a new label" : "创建新标签",
"Board title" : "面板标题",
"Members" : "会员",
"Create new board" : "创建新面板",
"New board title" : "新面板标题",
"Modified:" : "修改于:",
"Created:" : "创建于:",
"by" : "by",
"Saved" : "已保存",
"Add a card description ..." : "添加卡片说明...",
"Attachments" : "附件",
"Comments" : "评论",
"History" : "历史",
"All Boards" : "全部面板",
"Shared with you" : "共享给您的",
"edit" : "编辑",
"delete" : "删除",
"remove share" : "移除共享",
"Create a new board" : "创建一个新面板"
},
"nplurals=1; plural=0;");

42
l10n/zh_CN.json Normal file
View File

@@ -0,0 +1,42 @@
{ "translations": {
"Deck" : "面板",
"Finished" : "完成",
"To review" : "回顾",
"Action needed" : "需要操作",
"Later" : "稍后",
"Show archived cards" : "显示已存档的卡片",
"Hide archived cards" : "隐藏已存档的卡片",
"Board details" : "面板详情",
"Archive" : "归档",
"Unarchive" : "取消归档",
"Delete" : "删除",
"Enter a card title" : "输入卡片标题",
"Sharing" : "分享",
"Labels" : "标签",
"Select users or groups to share with" : "选择要共享的用户或组",
"No matching user or group found." : "未找到匹配的用户或组。",
"Share" : "分享",
"Edit" : "编辑",
"Manage" : "管理",
"Discard share" : "取消分享",
"Create a new label" : "创建新标签",
"Board title" : "面板标题",
"Members" : "会员",
"Create new board" : "创建新面板",
"New board title" : "新面板标题",
"Modified:" : "修改于:",
"Created:" : "创建于:",
"by" : "by",
"Saved" : "已保存",
"Add a card description ..." : "添加卡片说明...",
"Attachments" : "附件",
"Comments" : "评论",
"History" : "历史",
"All Boards" : "全部面板",
"Shared with you" : "共享给您的",
"edit" : "编辑",
"delete" : "删除",
"remove share" : "移除共享",
"Create a new board" : "创建一个新面板"
},"pluralForm" :"nplurals=1; plural=0;"
}

View File

@@ -23,9 +23,14 @@
namespace OCA\Deck\AppInfo;
use OCA\Deck\Db\Acl;
use OCA\Deck\Db\AclMapper;
use OCP\AppFramework\App;
use OCA\Deck\Middleware\SharingMiddleware;
use OCP\IGroup;
use OCP\IGroupManager;
use OCP\IUser;
use OCP\IUserManager;
class Application extends App {
@@ -42,15 +47,36 @@ class Application extends App {
$container->registerService('SharingMiddleware', function($container) use ($server) {
return new SharingMiddleware(
$container,
$server->getRequest(),
$server->getUserSession(),
$container->query('ControllerMethodReflector'),
$container->query('OCA\Deck\Service\PermissionService')
$server->getLogger(),
$server->getConfig()
);
});
$container->registerMiddleware('SharingMiddleware');
// Delete user/group acl entries when they get deleted
/** @var IUserManager $userManager */
$userManager = $server->getUserManager();
$userManager->listen('\OC\User', 'postDelete', function(IUser $user) use ($container) {
/** @var AclMapper $aclMapper */
$aclMapper = $container->query(AclMapper::class);
$acls = $aclMapper->findByParticipant(Acl::PERMISSION_TYPE_USER, $user->getUID());
foreach ($acls as $acl) {
$aclMapper->delete($acl);
}
});
/** @var IUserManager $userManager */
$groupManager = $server->getGroupManager();
$groupManager->listen('\OC\Group', 'postDelete', function(IGroup $group) use ($container) {
/** @var AclMapper $aclMapper */
$aclMapper = $container->query(AclMapper::class);
$aclMapper->findByParticipant(Acl::PERMISSION_TYPE_GROUP, $group->getGID());
$acls = $aclMapper->findByParticipant(Acl::PERMISSION_TYPE_GROUP, $group->getGID());
foreach ($acls as $acl) {
$aclMapper->delete($acl);
}
});
}
public function registerNavigationEntry() {

View File

@@ -130,13 +130,13 @@ class BoardController extends Controller {
* @param $boardId
* @param $type
* @param $participant
* @param $edit
* @param $share
* @param $manage
* @param $permissionEdit
* @param $permissionShare
* @param $permissionManage
* @return \OCP\AppFramework\Db\Entity
*/
public function addAcl($boardId, $type, $participant, $edit, $share, $manage) {
return $this->boardService->addAcl($boardId, $type, $participant, $edit, $share, $manage);
public function addAcl($boardId, $type, $participant, $permissionEdit, $permissionShare, $permissionManage) {
return $this->boardService->addAcl($boardId, $type, $participant, $permissionEdit, $permissionShare, $permissionManage);
}
/**

View File

@@ -1,85 +0,0 @@
<?php
/**
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @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/>.
*
*/
namespace OCA\Deck\Controller;
use OCA\Deck\Db\Acl;
use OCA\Deck\Service\BoardService;
use OCP\IGroupManager;
use OCP\IRequest;
use OCP\AppFramework\Controller;
use OCP\IUserManager;
class ShareController extends Controller {
private $userManager;
private $groupManager;
private $boardService;
private $userId;
public function __construct($appName, IRequest $request, IUserManager $userManager, IGroupManager $groupManager, BoardService $boardService, $userId) {
parent::__construct($appName, $request);
$this->userManager = $userManager;
$this->groupManager = $groupManager;
$this->userId = $userId;
$this->boardService = $boardService;
}
/**
* @NoAdminRequired
* @param $search
* @return array
*/
public function searchUser($search) {
$limit = 3;
$offset = null;
$result = [];
foreach ($this->groupManager->search($search, $limit, $offset) as $idx => $group) {
$acl = new Acl();
$acl->setType('group');
$acl->setParticipant($group->getGID());
$acl->setPermissionEdit(true);
$acl->setPermissionShare(true);
$acl->setPermissionManage(true);
$result[] = $acl;
}
$limit = 10;
foreach ($this->userManager->searchDisplayName($search, $limit, $offset) as $idx => $user) {
if ($user->getUID() === $this->userId) {
continue;
}
$acl = new Acl();
$acl->setType('user');
$acl->setParticipant($user->getUID());
$acl->setPermissionEdit(true);
$acl->setPermissionShare(true);
$acl->setPermissionManage(true);
$result[] = $acl;
}
return $result;
}
}

View File

@@ -48,12 +48,10 @@ class Acl extends RelationalEntity implements \JsonSerializable {
$this->addType('permissionEdit', 'boolean');
$this->addType('permissionShare', 'boolean');
$this->addType('permissionManage', 'boolean');
$this->addType('owner', 'boolean');
$this->addType('type', 'integer');
$this->addType('owner', 'boolean');
$this->addRelation('owner');
$this->setPermissionEdit(false);
$this->setPermissionShare(false);
$this->setPermissionManage(false);
$this->addResolvable('participant');
}
public function getPermission($permission) {
@@ -71,23 +69,12 @@ class Acl extends RelationalEntity implements \JsonSerializable {
}
public function jsonSerialize() {
return [
'id' => $this->id,
'participant' => $this->participant,
'type' => $this->getType(),
'boardId' => $this->boardId,
'permissionEdit' => $this->getPermissionEdit(),
'permissionShare' => $this->getPermissionShare(),
'permissionManage' => $this->getPermissionManage(),
'owner' => $this->getOwner()
];
$json = parent::jsonSerialize();
$json['type'] = $this->getTypeString();
return $json;
}
/*
* FIXME: migrate other code to const PERMISSION_TYPE_ instead of strings
* iirc js uses those strings as well
*/
public function getType() {
public function getTypeString() {
if ($this->type === Acl::PERMISSION_TYPE_GROUP) {
return 'group';
}
@@ -95,7 +82,8 @@ class Acl extends RelationalEntity implements \JsonSerializable {
}
public function setType($type) {
if ($type === 'group') {
// FIXME: Remove when all javascript uses numeric types
if ($type === 'group' || $type === '1') {
$typeInt = Acl::PERMISSION_TYPE_GROUP;
} else {
$typeInt = Acl::PERMISSION_TYPE_USER;
@@ -103,4 +91,5 @@ class Acl extends RelationalEntity implements \JsonSerializable {
$this->markFieldUpdated('type');
$this->type = $typeInt;
}
}

View File

@@ -25,7 +25,6 @@ namespace OCA\Deck\Db;
use OCP\IDBConnection;
class AclMapper extends DeckMapper implements IPermissionMapper {
public function __construct(IDBConnection $db) {
@@ -49,4 +48,9 @@ class AclMapper extends DeckMapper implements IPermissionMapper {
return $entity->getBoardId();
}
public function findByParticipant($type, $participant) {
$sql = 'SELECT * from *PREFIX*deck_board_acl WHERE type = ? AND participant = ?';
return $this->findEntities($sql, [$type, $participant]);
}
}

View File

@@ -32,8 +32,8 @@ class Board extends RelationalEntity implements JsonSerializable {
protected $owner;
protected $color;
protected $archived = false;
protected $labels;
protected $acl;
protected $labels = [];
protected $acl = [];
protected $shared;
public function __construct() {
@@ -43,22 +43,16 @@ class Board extends RelationalEntity implements JsonSerializable {
$this->addRelation('labels');
$this->addRelation('acl');
$this->addRelation('shared');
$this->addResolvable('owner');
$this->shared = -1;
}
public function jsonSerialize() {
$result = [
'id' => $this->id,
'title' => $this->title,
'owner' => $this->owner,
'color' => $this->color,
'labels' => $this->labels,
'acl' => $this->acl,
];
if ($this->shared !== -1) {
$result['shared'] = $this->shared;
$json = parent::jsonSerialize();
if ($this->shared === -1) {
unset($json['shared']);
}
return $result;
return $json;
}
public function setLabels($labels) {

View File

@@ -24,19 +24,31 @@
namespace OCA\Deck\Db;
use OCP\IDBConnection;
use OCP\IUserManager;
use OCP\IGroupManager;
class BoardMapper extends DeckMapper implements IPermissionMapper {
private $labelMapper;
private $aclMapper;
private $stackMapper;
private $userManager;
private $groupManager;
public function __construct(IDBConnection $db, LabelMapper $labelMapper, AclMapper $aclMapper, StackMapper $stackMapper) {
public function __construct(
IDBConnection $db,
LabelMapper $labelMapper,
AclMapper $aclMapper,
StackMapper $stackMapper,
IUserManager $userManager,
IGroupManager $groupManager
) {
parent::__construct($db, 'deck_boards', '\OCA\Deck\Db\Board');
$this->labelMapper = $labelMapper;
$this->aclMapper = $aclMapper;
$this->stackMapper = $stackMapper;
$this->userManager = $userManager;
$this->groupManager = $groupManager;
}
@@ -75,10 +87,10 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
* @return array
*/
public function findAllByUser($userId, $limit = null, $offset = null) {
$sql = 'SELECT id, title, owner, color, archived, 0 as shared FROM oc_deck_boards WHERE owner = ? UNION ' .
'SELECT boards.id, title, owner, color, archived, 1 as shared FROM oc_deck_boards as boards ' .
'JOIN oc_deck_board_acl as acl ON boards.id=acl.board_id WHERE acl.participant=? AND acl.type=\'user\' AND boards.owner != ?';
$entries = $this->findEntities($sql, [$userId, $userId, $userId], $limit, $offset);
$sql = 'SELECT id, title, owner, color, archived, 0 as shared FROM `*PREFIX*deck_boards` WHERE owner = ? UNION ' .
'SELECT boards.id, title, owner, color, archived, 1 as shared 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 != ?';
$entries = $this->findEntities($sql, [$userId, $userId, Acl::PERMISSION_TYPE_USER, $userId], $limit, $offset);
/* @var Board $entry */
foreach ($entries as $entry) {
$acl = $this->aclMapper->findAll($entry->id);
@@ -100,8 +112,8 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
if (count($groups) <= 0) {
return [];
}
$sql = 'SELECT boards.id, title, owner, color, archived, 2 as shared FROM oc_deck_boards as boards ' .
'INNER JOIN oc_deck_board_acl as acl ON boards.id=acl.board_id WHERE owner != ? AND type=\'group\' AND (';
$sql = 'SELECT boards.id, title, owner, color, archived, 2 as shared 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; $i < count($groups); $i++) {
$sql .= 'acl.participant = ? ';
if (count($groups) > 1 && $i < count($groups) - 1) {
@@ -109,7 +121,7 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
}
}
$sql .= ');';
$entries = $this->findEntities($sql, array_merge([$userId], $groups), $limit, $offset);
$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);
@@ -118,6 +130,11 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
return $entries;
}
public function findAll() {
$sql = 'SELECT id from *PREFIX*deck_boards;';
return $this->findEntities($sql, []);
}
public function delete(/** @noinspection PhpUnnecessaryFullyQualifiedNameInspection */
\OCP\AppFramework\Db\Entity $entity) {
// delete acl
@@ -149,5 +166,45 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
return $id;
}
public function mapAcl(Acl &$acl) {
$userManager = $this->userManager;
$groupManager = $this->groupManager;
$acl->resolveRelation('participant', function($participant) use (&$acl, &$userManager, &$groupManager) {
if($acl->getType() === Acl::PERMISSION_TYPE_USER) {
$user = $userManager->get($participant);
if($user !== null) {
return new User($user);
} else {
\OC::$server->getLogger()->debug('User ' . $acl->getId() . ' not found when mapping acl ' . $acl->getParticipant());
return null;
}
}
if($acl->getType() === Acl::PERMISSION_TYPE_GROUP) {
$group = $groupManager->get($participant);
if($group !== null) {
return new Group($group);
} else {
\OC::$server->getLogger()->debug('Group ' . $acl->getId() . ' not found when mapping acl ' . $acl->getParticipant());
return null;
}
}
throw new \Exception('Unknown permission type for mapping Acl');
});
}
/**
* @param Board $board
*/
public function mapOwner(Board &$board) {
$userManager = $this->userManager;
$board->resolveRelation('owner', function($owner) use (&$userManager) {
$user = $userManager->get($owner);
if($user !== null) {
return new User($user);
}
return null;
});
}
}

View File

@@ -48,21 +48,7 @@ class Card extends RelationalEntity implements JsonSerializable {
$this->addType('createdAt', 'integer');
$this->addType('archived', 'boolean');
$this->addRelation('labels');
$this->addResolvable('owner');
}
public function jsonSerialize() {
return [
'id' => $this->id,
'title' => $this->title,
'description' => $this->description,
'type' => $this->type,
'lastModified' => $this->lastModified,
'createdAt' => $this->createdAt,
'owner' => $this->owner,
'order' => $this->order,
'stackId' => $this->stackId,
'labels' => $this->labels,
'archived' => $this->archived,
];
}
}

View File

@@ -25,15 +25,18 @@ namespace OCA\Deck\Db;
use OCP\AppFramework\Db\Entity;
use OCP\IDBConnection;
use OCP\IUserManager;
class CardMapper extends DeckMapper implements IPermissionMapper {
private $labelMapper;
private $userManager;
public function __construct(IDBConnection $db, LabelMapper $labelMapper) {
public function __construct(IDBConnection $db, LabelMapper $labelMapper, IUserManager $userManager) {
parent::__construct($db, 'deck_cards', '\OCA\Deck\Db\Card');
$this->labelMapper = $labelMapper;
$this->userManager = $userManager;
}
public function insert(Entity $entity) {
@@ -57,6 +60,7 @@ class CardMapper extends DeckMapper implements IPermissionMapper {
$card = $this->findEntity($sql, [$id]);
$labels = $this->labelMapper->findAssignedLabelsForCard($card->id);
$card->setLabels($labels);
$this->mapOwner($card);
return $card;
}
@@ -125,5 +129,16 @@ class CardMapper extends DeckMapper implements IPermissionMapper {
return $row['id'];
}
public function mapOwner(Card &$card) {
$userManager = $this->userManager;
$card->resolveRelation('owner', function($owner) use (&$userManager) {
$user = $userManager->get($owner);
if($user !== null) {
return new User($user);
}
return null;
});
}
}

View File

@@ -36,24 +36,7 @@ abstract class DeckMapper extends Mapper {
return $this->findEntity($sql, [$id]);
}
/**
* Add relational data to an Entity by calling the related Mapper
* @param $entities
* @param $entityType
* @param $property
* addRelation($cards, $labels, function($one, $many) {
* if($one->id == $many->cardId)
* }
*/
public function addRelation($entities, $entityType, $property) {
}
protected function execute($sql, array $params = [], $limit = null, $offset = null) {
// FIXME: remove on release
/** @noinspection PhpUnnecessaryFullyQualifiedNameInspection */
/** @noinspection PhpUnnecessaryFullyQualifiedNameInspection */
\OCP\Util::writeLog('deck', "DeckMapper SQL: " . $sql . " with " . implode("|", $params), \OCP\Util::DEBUG);
return parent::execute($sql, $params, $limit, $offset);
}

View File

@@ -1,43 +1,41 @@
/*
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
<?php
/**
* @copyright Copyright (c) 2017 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @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/>.
*
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
(function ($, OC) {
namespace OCA\Deck\Db;
$(document).ready(function () {
$('#hello').click(function () {
alert('Hello from your script file');
});
use OCP\IGroup;
$('#echo').click(function () {
var url = OC.generateUrl('/apps/deck/echo');
var data = {
echo: $('#echo-content').val()
};
class Group extends RelationalObject {
$.post(url, data).success(function (response) {
$('#echo-result').text(response.echo);
});
public function __construct(IGroup $group) {
$primaryKey = $group->getGID();
parent::__construct($primaryKey, $group);
}
});
});
})(jQuery, OC);
public function getObjectSerialization() {
return [
'uid' => $this->object->getGID(),
'displayname' => $this->object->getGID()
];
}
}

View File

@@ -33,16 +33,8 @@ class Label extends RelationalEntity implements JsonSerializable {
protected $color;
protected $boardId;
protected $cardId;
public function __construct() {
$this->addType('id', 'integer');
}
public function jsonSerialize() {
return [
'id' => $this->id,
'title' => $this->title,
'boardId' => $this->boardId,
'cardId' => $this->cardId,
'color' => $this->color,
];
}
}

View File

@@ -49,8 +49,8 @@ class LabelMapper extends DeckMapper implements IPermissionMapper {
return $this->findEntities($sql, [$cardId], $limit, $offset);
}
public function findAssignedLabelsForBoard($boardId, $limit = null, $offset = null) {
$sql = "SELECT c.id as card_id, l.id as id, l.title as title, l.color as color FROM oc_deck_cards as c " .
" INNER JOIN oc_deck_assigned_labels as al ON al.card_id = c.id INNER JOIN oc_deck_labels as l ON al.label_id = l.id WHERE board_id=? ORDER BY l.id";
$sql = "SELECT c.id as card_id, l.id as id, l.title as title, l.color as color FROM `*PREFIX*deck_cards` as c " .
" INNER JOIN `*PREFIX*deck_assigned_labels` as al ON al.card_id = c.id INNER JOIN `*PREFIX*deck_labels` as l ON al.label_id = l.id WHERE board_id=? ORDER BY l.id";
$entities = $this->findEntities($sql, [$boardId], $limit, $offset);
return $entities;
}

View File

@@ -1,6 +1,6 @@
<?php
/**
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
* @copyright Copyright (c) 2017 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
@@ -21,29 +21,33 @@
*
*/
/**
* Created by PhpStorm.
* User: jus
* Date: 22.06.16
* Time: 13:32
*/
namespace OCA\Deck\Db;
use OCP\AppFramework\Db\Entity;
class RelationalEntity extends \OCP\AppFramework\Db\Entity {
class RelationalEntity extends Entity implements \JsonSerializable {
private $_relations = array();
private $_resolvedProperties = [];
/**
* Mark a property as relation so it will not get updated using Mapper::update
* @param string $property Name of the property
* @param $property string Name of the property
*/
public function addRelation($property) {
if (!in_array($property, $this->_relations)) {
$this->_relations[] = $property;
}
}
/**
* Mark a property as resolvable via resolveRelation()
* @param $property string Name of the property
*/
public function addResolvable($property) {
$this->_resolvedProperties[$property] = null;
}
/**
* Mark am attribute as updated
* overwritten from \OCP\AppFramework\Db\Entity to avoid writing relational attributes
@@ -56,4 +60,82 @@ class RelationalEntity extends \OCP\AppFramework\Db\Entity {
}
}
/**
* @return array serialized data
*/
public function jsonSerialize() {
$properties = get_object_vars($this);
$reflection = new \ReflectionClass($this);
$json = [];
foreach ($properties as $property => $value) {
if (substr($property, 0, 1) !== '_' && $reflection->hasProperty($property)) {
$propertyReflection = $reflection->getProperty($property);
if (!$propertyReflection->isPrivate()) {
$json[$property] = $this->getter($property);
}
}
}
foreach ($this->_resolvedProperties as $property => $value) {
if($value !== null) {
$json[$property] = $value;
}
}
return $json;
}
/*
* Resolve relational data from external methods
*
* example usage:
*
* in Board::__construct()
* $this->addResolvable('owner')
*
* in BoardMapper
* $board->resolveRelation('owner', function($owner) use (&$userManager) {
* return new \OCA\Deck\Db\User($userManager->get($owner));
* });
*
* resolved values can be obtained by calling resolveProperty
* e.g. $board->resolveOwner()
*
* @param string $property name of the property
* @param callable $resolver anonymous function to resolve relational
* data defined by $property as unique identifier
* @throws \Exception
*/
public function resolveRelation($property, $resolver) {
$result = null;
if($property !== null && $this->$property !== null) {
$result = $resolver($this->$property);
}
if($result instanceof RelationalObject || $result === null) {
$this->_resolvedProperties[$property] = $result;
} else {
throw new \Exception('resolver must return an instance of RelationalObject');
}
}
public function __call($methodName, $args){
$attr = lcfirst( substr($methodName, 7) );
if(strpos($methodName, 'resolve') === 0 && array_key_exists($attr, $this->_resolvedProperties)) {
if($this->_resolvedProperties[$attr] !== null) {
return $this->_resolvedProperties[$attr];
} else {
return $this->getter($attr);
}
}
$attr = lcfirst( substr($methodName, 3) );
if(strpos($methodName, 'set') === 0 && array_key_exists($attr, $this->_resolvedProperties)) {
if(!is_scalar($args[0])) {
$args[0] = $args[0]['primaryKey'];
}
parent::setter($attr, $args);
return null;
}
return parent::__call($methodName, $args);
}
}

View File

@@ -0,0 +1,60 @@
<?php
/**
* @copyright Copyright (c) 2017 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @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/>.
*
*/
namespace OCA\Deck\Db;
class RelationalObject implements \JsonSerializable {
protected $primaryKey;
protected $object;
/**
* RelationalObject constructor.
*
* @param $primaryKey string
* @param $object
*/
public function __construct($primaryKey, $object) {
$this->primaryKey = $primaryKey;
$this->object = $object;
}
public function jsonSerialize() {
return array_merge(
['primaryKey' => $this->primaryKey],
$this->getObjectSerialization()
);
}
/**
* This method should be overwritten if object doesn't implement \JsonSerializable
*/
public function getObjectSerialization() {
if($this->object instanceof \JsonSerializable) {
$this->object->jsonSerialize();
} else {
throw new \Exception('jsonSerialize is not implemented on ' . get_class($this));
}
}
}

View File

@@ -45,20 +45,10 @@ class Stack extends RelationalEntity implements JsonSerializable {
}
public function jsonSerialize() {
if (!empty($this->cards)) {
return [
'id' => $this->id,
'title' => $this->title,
'order' => $this->order,
'boardId' => $this->boardId,
'cards' => $this->cards
];
$json = parent::jsonSerialize();
if (empty($this->cards)) {
unset($json['cards']);
}
return [
'id' => $this->id,
'title' => $this->title,
'order' => $this->order,
'boardId' => $this->boardId
];
return $json;
}
}

41
lib/Db/User.php Normal file
View File

@@ -0,0 +1,41 @@
<?php
/**
* @copyright Copyright (c) 2017 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @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/>.
*
*/
namespace OCA\Deck\Db;
use OCP\IUser;
class User extends RelationalObject {
public function __construct(IUser $user) {
$primaryKey = $user->getUID();
parent::__construct($primaryKey, $user);
}
public function getObjectSerialization() {
return [
'uid' => $this->object->getUID(),
'displayname' => $this->object->getDisplayName()
];
}
}

View File

@@ -23,18 +23,32 @@
namespace OCA\Deck\Middleware;
use OCA\Deck\StatusException;
use \OCP\AppFramework\Middleware;
use OCP\AppFramework\Middleware;
use OCP\AppFramework\Http\JSONResponse;
use OCP\ILogger;
use OCP\Util;
use OCP\IConfig;
class SharingMiddleware extends Middleware {
/** @var ILogger */
private $logger;
/** @var IConfig */
private $config;
/**
* SharingMiddleware constructor.
*
* @param ILogger $logger
* @param IConfig $config
*/
public function __construct(ILogger $logger, IConfig $config) {
$this->logger = $logger;
$this->config = $config;
}
/**
* Return JSON error response if the user has no sufficient permission
*
@@ -46,6 +60,9 @@ class SharingMiddleware extends Middleware {
*/
public function afterException($controller, $methodName, \Exception $exception) {
if ($exception instanceof StatusException) {
if($this->config->getSystemValue('loglevel', Util::WARN) === Util::DEBUG) {
$this->logger->logException($exception);
}
return new JSONResponse([
"status" => $exception->getStatus(),
"message" => $exception->getMessage()

View File

@@ -0,0 +1,83 @@
<?php
/**
* @copyright Copyright (c) 2017 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @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/>.
*
*/
namespace OCA\Deck\Migration;
use OCA\Deck\Db\Acl;
use OCA\Deck\Db\AclMapper;
use OCA\Deck\Db\Board;
use OCA\Deck\Db\BoardMapper;
use OCP\IGroupManager;
use OCP\IUserManager;
use OCP\Migration\IRepairStep;
use OCP\Migration\IOutput;
class UnknownUsers implements IRepairStep {
private $userManager;
private $groupManager;
private $aclMapper;
private $boardMapper;
public function __construct(IUserManager $userManager, IGroupManager $groupManager, AclMapper $aclMapper, BoardMapper $boardMapper) {
$this->userManager = $userManager;
$this->groupManager = $groupManager;
$this->aclMapper = $aclMapper;
$this->boardMapper = $boardMapper;
}
/*
* @inheritdoc
*/
public function getName() {
return 'Delete orphaned ACL rules';
}
/**
* @inheritdoc
*/
public function run(IOutput $output) {
$boards = $this->boardMapper->findAll();
/** @var Board $board */
foreach ($boards as $board) {
$acls = $this->aclMapper->findAll($board->getId());
/** @var Acl $acl */
foreach ($acls as $acl) {
if($acl->getType() === Acl::PERMISSION_TYPE_USER) {
$user = $this->userManager->get($acl->getParticipant());
if($user === null) {
$this->aclMapper->delete($acl);
}
}
if($acl->getType() === Acl::PERMISSION_TYPE_GROUP) {
$group = $this->groupManager->get($acl->getParticipant());
if($group === null) {
$this->aclMapper->delete($acl);
}
}
}
}
}
}

View File

@@ -26,10 +26,7 @@ namespace OCA\Deck\Service;
use OCA\Deck\Db\Acl;
use OCA\Deck\Db\AclMapper;
use OCA\Deck\Db\Label;
use OCP\IL10N;
use OCA\Deck\Db\Board;
use OCA\Deck\Db\BoardMapper;
use OCA\Deck\Db\LabelMapper;
@@ -55,14 +52,36 @@ class BoardService {
$userBoards = $this->boardMapper->findAllByUser($userInfo['user']);
$groupBoards = $this->boardMapper->findAllByGroups($userInfo['user'], $userInfo['groups']);
$complete = array_merge($userBoards, $groupBoards);
return array_map("unserialize", array_unique(array_map("serialize", $complete)));
$result = [];
foreach($complete as &$item) {
if(!array_key_exists($item->getId(), $result)) {
$this->boardMapper->mapOwner($item);
if($item->getAcl() !== null) {
foreach ($item->getAcl() as &$acl) {
$this->boardMapper->mapAcl($acl);
}
}
$result[$item->getId()] = $item;
}
}
return array_values($result);
}
public function find($boardId) {
$this->permissionService->checkPermission($this->boardMapper, $boardId, Acl::PERMISSION_READ);
return $this->boardMapper->find($boardId, true, true);
/** @var Board $board */
$board = $this->boardMapper->find($boardId, true, true);
$this->boardMapper->mapOwner($board);
foreach ($board->getAcl() as &$acl) {
if($acl !== null) {
$this->boardMapper->mapAcl($acl);
}
}
return $board;
}
public function create($title, $userId, $color) {
$board = new Board();
$board->setTitle($title);
@@ -86,6 +105,7 @@ class BoardService {
$labels[] = $this->labelMapper->insert($label);
}
$new_board->setLabels($labels);
$this->boardMapper->mapOwner($new_board);
return $new_board;
}
@@ -100,6 +120,7 @@ class BoardService {
$board = $this->find($id);
$board->setTitle($title);
$board->setColor($color);
$this->boardMapper->mapOwner($board);
return $this->boardMapper->update($board);
}
@@ -113,21 +134,27 @@ class BoardService {
$acl->setPermissionEdit($edit);
$acl->setPermissionShare($share);
$acl->setPermissionManage($manage);
return $this->aclMapper->insert($acl);
$newAcl = $this->aclMapper->insert($acl);
$this->boardMapper->mapAcl($newAcl);
return $newAcl;
}
public function updateAcl($id, $edit, $share, $manage) {
$this->permissionService->checkPermission($this->boardMapper, $id, Acl::PERMISSION_SHARE);
$this->permissionService->checkPermission($this->aclMapper, $id, Acl::PERMISSION_SHARE);
/** @var Acl $acl */
$acl = $this->aclMapper->find($id);
$acl->setPermissionEdit($edit);
$acl->setPermissionShare($share);
$acl->setPermissionManage($manage);
$this->boardMapper->mapAcl($acl);
return $this->aclMapper->update($acl);
}
public function deleteAcl($id) {
$this->permissionService->checkPermission($this->boardMapper, $id, Acl::PERMISSION_SHARE);
$this->permissionService->checkPermission($this->aclMapper, $id, Acl::PERMISSION_SHARE);
/** @var Acl $acl */
$acl = $this->aclMapper->find($id);
$this->boardMapper->mapAcl($acl);
return $this->aclMapper->delete($acl);
}

View File

@@ -42,7 +42,8 @@ class CardService {
public function find($cardId) {
$this->permissionService->checkPermission($this->cardMapper, $cardId, Acl::PERMISSION_READ);
return $this->cardMapper->find($cardId);
$card = $this->cardMapper->find($cardId);
return $card;
}
/**

View File

@@ -127,14 +127,14 @@ class PermissionService {
public function userCan(array $acls, $permission) {
// check for users
foreach ($acls as $acl) {
if ($acl->getType() === "user" && $acl->getParticipant() === $this->userId) {
if ($acl->getType() === Acl::PERMISSION_TYPE_USER && $acl->getParticipant() === $this->userId) {
return $acl->getPermission($permission);
}
}
// check for groups
$hasGroupPermission = false;
foreach ($acls as $acl) {
if (!$hasGroupPermission && $acl->getType() === "group" && $this->groupManager->isInGroup($this->userId, $acl->getParticipant())) {
if (!$hasGroupPermission && $acl->getType() === Acl::PERMISSION_TYPE_GROUP && $this->groupManager->isInGroup($this->userId, $acl->getParticipant())) {
$hasGroupPermission = $acl->getPermission($permission);
}
}

View File

@@ -23,7 +23,9 @@
use OCP\Util;
Util::addStyle('deck', '../js/vendor/ng-sortable/dist/ng-sortable.min');
Util::addStyle('deck', 'style');
Util::addScript('deck', 'vendor/angular/angular.min');
Util::addScript('deck', 'vendor/angular-route/angular-route.min');
Util::addScript('deck', 'vendor/angular-sanitize/angular-sanitize.min');
@@ -34,8 +36,24 @@ Util::addScript('deck', 'vendor/angular-ui-select/dist/select.min');
Util::addScript('deck', 'vendor/markdown-it/dist/markdown-it.min');
Util::addScript('deck', 'vendor/angular-markdown-it/dist/ng-markdownit.min');
Util::addScript('deck', 'vendor/markdown-it-link-target/dist/markdown-it-link-target.min');
Util::addScript('deck', 'public/app');
if(!\OC::$server->getConfig()->getSystemValue('debug', false)) {
Util::addScript('deck', 'public/app');
} else {
// Load seperate JS files when debug mode is enabled
$js = [
'app' => ['App', 'Config', 'Run'],
'controller' => ['AppController', 'BoardController', 'CardController', 'ListController'],
'directive' => ['appnavigationentryutils', 'appPopoverMenuUtils', 'autofocusoninsert', 'avatar', 'elastic', 'search'],
'filters' => ['cardFilter', 'cardSearchFilter', 'iconWhiteFilter', 'lightenColorFilter', 'orderObjectBy', 'relativeDateFilter', 'textColorFilter'],
'service' => ['ApiService', 'BoardService', 'CardService', 'LabelService', 'StackService', 'StatusService'],
];
foreach($js as $folder=>$files) {
foreach ($files as $file) {
Util::addScript('deck', $folder.'/'.$file);
}
}
}
?>
<div id="app" class="app-deck" data-ng-app="Deck" ng-controller="AppController" ng-cloak>
@@ -44,12 +62,12 @@ Util::addScript('deck', 'public/app');
<?php print_unescaped($this->inc('part.navigation')); ?>
<?php /* print_unescaped($this->inc('part.settings')); */ ?>
</div>
<div id="app-content" ng-class="{ 'details-visible': sidebar.show }">
<div id="app-view" ui-view></div>
<div id="app-content" ng-class="{ 'details-visible': sidebar.show }" ui-view>
</div>
<route-loading-indicator></route-loading-indicator>
<script type="text/ng-template" id="/boardlist.mainView.html">
<?php print_unescaped($this->inc('part.boardlist')); ?>
</script>

View File

@@ -9,14 +9,26 @@
<h1>
{{ boardservice.getCurrent().title }}
</h1>
<div id="board-actions">
<div class="board-action-button" ng-if="filter!='archive'"><a ng-click="switchFilter('archive')" style="opacity:0.5;" title="<?php p($l->t('Show archived cards')); ?>"><i class="icon icon-archive{{ boardservice.getCurrent().color | iconWhiteFilter }}"></i></a></div>
<div class="board-action-button" ng-if="filter=='archive'"><a ng-click="switchFilter('')" title="<?php p($l->t('Hide archived cards')); ?>"><i class="icon icon-archive{{ boardservice.getCurrent().color | iconWhiteFilter }}"></i></a></div>
<div class="board-action-button"><a ui-sref="board.detail({ id: id })" title="<?php p($l->t('Board details')); ?>"><i class="icon icon-details{{ boardservice.getCurrent().color | iconWhiteFilter }}"></i></a>
<div id="board-actions">
<div class="board-action-button" ng-if="filter!='archive'"><a ng-click="switchFilter('archive')" style="opacity:0.5;" title="<?php p($l->t('Show archived cards')); ?>"><i class="icon icon-archive{{ boardservice.getCurrent().color | iconWhiteFilter }}"></i></a></div>
<div class="board-action-button" ng-if="filter=='archive'"><a ng-click="switchFilter('')" title="<?php p($l->t('Hide archived cards')); ?>"><i class="icon icon-archive{{ boardservice.getCurrent().color | iconWhiteFilter }}"></i></a></div>
<div class="board-action-button"><a ui-sref="board.detail({ id: id })" title="<?php p($l->t('Board details')); ?>"><i class="icon icon-details{{ boardservice.getCurrent().color | iconWhiteFilter }}"></i></a>
</div>
</div>
</div>
<div id="board" class="scroll-container">
<div id="stack-add" ng-if="boardservice.canEdit() && checkCanEdit()">
<form class="ng-pristine ng-valid" ng-submit="createStack()">
<input type="text" placeholder="Add a new stack"
ng-focus="status.addStack=true"
ng-blur="status.addStack=false"
ng-model="newStack.title" required
maxlength="100" />
<button class="icon icon-add" style="opacity: {{status.addStack ? 1: 0.5}};"
type="submit"></button>
</form>
</div>
</div>
<div id="board" class="scroll-container" ng-click="sidebar.show=false" ui-sref="board">
<search on-search="search" class="ng-hide"></search>
@@ -29,7 +41,7 @@
<input type="text" placeholder="Add a new stack"
ng-blur="s.status.editStack=false" ng-model="s.title"
ng-if="s.status.editStack" autofocus-on-insert
required/>
required maxlength="100"/>
</form>
<div class="stack-actions">
<button class="icon icon-confirm" ng-if="s.status.editStack"
@@ -45,14 +57,16 @@
<li class="card as-sortable-item"
ng-repeat="c in s.cards"
data-as-sortable-item
ng-click="$event.stopPropagation()"
ui-sref="board.card({boardId: id, cardId: c.id})"
ng-class="{'archived': c.archived, 'has-labels': c.labels.length>0 }">
<div data-as-sortable-item-handle>
<div class="card-upper">
<i class="icon icon-filetype-text icon-description-marker" ng-if="c.description" title="{{ c.description }}"></i>
<h3>{{ c.title }}</h3>
<ul class="labels">
<li ng-repeat="label in c.labels"
style="background-color: #{{ label.color }};">
style="background-color: #{{ label.color }};" title="{{ label.title }}">
<span>{{ label.title }}</span>
</li>
</ul>
@@ -103,6 +117,7 @@
ng-model="newCard.title"
ng-blur="status.addCard[s.id]=false"
style="color:{{ boardservice.getCurrent().color | textColorFilter }}; border-color:{{ boardservice.getCurrent().color | textColorFilter }};"
maxlength="100"
required placeholder="<?php p($l->t('Enter a card title')); ?>"/>
</h3>
</form>
@@ -111,21 +126,7 @@
</div>
</div>
</div>
<div class="stack" style="display: inline-block;" ng-if="boardservice.canEdit() && checkCanEdit()">
<form class="ng-pristine ng-valid" ng-submit="createStack()">
<h2>
<input type="text" placeholder="Add a new stack"
ng-focus="status.addStack=true"
ng-blur="status.addStack=false"
ng-model="newStack.title" required/>
<button class="icon icon-add" ng-show="status.addStack"
type="submit"></button>
</h2>
</form>
</div>
</div>
</div>
</div>
</div>

View File

@@ -17,34 +17,35 @@
<div class="tabsContainer">
<div id="commentsTabView" class="tab commentsTabView" ng-if="status.boardtab==0 || !status.boardtab">
<ui-select ng-if="boardservice.canShare()" ng-model="status.addSharee" theme="bootstrap" style="width:100%;" title="Choose a user to assign" placeholder="Assign users ..." on-select="aclAdd(status.addSharee)">
<ui-select-match placeholder="<?php p($l->t('Select users...')); ?>">
<span><i class="icon icon-{{$item.type}}"></i> {{ $item.participant }}</span>
<ui-select ng-if="boardservice.canShare()" ng-model="status.addSharee" theme="select2" style="width:100%;" title="Choose a user to assign" placeholder="Assign users ..." on-select="aclAdd(status.addSharee)" search-enabled="true">
<ui-select-match placeholder="<?php p($l->t('Select users or groups to share with')); ?>">
<span><i class="icon icon-{{$item.type}}"></i> {{ $item.participant.displayname }}</span>
</ui-select-match>
<ui-select-choices refresh="searchForUser($select.search)"
refresh-delay="0" repeat="sharee in boardservice.sharees">
<span><i class="icon icon-{{sharee.type}}"></i> {{ sharee.participant }}</span>
<ui-select-choices refresh="searchForUser($select.search)" refresh-delay="0" repeat="sharee in boardservice.sharees">
<span><i class="icon icon-{{sharee.type}}"></i> {{ sharee.participant.displayname }}</span>
</ui-select-choices>
<ui-select-no-choice>
<?php p($l->t('Dang! We couldn\'t find any choices...')); ?>
<?php p($l->t('No matching user or group found.')); ?>
</ui-select-no-choice>
</ui-select>
<ul id="shareWithList" class="shareWithList">
<li>
<span class="icon-loading-small" style="display:none;"></span>
<div class="avatardiv" avatar ng-attr-displayname="{{ boardservice.getCurrent().owner }}" ng-if="boardservice.id"></div>
<div class="avatardiv" avatar ng-attr-displayname="{{ boardservice.getCurrent().owner.uid }}" ng-if="boardservice.id"></div>
<span class="has-tooltip username">
{{ boardservice.getCurrent().owner }}</span>
<span class="shareOption"><?php p($l->t('Board owner')); ?></span>
{{ boardservice.getCurrent().owner.displayname }}
</span>
</li>
<li ng-repeat="acl in boardservice.getCurrent().acl track by $index">
<span class="icon-loading-small" style="display:none;"></span>
<div class="avatardiv" avatar displayname="{{ acl.participant }}" ng-if="acl.type=='user'"></div>
<div class="avatardiv" avatar displayname="{{ acl.participant.uid }}" ng-if="acl.type=='user'"></div>
<div class="avatardiv" ng-if="acl.type=='group'"><i class="icon icon-{{acl.type}}"></i></div>
<span class="has-tooltip username">
{{ acl.participant }}</span>
{{ acl.participant.displayname }}
</span>
<span class="sharingOptionsGroup">
<span class="shareOption" ng-if="boardservice.canManage()">
<input type="checkbox" class="permissions checkbox" id="checkbox-permission-{{ acl.id }}-share" ng-model="acl.permissionShare" ng-change="aclUpdate(acl)" />
<label for="checkbox-permission-{{ acl.id }}-share"><?php p($l->t('Share')); ?></label>
@@ -57,7 +58,8 @@
<input type="checkbox" class="permissions checkbox" id="checkbox-permission-{{ acl.id }}-manage" ng-model="acl.permissionManage" ng-change="aclUpdate(acl)" />
<label for="checkbox-permission-{{ acl.id }}-manage"><?php p($l->t('Manage')); ?></label>
</span>
<a ng-if="boardservice.canManage()" class="unshare" ng-click="aclDelete(acl)"><span class="icon-loading-small hidden"></span><span class="icon icon-delete"></span><span class="hidden-visually"><?php p($l->t('Discard share')); ?></span></a>
</span>
<a ng-if="boardservice.canManage()" ng-click="aclDelete(acl)"><span class="icon-loading-small hidden"></span><span class="icon icon-delete"></span><span class="hidden-visually"><?php p($l->t('Discard share')); ?></span></a>
</li>
</ul>
@@ -71,7 +73,7 @@
</span>
<span class="label-title" style="background-color:#{{label.color}}; color:{{ textColor(label.color) }}; width:178px;" ng-if="label.edit">
<form ng-submit="labelUpdate(label)">
<input type="text" ng-model="label.title" class="input-inline" style="background-color:#{{label.color}}; color:{{ label.color|textColorFilter }};" autofocus-on-insert />
<input type="text" ng-model="label.title" class="input-inline" style="background-color:#{{label.color}}; color:{{ label.color|textColorFilter }};" autofocus-on-insert maxlength="100"/>
</form>
</span>
<div class="colorselect" ng-if="label.edit">
@@ -85,7 +87,7 @@
<li ng-if="status.createLabel">
<form ng-submit="labelCreate(newLabel)">
<span class="label-title" style="background-color:#{{newLabel.color}}; color:{{ textColor(newLabel.color) }}; width:178px;">
<input type="text" class="input-inline" ng-model="newLabel.title" style="color:{{ newLabel.color|textColorFilter }};" autofocus-on-insert />
<input type="text" class="input-inline" ng-model="newLabel.title" style="color:{{ newLabel.color|textColorFilter }};" autofocus-on-insert maxlength="100" />
</span>
<div class="colorselect">
<div class="color" ng-repeat="c in defaultColors" style="background-color:#{{ c }};" ng-click="newLabel.color=c" ng-class="{'selected': (c == newLabel.color) }"><br /></div>

View File

@@ -17,11 +17,8 @@
<td><a href="#/board/{{b.id}}">{{ b.title }}</a></td>
<td>
<div id="assigned-users">
<div class="avatardiv" avatar
displayname="{{ b.owner }}"></div>
<div class="avatardiv" avatar
displayname="{{ acl.participant }}"
ng-repeat="acl in b.acl | limitTo: 7"></div>
<div class="avatardiv" avatar displayname="{{ b.owner.uid }}" title="{{ b.owner.displayname }}"></div>
<div class="avatardiv" avatar displayname="{{ acl.participant.uid }}" title="{{ acl.participant.uid }}" ng-repeat="acl in b.acl | limitTo: 7"></div>
</div>
</td>
</tr>
@@ -36,7 +33,7 @@
class="ng-pristine ng-valid" ng-submit="boardCreate()">
<input id="newTitle" class="edit ng-valid ng-empty"
type="text" placeholder="<?php p($l->t('New board title')); ?>"
autofocus-on-insert ng-model="newBoard.title">
autofocus-on-insert ng-model="newBoard.title" maxlength="100">
<div class="colorselect">
<div class="color" ng-repeat="c in colors"
style="background-color:#{{ c }};"

View File

@@ -13,7 +13,7 @@
<input class="input-inline" type="text" ng-if="status.cardRename"
ng-model="cardservice.getCurrent().title"
ng-blur="cardRename(cardservice.getCurrent())"
autofocus-on-insert required>
autofocus-on-insert required maxlength="100">
</form>
<div ng-click="cardRenameShow()" ng-show="!status.cardRename">
{{ cardservice.getCurrent().title }}
@@ -26,18 +26,17 @@
<?php p($l->t('Modified:')); ?> <span class="live-relative-timestamp" data-timestamp="{{cardservice.getCurrent().lastModified*1000}}">{{ cardservice.getCurrent().lastModified|relativeDateFilter }}</span>
<?php p($l->t('Created:')); ?> <span class="live-relative-timestamp" data-timestamp="{{cardservice.getCurrent().createdAt*1000}}">{{ cardservice.getCurrent().createdAt|relativeDateFilter }}</span>
<?php p($l->t('by')); ?>
<span>{{ cardservice.getCurrent().owner }}</span>
<span>{{ cardservice.getCurrent().owner.displayname }}</span>
</div>
<div id="labels">
<ui-select multiple tagging="" ng-model="card.labels" theme="bootstrap"
<ui-select multiple tagging="" ng-model="card.labels" theme="select2"
style="width:100%;" title="Choose a label"
placeholder="Add a label"
on-select="labelAssign($item, $model)"
on-remove="labelRemove($item, $model)" ng-disabled="!boardservice.canEdit() || archived">
<ui-select-match placeholder="Select labels..."><span
class="select-label"
style="background-color:#{{$item.color}}; color:{{ $item.color|textColorFilter }};">{{$item.title}}&nbsp;</span>
<ui-select-match placeholder="Select labels...">
<span class="select-label" style="background-color:#{{$item.color}}; color:{{ $item.color|textColorFilter }};">{{$item.title}}&nbsp;</span>
</ui-select-match>
<ui-select-choices
repeat="label in boardservice.getCurrent().labels | filter:$select.search">

View File

@@ -2,20 +2,21 @@
<li><a href="#" class=""><?php p($l->t('All Boards')); ?></a></li>
<li class="with-icon with-menu" data-ng-repeat="b in boardservice.sorted">
<li class="with-icon with-menu" ng-class="{active: b.id === boardservice.getCurrent().id}" data-ng-repeat="b in boardservice.sorted">
<span class="board-bullet" style="background-color:#{{b.color}};" ng-if="!b.status.edit"> </span>
<a href="#!/board/{{b.id}}/" ng-if="!b.status.edit">{{ b.title }}</a>
<div class="app-navigation-entry-utils" ng-show="!b.status.edit" style="position:absolute;">
<ul>
<li class="app-navigation-entry-utils-counter board-delete-undo" ng-show="status.deleteUndo[b.id]" ng-click="boardDeleteUndo(b)" title="Click to undo">Deleting in {{ status.deleteUndo[b.id] }}s &nbsp; X</li>
<li class="app-navigation-entry-utils-menu-share svg" ng-show="b.shared>0"><i class="icon icon-share" title="<?php p($l->t('Shared with you')); ?>"> </i></li>
<li class="app-navigation-entry-utils-menu-button svg"><button class="icon-more"></button></li>
<li class="app-navigation-entry-utils-menu-button svg" ng-show="!status.deleteUndo[b.id]"><button class="icon-more"></button></li>
</ul>
</div>
<div class="app-navigation-entry-menu app-navigation-noclose" ng-show="!b.status.edit">
<ul>
<li ng-show="b.owner===user"><button class="icon-rename svg" title="<?php p($l->t('edit')); ?>" ng-click="b.status.edit=true"></button></li>
<li ng-show="b.owner===user"><button class="icon-delete svg" title="<?php p($l->t('delete')); ?>" ng-click="boardDelete(b)"></button></li>
<li ng-show="b.owner!==user"><button class="icon-delete svg" title="<?php p($l->t('remove share')); ?>" ng-click="boardRemoveShare(b)"></button></li>
<li ng-show="b.owner.uid===user"><button class="icon-rename svg" title="<?php p($l->t('edit')); ?>" ng-click="b.status.edit=true"></button></li>
<li ng-show="b.owner.uid===user"><button class="icon-delete svg" title="<?php p($l->t('delete')); ?>" ng-click="boardDelete(b)"></button></li>
<li ng-show="b.owner.uid!==user && false"><button class="icon-delete svg" title="<?php p($l->t('remove share')); ?>" ng-click="boardRemoveShare(b)"></button></li>
</ul>
</div>
<div class="app-navigation-entry-deleted" ng-show="false">
@@ -24,7 +25,7 @@
</div>
<div class="app-navigation-entry-edit" ng-show="b.status.edit">
<form ng-disabled="isAddingList" class="ng-pristine ng-valid" ng-submit="boardUpdate(b)">
<input id="newTitle" class="edit ng-valid ng-empty" type="text" autofocus-on-insert ng-model="b.title">
<input id="newTitle" class="edit ng-valid ng-empty" type="text" autofocus-on-insert ng-model="b.title" maxlength="100">
<input type="submit" value="" class="action icon-checkmark svg">
<div class="colorselect">
<div class="color" ng-repeat="c in colors" style="background-color:#{{ c }};" ng-click="b.color=c" ng-class="{'selected': (c == b.color) }"><br /></div>
@@ -39,7 +40,7 @@
</a>
<div class="app-navigation-entry-edit" ng-if="status.addBoard">
<form ng-disabled="isAddingList" class="ng-pristine ng-valid" ng-submit="boardCreate()">
<input id="newTitle" class="edit ng-valid ng-empty" type="text" placeholder="<?php p($l->t('Board title')); ?>" autofocus-on-insert ng-model="newBoard.title">
<input id="newTitle" class="edit ng-valid ng-empty" type="text" placeholder="<?php p($l->t('Board title')); ?>" autofocus-on-insert ng-model="newBoard.title" maxlength="100">
<input type="submit" value="" class="action icon-checkmark svg">
<div class="colorselect">
<div class="color" ng-repeat="c in colors" style="background-color:#{{ c }};" ng-click="selectColor(c)" ng-class="{'selected': (c == newBoard.color) }"><br /></div>

View File

@@ -0,0 +1,23 @@
{
"require-dev": {
"phpunit/phpunit": "~4.6",
"behat/behat": "^3.0",
"guzzlehttp/guzzle": "~5.0",
"jarnaiz/behat-junit-formatter": "^1.3",
"sabre/dav": "3.2"
},
"autoload": {
"files": [
"../../../../build/integration/features/bootstrap/Auth.php",
"../../../../build/integration/features/bootstrap/Provisioning.php",
"../../../../build/integration/features/bootstrap/Sharing.php",
"../../../../build/integration/features/bootstrap/Trashbin.php",
"../../../../build/integration/features/bootstrap/WebDav.php"
],
"psr-0": {
"": [
"features/bootstrap/"
]
}
}
}

View File

@@ -0,0 +1,12 @@
default:
suites:
test:
paths:
- %paths.base%/../features/
contexts:
- FeatureContext:
baseUrl: http://localhost:8080/index.php/ocs/
admin:
- admin
- admin
regular_user_password: 123456

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