Compare commits
340 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4d0741e691 | ||
|
|
090e788c0c | ||
|
|
0e6b79fe9b | ||
|
|
ab3a42fc11 | ||
|
|
56bee425b9 | ||
|
|
6e192db79b | ||
|
|
c29aed239c | ||
|
|
9c8f5d5f63 | ||
|
|
1fcb667a3c | ||
|
|
7390acae26 | ||
|
|
677123a8f7 | ||
|
|
067ec5e057 | ||
|
|
fd406a0adb | ||
|
|
1d4fe31155 | ||
|
|
c2b8408cd2 | ||
|
|
b50e295e27 | ||
|
|
97864ac1ff | ||
|
|
f940d23968 | ||
|
|
ce31e02d6a | ||
|
|
c2189683c7 | ||
|
|
9b2903b4d5 | ||
|
|
2875e23b96 | ||
|
|
1d54fc3ae8 | ||
|
|
23e88a7e15 | ||
|
|
08ef55c950 | ||
|
|
4d10b5fd59 | ||
|
|
4a3ba6540c | ||
|
|
9c6d80d5d3 | ||
|
|
2d3ef29041 | ||
|
|
4d9e26a6ce | ||
|
|
1a2c950b61 | ||
|
|
029accfe49 | ||
|
|
7716fb6738 | ||
|
|
da87973b85 | ||
|
|
91aa14c7c2 | ||
|
|
f3da8f80a7 | ||
|
|
5021e475c7 | ||
|
|
7628eb425c | ||
|
|
d33725303a | ||
|
|
e0808273ec | ||
|
|
84dc4ce1dd | ||
|
|
e7fcef3e3a | ||
|
|
99591eae0e | ||
|
|
a88ea8f4b3 | ||
|
|
5772a7025d | ||
|
|
abd82db9af | ||
|
|
6efcf374d3 | ||
|
|
335d9a3a42 | ||
|
|
040e248962 | ||
|
|
87c0bc819a | ||
|
|
d902f88258 | ||
|
|
a6bdf077ff | ||
|
|
0f2e735a20 | ||
|
|
bb2eb7221a | ||
|
|
e69b5465bd | ||
|
|
7d393292f3 | ||
|
|
1c2c700593 | ||
|
|
71e7c98fd6 | ||
|
|
da650bb356 | ||
|
|
ddc903cc03 | ||
|
|
e70340e267 | ||
|
|
c140e2f946 | ||
|
|
7cffc7cdff | ||
|
|
c5ffde0469 | ||
|
|
f561dc77e6 | ||
|
|
b9f37c6c36 | ||
|
|
60e6ac0f10 | ||
|
|
9fbd85a67a | ||
|
|
27b8c79bca | ||
|
|
31ae00708d | ||
|
|
3b8ee46bdd | ||
|
|
999010aec2 | ||
|
|
b577a79915 | ||
|
|
d6373226db | ||
|
|
436ca348e4 | ||
|
|
1f56372aa0 | ||
|
|
5028b48777 | ||
|
|
e968b6f680 | ||
|
|
452f49c17c | ||
|
|
df0a8515a3 | ||
|
|
7b1dea3e56 | ||
|
|
6862b1c07e | ||
|
|
d05694c2ce | ||
|
|
d156a6ae80 | ||
|
|
511f17f13f | ||
|
|
8073ae9c0e | ||
|
|
6eb8c117a3 | ||
|
|
f74a3d6724 | ||
|
|
d3efff0ce7 | ||
|
|
44fd63ef7e | ||
|
|
19f5063068 | ||
|
|
8bc497b4b2 | ||
|
|
fba60673c5 | ||
|
|
36afac9eff | ||
|
|
014f708752 | ||
|
|
2139a82e9d | ||
|
|
4e320ff1e9 | ||
|
|
d4c744b084 | ||
|
|
695042cdd0 | ||
|
|
6c8ac1ed47 | ||
|
|
b75d1ef3fd | ||
|
|
cba7525951 | ||
|
|
1db20878a9 | ||
|
|
12037679e5 | ||
|
|
80b025fafe | ||
|
|
91f9b8ee72 | ||
|
|
ab1c765ff6 | ||
|
|
8661d51317 | ||
|
|
625ebdc4c0 | ||
|
|
283aa01fd4 | ||
|
|
2ad66ca76e | ||
|
|
1d8b4cd33d | ||
|
|
469e687686 | ||
|
|
ee2ebbecf8 | ||
|
|
90d6923fb6 | ||
|
|
d08bd23578 | ||
|
|
f36a1614c2 | ||
|
|
011470cfde | ||
|
|
fecd59b511 | ||
|
|
59827e0f69 | ||
|
|
619f70b33b | ||
|
|
bc904c44d4 | ||
|
|
6a43db39a3 | ||
|
|
57921c9e96 | ||
|
|
eb4b82060a | ||
|
|
60bf07d88b | ||
|
|
71617d9d6b | ||
|
|
1c040d35be | ||
|
|
329df8e856 | ||
|
|
493eee601b | ||
|
|
e3405c915b | ||
|
|
001aaa4dcd | ||
|
|
9f62a24450 | ||
|
|
6b8d42f176 | ||
|
|
bc7c5ea4b7 | ||
|
|
c3d925a172 | ||
|
|
1b2fed9e86 | ||
|
|
f4f7c05f9f | ||
|
|
610507f790 | ||
|
|
edbeda81f6 | ||
|
|
9accaa4987 | ||
|
|
0dbe106907 | ||
|
|
64e3af25f9 | ||
|
|
77a3563b89 | ||
|
|
ba3b5b59ff | ||
|
|
60d77e4d33 | ||
|
|
6f595aebdc | ||
|
|
0b5c7fb56a | ||
|
|
f14e9758a0 | ||
|
|
bd5f2c13b7 | ||
|
|
bdb9442671 | ||
|
|
8874b3df69 | ||
|
|
74550b9953 | ||
|
|
a0af85abe4 | ||
|
|
34316d84f0 | ||
|
|
84a9e72463 | ||
|
|
da8b7774b4 | ||
|
|
0de1c581e8 | ||
|
|
1eeaff7f29 | ||
|
|
27ec348533 | ||
|
|
a5ee26a592 | ||
|
|
3496c09472 | ||
|
|
be752061ff | ||
|
|
1652bb921a | ||
|
|
7aa7574e26 | ||
|
|
2887df270d | ||
|
|
c0a9597877 | ||
|
|
f63eef36b7 | ||
|
|
35e7c7dbe7 | ||
|
|
75189217b0 | ||
|
|
519336787c | ||
|
|
9e792db7c0 | ||
|
|
23a218d9af | ||
|
|
ec7eb72f05 | ||
|
|
4324fe9e2e | ||
|
|
0e3b54a5d4 | ||
|
|
8dffaaa8c5 | ||
|
|
6d88ea7ef6 | ||
|
|
4ca406472d | ||
|
|
f8cd20a01a | ||
|
|
aa2b9adeec | ||
|
|
37de63434e | ||
|
|
bb665fa56c | ||
|
|
a13e4b664d | ||
|
|
e020c2631f | ||
|
|
781e2b0bb2 | ||
|
|
2d35d90999 | ||
|
|
65952acfdb | ||
|
|
7ec4870999 | ||
|
|
015e2d9461 | ||
|
|
623b55d348 | ||
|
|
0e37354a6e | ||
|
|
e16852ad17 | ||
|
|
8fc38a41d0 | ||
|
|
097bb21b45 | ||
|
|
39ae9332e2 | ||
|
|
cc92937c6b | ||
|
|
ac9fef5f05 | ||
|
|
4e67c3172b | ||
|
|
4a45687a28 | ||
|
|
38dc7945dd | ||
|
|
70d3fba187 | ||
|
|
10b7d8b335 | ||
|
|
fcabdbdc24 | ||
|
|
408ea69272 | ||
|
|
c6d16f4c16 | ||
|
|
770142232c | ||
|
|
501545f2e5 | ||
|
|
f71f24c450 | ||
|
|
b8cb364f00 | ||
|
|
3cb811bb79 | ||
|
|
910325a712 | ||
|
|
2f14fa60e9 | ||
|
|
5f9d039056 | ||
|
|
cc96da86c2 | ||
|
|
7523792b9a | ||
|
|
c7b7f767e0 | ||
|
|
ead3608082 | ||
|
|
21920b2380 | ||
|
|
4f1f9fd78d | ||
|
|
1155b85554 | ||
|
|
86515a7219 | ||
|
|
159535a1f5 | ||
|
|
e8c8d4c08d | ||
|
|
56708643d5 | ||
|
|
39ca8e5255 | ||
|
|
8402b80690 | ||
|
|
49c21f7dc4 | ||
|
|
362de5d411 | ||
|
|
d32da1017c | ||
|
|
643797daca | ||
|
|
b854015e16 | ||
|
|
e7400fe1e5 | ||
|
|
3f272b91c6 | ||
|
|
907bf57460 | ||
|
|
49e1d8e8ec | ||
|
|
1cd1684936 | ||
|
|
b3cb618707 | ||
|
|
96ec6b812c | ||
|
|
ec01ab4f42 | ||
|
|
f51d0b6716 | ||
|
|
e654fa0b4c | ||
|
|
ea01804567 | ||
|
|
93589d3eed | ||
|
|
a7497aa590 | ||
|
|
74eb579474 | ||
|
|
b2d844c013 | ||
|
|
dfb91a0e39 | ||
|
|
07cfa1abb8 | ||
|
|
29c63288bf | ||
|
|
47f9b6cfc3 | ||
|
|
f04225a33a | ||
|
|
a3b89f7da6 | ||
|
|
8f1dbd3576 | ||
|
|
d92f4d9739 | ||
|
|
4c9b4ed24f | ||
|
|
79c653152c | ||
|
|
1a7d3ce00f | ||
|
|
77fb6d54ea | ||
|
|
f14e086c66 | ||
|
|
0506c2454f | ||
|
|
adf443902c | ||
|
|
6c3239ea1f | ||
|
|
c2b5ada462 | ||
|
|
1f14b76caa | ||
|
|
026abd72f6 | ||
|
|
18544f90c2 | ||
|
|
0d7379366e | ||
|
|
2c7ce4590a | ||
|
|
64f6a64f77 | ||
|
|
8cec3f4b58 | ||
|
|
4c14cb74c1 | ||
|
|
4729e1f85b | ||
|
|
297eb6b2c8 | ||
|
|
65c83837a3 | ||
|
|
bd0aa664b8 | ||
|
|
b46e4c918a | ||
|
|
1b4519f578 | ||
|
|
f00f03253b | ||
|
|
65bfebb218 | ||
|
|
96f328475d | ||
|
|
71cbf8894d | ||
|
|
1bcb07bcad | ||
|
|
6b5adbed02 | ||
|
|
47b08f0e52 | ||
|
|
c8b5b1efa5 | ||
|
|
8521cf4e0c | ||
|
|
a63de8066e | ||
|
|
35d9b48117 | ||
|
|
0f46b283b7 | ||
|
|
c1580c765b | ||
|
|
1fc0d64925 | ||
|
|
45be999245 | ||
|
|
03a3d29f1a | ||
|
|
b1e434ef6b | ||
|
|
1edb403c9a | ||
|
|
d2f78714a6 | ||
|
|
fb2ee56346 | ||
|
|
950c6b9046 | ||
|
|
acd85eb097 | ||
|
|
ef06f21d2a | ||
|
|
24af938058 | ||
|
|
2354a96624 | ||
|
|
4a2c360de1 | ||
|
|
89fc66df64 | ||
|
|
d60ff00eec | ||
|
|
756b4ddcc2 | ||
|
|
41b917abfb | ||
|
|
5ab601274c | ||
|
|
1b0ea73318 | ||
|
|
32269d0483 | ||
|
|
021e3aa346 | ||
|
|
465a09f129 | ||
|
|
adc44622eb | ||
|
|
0711149e41 | ||
|
|
69ad41bb58 | ||
|
|
22744ee39c | ||
|
|
6a3643384c | ||
|
|
2649309e57 | ||
|
|
6b2873ab28 | ||
|
|
643d70e6f0 | ||
|
|
17fcf0cd61 | ||
|
|
922aaf31d8 | ||
|
|
8c94da81f1 | ||
|
|
a4dbb31b8c | ||
|
|
5ea20e1268 | ||
|
|
bd349a677d | ||
|
|
411cab1d45 | ||
|
|
18b03550cc | ||
|
|
6ae42b1007 | ||
|
|
37ce80b085 | ||
|
|
c121a936ef | ||
|
|
a1edb667b9 | ||
|
|
4ef6045ee5 | ||
|
|
6783962cd8 | ||
|
|
921cfdfc4a | ||
|
|
c5179ac62f | ||
|
|
0a50467db0 | ||
|
|
7f6cde15d4 | ||
|
|
1e4d663c11 |
18
.babelrc
Normal file
18
.babelrc
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"plugins": [
|
||||
"@babel/plugin-syntax-dynamic-import"
|
||||
],
|
||||
"presets": [
|
||||
[
|
||||
"@babel/preset-env",
|
||||
{
|
||||
"targets": {
|
||||
"browsers": [
|
||||
"last 2 versions",
|
||||
"ie >= 11"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
61
.drone.yml
61
.drone.yml
@@ -2,7 +2,7 @@ kind: pipeline
|
||||
name: checkers
|
||||
steps:
|
||||
- name: compatibility
|
||||
image: nextcloudci/php7.2:php7.2-13
|
||||
image: nextcloudci/php7.1:php7.1-16
|
||||
environment:
|
||||
APP_NAME: deck
|
||||
CORE_BRANCH: master
|
||||
@@ -16,8 +16,17 @@ steps:
|
||||
- ./occ app:check-code $APP_NAME -c strong-comparison
|
||||
- ./occ app:check-code $APP_NAME -c deprecation
|
||||
- cd apps/$APP_NAME/
|
||||
- name: syntax-php7.1
|
||||
image: nextcloudci/php7.1:php7.1-15
|
||||
environment:
|
||||
APP_NAME: deck
|
||||
CORE_BRANCH: master
|
||||
DB: sqlite
|
||||
commands:
|
||||
- composer install
|
||||
- ./vendor/bin/parallel-lint --exclude ./vendor/ .
|
||||
- name: syntax-php7.2
|
||||
image: nextcloudci/php7.2:php7.2-13
|
||||
image: nextcloudci/php7.2:php7.2-9
|
||||
environment:
|
||||
APP_NAME: deck
|
||||
CORE_BRANCH: master
|
||||
@@ -34,15 +43,33 @@ steps:
|
||||
commands:
|
||||
- composer install
|
||||
- ./vendor/bin/parallel-lint --exclude ./vendor/ .
|
||||
- name: syntax-php7.4
|
||||
image: nextcloudci/php7.4:2
|
||||
environment:
|
||||
trigger:
|
||||
branch:
|
||||
- master
|
||||
- stable*
|
||||
event:
|
||||
- pull_request
|
||||
- push
|
||||
---
|
||||
kind: pipeline
|
||||
name: unit-php7.1
|
||||
steps:
|
||||
- name: php7.1
|
||||
image: nextcloudci/php7.1:php7.1-16
|
||||
environment:
|
||||
APP_NAME: deck
|
||||
CORE_BRANCH: master
|
||||
DB: sqlite
|
||||
commands:
|
||||
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
|
||||
- composer install
|
||||
- ./vendor/bin/parallel-lint --exclude ./vendor/ .
|
||||
- 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
|
||||
trigger:
|
||||
branch:
|
||||
- master
|
||||
@@ -55,7 +82,7 @@ kind: pipeline
|
||||
name: unit-php7.2
|
||||
steps:
|
||||
- name: php7.2
|
||||
image: nextcloudci/php7.2:php7.2-13
|
||||
image: nextcloudci/php7.2:php7.2-9
|
||||
environment:
|
||||
APP_NAME: deck
|
||||
CORE_BRANCH: master
|
||||
@@ -82,7 +109,7 @@ kind: pipeline
|
||||
name: unit-php7.3
|
||||
steps:
|
||||
- name: php7.3
|
||||
image: nextcloudci/php7.3:php7.3-5
|
||||
image: nextcloudci/php7.3:php7.3-2
|
||||
environment:
|
||||
APP_NAME: deck
|
||||
CORE_BRANCH: master
|
||||
@@ -109,7 +136,7 @@ kind: pipeline
|
||||
name: integration
|
||||
steps:
|
||||
- name: integration
|
||||
image: nextcloudci/php7.2:php7.2-13
|
||||
image: nextcloudci/php7.1:php7.1-16
|
||||
environment:
|
||||
APP_NAME: deck
|
||||
CORE_BRANCH: master
|
||||
@@ -135,19 +162,23 @@ trigger:
|
||||
kind: pipeline
|
||||
name: frontend
|
||||
steps:
|
||||
- name: install
|
||||
image: node:11-alpine
|
||||
commands:
|
||||
- npm install
|
||||
- name: eslint
|
||||
image: nextcloudci/eslint:eslint-1
|
||||
image: node:11-alpine
|
||||
commands:
|
||||
- ./run-eslint.sh
|
||||
- npm run lint
|
||||
- name: jsbuild
|
||||
image: node:lts-alpine
|
||||
image: node:11-alpine
|
||||
commands:
|
||||
- apk add --no-cache make
|
||||
- make build-js
|
||||
- npm run build
|
||||
trigger:
|
||||
branch:
|
||||
- master
|
||||
- stable*
|
||||
- vue
|
||||
event:
|
||||
- pull_request
|
||||
- push
|
||||
|
||||
9
.editorconfig
Normal file
9
.editorconfig
Normal file
@@ -0,0 +1,9 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
|
||||
[*.{js,vue}]
|
||||
indent_style = tab
|
||||
67
.eslintrc.js
Normal file
67
.eslintrc.js
Normal file
@@ -0,0 +1,67 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
env: {
|
||||
browser: true,
|
||||
es6: true,
|
||||
node: true,
|
||||
jest: true
|
||||
},
|
||||
globals: {
|
||||
t: true,
|
||||
n: true,
|
||||
OC: true,
|
||||
OCA: true,
|
||||
Vue: true,
|
||||
VueRouter: true
|
||||
},
|
||||
parserOptions: {
|
||||
parser: 'babel-eslint',
|
||||
ecmaVersion: 6
|
||||
},
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:node/recommended',
|
||||
'plugin:vue/essential',
|
||||
'plugin:vue/recommended',
|
||||
'standard'
|
||||
],
|
||||
plugins: ['vue', 'node'],
|
||||
rules: {
|
||||
// space before function ()
|
||||
'space-before-function-paren': ['error', 'never'],
|
||||
// curly braces always space
|
||||
'object-curly-spacing': ['error', 'always'],
|
||||
// stay consistent with array brackets
|
||||
'array-bracket-newline': ['error', 'consistent'],
|
||||
// 1tbs brace style
|
||||
'brace-style': 'error',
|
||||
// tabs only
|
||||
indent: ['error', 'tab'],
|
||||
'no-tabs': 0,
|
||||
'vue/html-indent': ['error', 'tab'],
|
||||
// only debug console
|
||||
'no-console': ['warn', { allow: ['error', 'warn', 'debug'] }],
|
||||
// classes blocks
|
||||
'padded-blocks': ['error', { classes: 'always' }],
|
||||
// always have the operator in front
|
||||
'operator-linebreak': ['error', 'before'],
|
||||
// ternary on multiline
|
||||
'multiline-ternary': ['error', 'always-multiline'],
|
||||
// es6 import/export and require
|
||||
'node/no-unpublished-require': ['off'],
|
||||
'node/no-unsupported-features/es-syntax': ['off'],
|
||||
// space before self-closing elements
|
||||
'vue/html-closing-bracket-spacing': 'error',
|
||||
// code spacing with attributes
|
||||
'vue/max-attributes-per-line': [
|
||||
'error',
|
||||
{
|
||||
singleline: 3,
|
||||
multiline: {
|
||||
max: 3,
|
||||
allowFirstLine: true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
root: true
|
||||
|
||||
extends:
|
||||
- eslint:recommended
|
||||
|
||||
env:
|
||||
browser: true
|
||||
amd: true
|
||||
es6: true
|
||||
|
||||
globals:
|
||||
global: false
|
||||
app: false
|
||||
angular: false
|
||||
$: false
|
||||
escapeHTML: false
|
||||
OC: false
|
||||
OCA: false
|
||||
t: false
|
||||
oc_current_user: false
|
||||
oc_requesttoken: false
|
||||
Clipboard: false
|
||||
oc_defaults: false
|
||||
|
||||
parserOptions:
|
||||
ecmaVersion: 6
|
||||
sourceType: "module"
|
||||
|
||||
rules:
|
||||
curly: error
|
||||
eqeqeq: ["error", "smart"]
|
||||
guard-for-in: error
|
||||
no-console: off
|
||||
no-fallthrough: error
|
||||
no-mixed-spaces-and-tabs: error
|
||||
no-unused-vars: warn
|
||||
no-useless-escape: warn
|
||||
no-use-before-define: error
|
||||
semi: ["error", "always"]
|
||||
indent:
|
||||
- error
|
||||
- tab
|
||||
- SwitchCase: 1
|
||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -1,7 +1,5 @@
|
||||
js/node_modules/*
|
||||
js/vendor/
|
||||
js/public/
|
||||
js/build/
|
||||
node_modules/*
|
||||
js/
|
||||
build/
|
||||
css/style.css
|
||||
css/vendor.css
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
/build/
|
||||
/.git
|
||||
/js/node_modules
|
||||
/js/tests
|
||||
/js/legacy
|
||||
/js/controller
|
||||
/js/directive
|
||||
/js/filters
|
||||
/js/service
|
||||
/js/bower.json
|
||||
/js/.bowerrc
|
||||
/js/.jshintrc
|
||||
/js/Gruntfile.js
|
||||
/js/package.json
|
||||
/js/package-lock.json
|
||||
/docs/
|
||||
/tests
|
||||
/.codecov.yml
|
||||
/composer.json
|
||||
/composer.lock
|
||||
/_config.yml
|
||||
/.drone.yml
|
||||
/.travis.yml
|
||||
/.eslintignore
|
||||
/.eslintrc.yml
|
||||
/.gitignore
|
||||
/issue_template.md
|
||||
/krankerl.toml
|
||||
/Makefile
|
||||
/mkdocs.yml
|
||||
/run-eslint.sh
|
||||
@@ -2,13 +2,18 @@ language: php
|
||||
services:
|
||||
- mysql
|
||||
php:
|
||||
- 7.1
|
||||
- 7.2
|
||||
- 7.3
|
||||
env:
|
||||
- CORE_BRANCH=master DB=mysql
|
||||
|
||||
before_install:
|
||||
- export PATH="$PWD/vendor/bin:$PATH"
|
||||
- wget https://phar.phpunit.de/phpunit-6.5.phar
|
||||
- chmod +x phpunit-6.5.phar
|
||||
- mkdir bin
|
||||
- mv phpunit-6.5.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
|
||||
|
||||
27
CHANGELOG.md
27
CHANGELOG.md
@@ -1,33 +1,6 @@
|
||||
# Changelog
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## 0.8.2 - 2020-04-08
|
||||
|
||||
## Fixed
|
||||
- Fix build with missing javascript bundles
|
||||
|
||||
## 0.8.1 - 2020-04-08
|
||||
|
||||
## Added
|
||||
- Nextcloud 19 compatibility
|
||||
|
||||
## Fixed
|
||||
- Let new shares only use the current users permissions
|
||||
- Check for board membership on comments entity event
|
||||
|
||||
## 0.8.0 - 2020-01-16
|
||||
|
||||
## Added
|
||||
- Case insensitive search (@matchish)
|
||||
|
||||
## Fixed
|
||||
- Fix reversed permissions for reordering stacks (@JLueke)
|
||||
- Fix reversed visibility of 'add stack' field (@JLueke)
|
||||
- Fix occ export command
|
||||
- Fix error causing cron execution to fail
|
||||
- Fix activity entry on moving cards
|
||||
- Proper wording in activity timeline (@a11exandru)
|
||||
|
||||
## 0.7.0 - 2019-08-20
|
||||
|
||||
## Added
|
||||
|
||||
2
Makefile
2
Makefile
@@ -84,7 +84,7 @@ test-unit:
|
||||
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-8.2.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
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
- 🚀 Get your project organized
|
||||
|
||||
</description>
|
||||
<version>0.8.2</version>
|
||||
<version>0.7.0</version>
|
||||
<licence>agpl</licence>
|
||||
<author>Julius Härtl</author>
|
||||
<namespace>Deck</namespace>
|
||||
@@ -36,7 +36,7 @@
|
||||
<database min-version="9.4">pgsql</database>
|
||||
<database>sqlite</database>
|
||||
<database min-version="5.5">mysql</database>
|
||||
<nextcloud min-version="17" max-version="19" />
|
||||
<nextcloud min-version="17" max-version="18" />
|
||||
</dependencies>
|
||||
<background-jobs>
|
||||
<job>OCA\Deck\Cron\DeleteCron</job>
|
||||
|
||||
@@ -40,6 +40,7 @@ return [
|
||||
['name' => 'board#addAcl', 'url' => '/boards/{boardId}/acl', 'verb' => 'POST'],
|
||||
['name' => 'board#updateAcl', 'url' => '/boards/{boardId}/acl', 'verb' => 'PUT'],
|
||||
['name' => 'board#deleteAcl', 'url' => '/boards/{boardId}/acl/{aclId}', 'verb' => 'DELETE'],
|
||||
['name' => 'board#clone', 'url' => '/boards/{boardId}/clone', 'verb' => 'POST'],
|
||||
|
||||
// stacks
|
||||
['name' => 'stack#index', 'url' => '/stacks/{boardId}', 'verb' => 'GET'],
|
||||
|
||||
@@ -13,8 +13,7 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"roave/security-advisories": "dev-master",
|
||||
"christophwurst/nextcloud": "^17",
|
||||
"jakub-onderka/php-parallel-lint": "^1.0.0",
|
||||
"phpunit/phpunit": "^8"
|
||||
"christophwurst/nextcloud": "^16.0",
|
||||
"jakub-onderka/php-parallel-lint": "^1.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
|
||||
*
|
||||
* @author Julius Härtl <jus@bitgrid.net>
|
||||
* @author Artem Anufrij <artem.anufrij@live.de>
|
||||
* @author Marin Treselj <marin@pixelipo.com>
|
||||
* @author Oskar Kurz <oskar.kurz@gmail.com>
|
||||
* @author Ryan Fletcher <ryan.fletcher@codepassion.ca>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
@@ -20,28 +24,17 @@
|
||||
*
|
||||
*/
|
||||
|
||||
import app from '../app/App.js';
|
||||
// OwnCloud Click Handling
|
||||
// https://doc.owncloud.org/server/8.0/developer_manual/app/css.html
|
||||
app.directive('appNavigationEntryUtils', function () {
|
||||
'use strict';
|
||||
return {
|
||||
restrict: 'C',
|
||||
link: function (scope, elm) {
|
||||
// colors
|
||||
$color-warning-light: nc-lighten($color-warning, 15%);
|
||||
$color-lightgrey: nc-darken($color-main-background, 4%);
|
||||
$color-grey: nc-darken($color-main-background, 7%);
|
||||
$color-darkgrey: nc-darken($color-main-background, 32%);
|
||||
|
||||
var menu = elm.siblings('.app-navigation-entry-menu');
|
||||
var button = $(elm)
|
||||
.find('.app-navigation-entry-utils-menu-button button');
|
||||
// margins/paddings
|
||||
$board-item-margin: 10px 10px 20px 10px;
|
||||
$board-last-item-margin: 10px;
|
||||
|
||||
button.click(function () {
|
||||
menu.toggleClass('open');
|
||||
});
|
||||
scope.$on('documentClicked', function (scope, event) {
|
||||
if (event.target !== button[0]) {
|
||||
menu.removeClass('open');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
$compact-board-item-margin: 5px 10px 10px 10px;
|
||||
$compact-board-last-item-margin: 5px 10px 10px;
|
||||
|
||||
@import 'icons';
|
||||
@@ -5,10 +5,6 @@
|
||||
background-image: url('../img/deck-dark.svg');
|
||||
}
|
||||
|
||||
.icon-group {
|
||||
background-image: url('../../../settings/img/users.svg');
|
||||
}
|
||||
|
||||
.icon-help {
|
||||
background-image: url('../../../settings/img/help.svg');
|
||||
}
|
||||
@@ -17,6 +13,10 @@
|
||||
background-image: url('../img/add-white.svg');
|
||||
}
|
||||
|
||||
.icon-attach {
|
||||
background-image: url('../img/attach.svg');
|
||||
}
|
||||
|
||||
.icon-archive {
|
||||
background-image: url('../img/archive.svg');
|
||||
}
|
||||
@@ -53,11 +53,14 @@
|
||||
background-image: url('../img/toggle-view-collapse.svg');
|
||||
}
|
||||
|
||||
|
||||
@if mixin-exists('icon-black-white') {
|
||||
@include icon-black-white('deck', 'deck', 1);
|
||||
@include icon-black-white('archive', 'deck', 1);
|
||||
@include icon-black-white('circles', 'deck', 1);
|
||||
|
||||
@include icon-black-white('deck', 'deck', 1);
|
||||
@include icon-black-white('archive', 'deck', 1);
|
||||
@include icon-black-white('circles', 'deck', 1);
|
||||
@include icon-black-white('clone', 'deck', 1);
|
||||
@include icon-black-white('attach', 'deck', 1);
|
||||
|
||||
.icon-toggle-compact-collapsed {
|
||||
@include icon-color('toggle-view-expand', 'deck', $color-black);
|
||||
}
|
||||
@@ -77,4 +80,7 @@
|
||||
opacity: 1;
|
||||
background-size: 20px;
|
||||
background-position: center center;
|
||||
}
|
||||
}
|
||||
.icon-colorpicker {
|
||||
background-image: url('../img/color_picker.svg');
|
||||
}
|
||||
|
||||
@@ -72,10 +72,6 @@ input.input-inline {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
#app img {
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
#searchbox {
|
||||
display: flex !important;
|
||||
}
|
||||
@@ -543,11 +539,6 @@ input.input-inline {
|
||||
margin-right: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 22px;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
|
||||
43
docs/API.md
43
docs/API.md
@@ -45,13 +45,6 @@ In any case a user doesn't have access to a requested entity, a 403 error will b
|
||||
### If-Modified-Since
|
||||
|
||||
Some index endpoints support limiting the result set to entries that have been changed since the given time.
|
||||
The supported date formats are:
|
||||
|
||||
* IMF-fixdate: `Sun, 03 Aug 2019 10:34:12 GMT`
|
||||
* (obsolete) RFC 850: `Sunday, 03-Aug-19 10:34:12 GMT`
|
||||
* (obsolete) ANSI C asctime(): `Sun Aug 3 10:34:12 2019`
|
||||
|
||||
It is highly recommended to only use the IMF-fixdate format.
|
||||
|
||||
Example curl request:
|
||||
|
||||
@@ -59,7 +52,7 @@ Example curl request:
|
||||
curl -u admin:admin -X GET \
|
||||
'http://localhost:8000/index.php/apps/deck/api/v1.0/boards/2/stacks' \
|
||||
-H "OCS-APIRequest: true" \
|
||||
-H "If-Modified-Since: Mon, 05 Nov 2018 09:28:00 GMT"
|
||||
-H "If-Modified-Since: Mon, 5 Nov 2018 09:28:00 GMT"
|
||||
```
|
||||
|
||||
# Endpoints
|
||||
@@ -433,13 +426,6 @@ The board list endpoint supports setting an `If-Modified-Since` header to limit
|
||||
|
||||
### POST /boards/{boardId}/stacks - Create a new stack
|
||||
|
||||
#### Request body
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ------- | ---------------------------------------------------- |
|
||||
| title | String | The title of the new stack |
|
||||
| order | Integer | Order for sorting the stacks |
|
||||
|
||||
#### Request parameters
|
||||
|
||||
| Parameter | Type | Description |
|
||||
@@ -651,33 +637,6 @@ The board list endpoint supports setting an `If-Modified-Since` header to limit
|
||||
|
||||
##### 200 Success
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 3,
|
||||
"participant": {
|
||||
"primaryKey": "admin",
|
||||
"uid": "admin",
|
||||
"displayname": "admin"
|
||||
},
|
||||
"cardId": 1
|
||||
}
|
||||
```
|
||||
|
||||
##### 400 Bad request
|
||||
|
||||
```json
|
||||
{
|
||||
"status": 400,
|
||||
"message": "The user is already assigned to the card"
|
||||
}
|
||||
```
|
||||
|
||||
The request can fail with a bad request response for the following reasons:
|
||||
- Missing or wrongly formatted request parameters
|
||||
- The user is already assigned to the card
|
||||
- The user is not part of the board
|
||||
|
||||
|
||||
### PUT /boards/{boardId}/stacks/{stackId}/cards/{cardId}/unassignUser - Assign a user to a card
|
||||
|
||||
#### Request parameters
|
||||
|
||||
1
img/attach.svg
Normal file
1
img/attach.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M16.5 6v11.5c0 2.21-1.79 4-4 4s-4-1.79-4-4V5c0-1.38 1.12-2.5 2.5-2.5s2.5 1.12 2.5 2.5v10.5c0 .55-.45 1-1 1s-1-.45-1-1V6H10v9.5c0 1.38 1.12 2.5 2.5 2.5s2.5-1.12 2.5-2.5V5c0-2.21-1.79-4-4-4S7 2.79 7 5v12.5c0 3.04 2.46 5.5 5.5 5.5s5.5-2.46 5.5-5.5V6h-1.5z"/><path d="M0 0h24v24H0z" fill="none"/></svg>
|
||||
|
After Width: | Height: | Size: 390 B |
1
img/clone.svg
Normal file
1
img/clone.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="16" height="16" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M11.8 13.8H2.2V4.2h9.6m1.2 0c0-.67-.53-1.2-1.2-1.2H2.2C1.53 3 1 3.53 1 4.2v9.6c0 .67.53 1.2 1.2 1.2h9.6c.67 0 1.2-.53 1.2-1.2"/><path d="m4.2 1c-0.67 0-1.2 0.54-1.2 1.2h10.8v10.8c0.67 0 1.2-0.53 1.2-1.2v-9.6c0-0.67-0.53-1.2-1.2-1.2z"/></svg>
|
||||
|
After Width: | Height: | Size: 327 B |
@@ -1,12 +0,0 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
[
|
||||
'@babel/preset-env',
|
||||
{
|
||||
targets: {
|
||||
browsers: ['last 2 versions', 'ie >= 11']
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
49
js/.jshintrc
49
js/.jshintrc
@@ -1,49 +0,0 @@
|
||||
{
|
||||
"esversion": 6,
|
||||
|
||||
"globals": {
|
||||
"jasmine" : false,
|
||||
"spyOn" : false,
|
||||
"it" : false,
|
||||
"describe" : false,
|
||||
"expect" : false,
|
||||
"beforeEach" : false,
|
||||
"waits" : false,
|
||||
"waitsFor" : false,
|
||||
"runs" : false,
|
||||
"require" : false,
|
||||
"module": true
|
||||
},
|
||||
|
||||
"asi" : true,
|
||||
"boss" : true,
|
||||
"browser" : true,
|
||||
"curly" : true,
|
||||
"debug" : true,
|
||||
"devel" : true,
|
||||
"eqeqeq" : true,
|
||||
"eqnull" : false,
|
||||
"evil" : false,
|
||||
"forin" : true,
|
||||
"immed" : true,
|
||||
"indent" : 4,
|
||||
"jquery" : true,
|
||||
"latedef" : true,
|
||||
"laxbreak" : false,
|
||||
"newcap" : true,
|
||||
"noarg" : true,
|
||||
"node" : false,
|
||||
"noempty" : false,
|
||||
"nomen" : false,
|
||||
"nonew" : true,
|
||||
"onevar" : true,
|
||||
"plusplus" : false,
|
||||
"quotmark" : "single",
|
||||
"regexp" : false,
|
||||
"sub" : true,
|
||||
"trailing" : true,
|
||||
"undef" : true,
|
||||
"unused" : true,
|
||||
"white" : false,
|
||||
"scripturl" : true
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/* global angular */
|
||||
|
||||
|
||||
angular.module('markdown', [])
|
||||
.provider('markdown', [function () {
|
||||
var opts = {};
|
||||
return {
|
||||
config: function (newOpts) {
|
||||
opts = newOpts;
|
||||
},
|
||||
$get: function () {
|
||||
return new window.showdown.Converter(opts);
|
||||
}
|
||||
};
|
||||
}])
|
||||
.filter('markdown', ['markdown', function (markdown) {
|
||||
return function (text) {
|
||||
return markdown.makeHtml(text || '');
|
||||
};
|
||||
}]);
|
||||
|
||||
import uirouter from '@uirouter/angularjs';
|
||||
import ngsanitize from 'angular-sanitize';
|
||||
import angularuiselect from 'ui-select';
|
||||
import ngsortable from 'ng-sortable';
|
||||
import md from 'angular-markdown-it';
|
||||
import nganimate from 'angular-animate';
|
||||
import 'angular-file-upload';
|
||||
import ngInfiniteScroll from 'ng-infinite-scroll';
|
||||
import '../legacy/jquery.atwho.min';
|
||||
import '../legacy/jquery.caret.min';
|
||||
|
||||
var app = angular.module('Deck', [
|
||||
ngsanitize,
|
||||
uirouter,
|
||||
angularuiselect,
|
||||
ngsortable, md, nganimate,
|
||||
'angularFileUpload',
|
||||
ngInfiniteScroll
|
||||
]);
|
||||
|
||||
export default app;
|
||||
117
js/app/Config.js
117
js/app/Config.js
@@ -1,117 +0,0 @@
|
||||
/*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/* global app oc_requesttoken markdownitLinkTarget */
|
||||
|
||||
import app from './App.js';
|
||||
import md from 'angular-markdown-it';
|
||||
import markdownitLinkTarget from 'markdown-it-link-target';
|
||||
import markdownitCheckbox from 'legacy/markdown-it-checkbox.js';
|
||||
|
||||
app.config(function ($provide, $interpolateProvider, $httpProvider, $urlRouterProvider, $stateProvider, $compileProvider, markdownItConverterProvider) {
|
||||
'use strict';
|
||||
$httpProvider.defaults.headers.common.requesttoken = oc_requesttoken;
|
||||
|
||||
|
||||
$compileProvider.debugInfoEnabled(true);
|
||||
// This should fix adding "unsafe:" prefix to ui-select href links containing javascript
|
||||
// inline JS is blocked by CSP anyway and filtered out by our markdown renderer as well
|
||||
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|javascript):/);
|
||||
|
||||
markdownItConverterProvider.config({
|
||||
breaks: true,
|
||||
linkify: true,
|
||||
xhtmlOut: true
|
||||
});
|
||||
markdownItConverterProvider.use(markdownitLinkTarget).use(markdownitCheckbox);
|
||||
|
||||
$urlRouterProvider.otherwise('/');
|
||||
|
||||
$stateProvider
|
||||
.state('list', {
|
||||
url: '/:filter',
|
||||
templateUrl: '/boardlist.mainView.html',
|
||||
controller: 'ListController',
|
||||
reloadOnSearch: false,
|
||||
params: {
|
||||
filter: {value: '', dynamic: true}
|
||||
}
|
||||
})
|
||||
.state('board', {
|
||||
url: '/board/:boardId/:filter',
|
||||
templateUrl: '/board.html',
|
||||
controller: 'BoardController',
|
||||
params: {
|
||||
filter: {value: '', dynamic: true}
|
||||
}
|
||||
})
|
||||
.state('board.detail', {
|
||||
url: '/detail/',
|
||||
reloadOnSearch: false,
|
||||
params: {
|
||||
tab: {value: 0, dynamic: true},
|
||||
},
|
||||
views: {
|
||||
'sidebarView@': {
|
||||
templateUrl: '/board.sidebarView.html',
|
||||
controller: 'BoardController'
|
||||
}
|
||||
}
|
||||
})
|
||||
.state('board.card', {
|
||||
url: '/card/:cardId',
|
||||
params: {
|
||||
tab: {value: 0, dynamic: true},
|
||||
},
|
||||
views: {
|
||||
'sidebarView@': {
|
||||
templateUrl: '/card.sidebarView.html',
|
||||
controller: 'CardController'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$provide.decorator('nvFileOverDirective', function ($delegate) {
|
||||
var directive = $delegate[0],
|
||||
link = directive.link;
|
||||
|
||||
directive.compile = function () {
|
||||
return function (scope, element, attrs) {
|
||||
var overClass = attrs.overClass || 'nv-file-over';
|
||||
link.apply(this, arguments);
|
||||
let counter = 0;
|
||||
element.on('dragenter', function (event) {
|
||||
counter++;
|
||||
});
|
||||
element.on('dragleave', function (event) {
|
||||
counter--;
|
||||
if (counter <= 0) {
|
||||
$('.' + overClass).removeClass(overClass);
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
return $delegate;
|
||||
});
|
||||
|
||||
});
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
import app from './App.js';
|
||||
|
||||
/* global Snap */
|
||||
app.run(function ($document, $rootScope, $transitions, BoardService) {
|
||||
'use strict';
|
||||
|
||||
$document.click(function (event) {
|
||||
$rootScope.$broadcast('documentClicked', event);
|
||||
});
|
||||
$transitions.onEnter({from: 'list'}, function ($state, $transition$) {
|
||||
BoardService.unsetCurrrent();
|
||||
});
|
||||
$transitions.onEnter({to: 'list'}, function ($state, $transition$) {
|
||||
BoardService.unsetCurrrent();
|
||||
document.title = "Deck - " + oc_defaults.name;
|
||||
});
|
||||
$transitions.onEnter({to: 'board.card'}, function ($state, $transition$) {
|
||||
$rootScope.sidebar.show = true;
|
||||
});
|
||||
$transitions.onEnter({to: 'board.detail'}, function ($state, $transition$) {
|
||||
$rootScope.sidebar.show = true;
|
||||
});
|
||||
$transitions.onEnter({to: 'board'}, function ($state) {
|
||||
$rootScope.sidebar.show = false;
|
||||
});
|
||||
$transitions.onExit({from: 'board.card'}, function ($state) {
|
||||
$rootScope.sidebar.show = false;
|
||||
});
|
||||
$transitions.onExit({from: 'board.detail'}, function ($state) {
|
||||
$rootScope.sidebar.show = false;
|
||||
});
|
||||
|
||||
$('link[rel="shortcut icon"]').attr(
|
||||
'href',
|
||||
OC.filePath('deck', 'img', 'app-512.png')
|
||||
);
|
||||
|
||||
// Select all elements with data-toggle="tooltips" in the document
|
||||
$('body').tooltip({
|
||||
selector: '[data-toggle="tooltip"]'
|
||||
});
|
||||
|
||||
});
|
||||
@@ -1,350 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2018 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/* global OC OCA OCP t escapeHTML Handlebars moment */
|
||||
|
||||
import CommentCollection from '../legacy/commentcollection';
|
||||
import CommentModel from '../legacy/commentmodel';
|
||||
|
||||
class ActivityController {
|
||||
constructor ($scope, CardService, ActivityService, BoardService) {
|
||||
'ngInject';
|
||||
this.cardservice = CardService;
|
||||
this.boardservice = BoardService;
|
||||
this.activityservice = ActivityService;
|
||||
this.$scope = $scope;
|
||||
this.type = '';
|
||||
this.loading = false;
|
||||
this.status = {
|
||||
commentCreateLoading: false
|
||||
};
|
||||
this.$scope.newComment = '';
|
||||
this.$scope.newCommentString = 'New comment…';
|
||||
|
||||
this.currentUser = OC.getCurrentUser();
|
||||
|
||||
const self = this;
|
||||
this.$scope.$watch(function () {
|
||||
return self.element.id;
|
||||
}, function (params) {
|
||||
if (self.type === 'deck_card') {
|
||||
self.activityservice.loadComments(self.element.id);
|
||||
}
|
||||
|
||||
if (self.getData(self.element.id).length === 0) {
|
||||
self.loading = true;
|
||||
self.fetchUntilResults();
|
||||
}
|
||||
self.activityservice.fetchNewerActivities(self.type, self.element.id).then(function () {});
|
||||
if (self.type === 'deck_card') {
|
||||
self.cardservice.getCurrent().commentsUnread = 0;
|
||||
}
|
||||
}, true);
|
||||
|
||||
let $target = $('.newCommentForm .message');
|
||||
this.applyAtWho($target);
|
||||
|
||||
this.activityservice.subscribe(this.$scope, function() {
|
||||
self.$scope.$apply();
|
||||
});
|
||||
|
||||
if (typeof OCA.Activity.Templates !== 'undefined') {
|
||||
OCA.Activity.Templates.userLocal = Handlebars.template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
|
||||
var helper;
|
||||
// Compiled handlesbars template
|
||||
// '<span class="avatar-name-wrapper"><avatar ng-attr-contactsmenu ng-attr-tooltip ng-attr-user="{{ id }}" ng-attr-displayname="{{name}}" ng-attr-size="16"></avatar> {{ name }}</span>';
|
||||
return "<span class=\"avatar-name-wrapper\"><avatar ng-attr-contactsmenu ng-attr-tooltip ng-attr-user=\""
|
||||
+ container.escapeExpression(((helper = (helper = helpers.id || (depth0 != null ? depth0.id : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : {},{"name":"id","hash":{},"data":data}) : helper)))
|
||||
+ "\" ng-attr-displayname=\""
|
||||
+ container.escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : {},{"name":"name","hash":{},"data":data}) : helper)))
|
||||
+ "\" ng-attr-size=\"16\"></avatar> "
|
||||
+ container.escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : {},{"name":"name","hash":{},"data":data}) : helper)))
|
||||
+ "</span>";
|
||||
},"useData":true});
|
||||
} else {
|
||||
OCA.Activity.RichObjectStringParser._userLocalTemplate = '<span class="avatar-name-wrapper"><avatar ng-attr-contactsmenu ng-attr-tooltip ng-attr-user="{{ id }}" ng-attr-displayname="{{name}}" ng-attr-size="16"></avatar> {{ name }}</span>';
|
||||
}
|
||||
}
|
||||
|
||||
applyAtWho($target) {
|
||||
const self = this;
|
||||
if (!$target) {
|
||||
return;
|
||||
}
|
||||
$target.atwho({
|
||||
at: '@',
|
||||
callbacks: {
|
||||
remoteFilter: function(query, callback) {
|
||||
let uids = self.boardservice.getUsers();
|
||||
uids = uids.filter((x) => x.uid.toLowerCase().includes(query.toLowerCase()) || x.displayname.toLowerCase().includes(query.toLowerCase()));
|
||||
callback(uids);
|
||||
},
|
||||
highlighter: function (li) {
|
||||
// misuse the highlighter callback to instead of
|
||||
// highlighting loads the avatars.
|
||||
var $li = $(li);
|
||||
$li.find('.avatar').avatar(undefined, 32);
|
||||
return $li;
|
||||
},
|
||||
sorter: function (q, items) { return items; }
|
||||
},
|
||||
displayTpl: function (item) {
|
||||
return '<li>' +
|
||||
'<span class="avatar-name-wrapper">' +
|
||||
'<span class="avatar" ' +
|
||||
'data-username="' + escapeHTML(item.uid) + '" ' + // for avatars
|
||||
'data-user="' + escapeHTML(item.uid) + '" ' + // for contactsmenu
|
||||
'data-user-display-name="' + escapeHTML(item.displayname) + '">' +
|
||||
'</span>' +
|
||||
'<strong>' + escapeHTML(item.displayname) + '</strong>' +
|
||||
'</span></li>';
|
||||
},
|
||||
insertTpl: function (item) {
|
||||
return '' +
|
||||
'<span class="avatar-name-wrapper">' +
|
||||
'<span class="avatar" ' +
|
||||
'data-username="' + escapeHTML(item.uid) + '" ' + // for avatars
|
||||
'data-user="' + escapeHTML(item.uid) + '" ' + // for contactsmenu
|
||||
'data-user-display-name="' + escapeHTML(item.displayname) + '">' +
|
||||
'</span>' +
|
||||
'<strong>' + escapeHTML(item.displayname) + '</strong>' +
|
||||
'</span>';
|
||||
},
|
||||
searchKey: 'displayname'
|
||||
});
|
||||
$target.on('inserted.atwho', function (je, $el) {
|
||||
$(je.target).find(
|
||||
'span[data-username="' + $el.find('[data-username]').data('username') + '"]'
|
||||
).avatar(undefined, 16);
|
||||
});
|
||||
$target.on('shown.atwho', function (je) {
|
||||
$target.find('.avatar').avatar(undefined, 16);
|
||||
});
|
||||
}
|
||||
|
||||
commentBodyToPlain(content) {
|
||||
let $comment = $('<div/>').html(content);
|
||||
$comment.find('.avatar-name-wrapper').each(function () {
|
||||
var $this = $(this);
|
||||
var $inserted = $this.parent();
|
||||
$inserted.html('@' + $this.find('.avatar').data('username'));
|
||||
});
|
||||
$comment.html(OCP.Comments.richToPlain($comment.html()));
|
||||
$comment.html($comment.html().replace(/<br\s*[\/]?>/gi, '\n'));
|
||||
return $comment.text();
|
||||
}
|
||||
|
||||
static _composeHTMLMention(uid, displayName) {
|
||||
var avatar = '' +
|
||||
'<span class="avatar" data-username="' + escapeHTML(uid) + '" data-user="' + escapeHTML(uid) + '" ng-attr-size="16" ' +
|
||||
'ng-attr-user="' + escapeHTML(uid) + '" ' +
|
||||
'ng-attr-displayname="' + escapeHTML(displayName) + '" ng-attr-contactsmenu="true">' +
|
||||
'</span>';
|
||||
|
||||
var isCurrentUser = (uid === OC.getCurrentUser().uid);
|
||||
|
||||
return '' +
|
||||
'<span class="atwho-inserted" contenteditable="false">' +
|
||||
'<span class="avatar-name-wrapper' + (isCurrentUser ? ' currentUser' : '') + '">' +
|
||||
avatar +
|
||||
'<strong>' + escapeHTML(displayName) + '</strong>' +
|
||||
'</span>' +
|
||||
'</span>';
|
||||
}
|
||||
|
||||
formatMessage(activity) {
|
||||
let message = activity.message;
|
||||
let mentions = activity.commentModel.get('mentions');
|
||||
const editMode = false;
|
||||
message = escapeHTML(message).replace(/\n/g, '<br/>');
|
||||
|
||||
for(var i in mentions) {
|
||||
if(!mentions.hasOwnProperty(i)) {
|
||||
return;
|
||||
}
|
||||
var mention = '@' + mentions[i].mentionId;
|
||||
// escape possible regex characters in the name
|
||||
mention = mention.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
|
||||
const displayName = ActivityController._composeHTMLMention(mentions[i].mentionId, mentions[i].mentionDisplayName);
|
||||
// replace every mention either at the start of the input or after a whitespace
|
||||
// followed by a non-word character.
|
||||
message = message.replace(new RegExp('(^|\\s)(' + mention + ')\\b', 'g'),
|
||||
function(match, p1) {
|
||||
// to get number of whitespaces (0 vs 1) right
|
||||
return p1+displayName;
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
if(editMode !== true) {
|
||||
message = OCP.Comments.plainToRich(message);
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
postComment() {
|
||||
const self = this;
|
||||
this.status.commentCreateLoading = true;
|
||||
|
||||
let content = this.commentBodyToPlain(self.$scope.newComment);
|
||||
if (content.length < 1) {
|
||||
self.status.commentCreateLoading = false;
|
||||
OC.Notification.showTemporary(t('deck', 'Please provide a content for your comment.'));
|
||||
return;
|
||||
}
|
||||
var model = this.activityservice.commentCollection.create({
|
||||
actorId: OC.getCurrentUser().uid,
|
||||
actorDisplayName: OC.getCurrentUser().displayName,
|
||||
actorType: 'users',
|
||||
verb: 'comment',
|
||||
message: content,
|
||||
creationDateTime: (new Date()).toUTCString()
|
||||
}, {
|
||||
at: 0,
|
||||
// wait for real creation before adding
|
||||
wait: true,
|
||||
success: function() {
|
||||
self.$scope.newComment = '';
|
||||
self.activityservice.fetchNewerActivities(self.type, self.element.id).then(function () {});
|
||||
self.status.commentCreateLoading = false;
|
||||
},
|
||||
error: function() {
|
||||
self.status.commentCreateLoading = false;
|
||||
OC.Notification.showTemporary(t('deck', 'Posting the comment failed.'));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
updateComment(item) {
|
||||
item.commentEdit = this.formatMessage(item);
|
||||
let $target = $('.newCommentForm .message');
|
||||
this.applyAtWho($target);
|
||||
/** Workaround to trigger avatar rendering after the view has been updated */
|
||||
window.setTimeout(function () {
|
||||
$target.find('.avatar').avatar(undefined, 16);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
editComment(item) {
|
||||
const self = this;
|
||||
let content = this.commentBodyToPlain(item.commentEdit);
|
||||
if (content.length < 1) {
|
||||
OC.Notification.showTemporary(t('deck', 'Please provide a content for your comment.'));
|
||||
return;
|
||||
}
|
||||
/** We need to save the model and afterwards run a fetch to update the mentions
|
||||
* and call apply to propagate the changes to angular
|
||||
*/
|
||||
item.commentModel.on('sync', function() {
|
||||
item.commentModel.off('sync');
|
||||
item.commentModel.fetch({
|
||||
success: function() {
|
||||
self.$scope.$apply();
|
||||
}
|
||||
});
|
||||
});
|
||||
item.commentModel.save({
|
||||
message: content,
|
||||
});
|
||||
item.message = content;
|
||||
item.commentEdit = undefined;
|
||||
}
|
||||
|
||||
deleteComment(item) {
|
||||
item.commentModel.destroy();
|
||||
item.deleted = true;
|
||||
item.commentModel = undefined;
|
||||
item.message = t('deck', 'The comment has been deleted');
|
||||
}
|
||||
|
||||
getData(id) {
|
||||
return this.activityservice.getData(this.type, id);
|
||||
}
|
||||
|
||||
parseMessage(activity) {
|
||||
let subject = activity.subject_rich[0];
|
||||
let parameters = activity.subject_rich[1];
|
||||
if (parameters.after && typeof parameters.after.id === 'string' && parameters.after.id.startsWith('dt:')) {
|
||||
let dateTime = parameters.after.id.substr(3);
|
||||
parameters.after.name = moment(dateTime).format('L LTS');
|
||||
}
|
||||
return OCA.Activity.RichObjectStringParser.parseMessage(subject, parameters);
|
||||
}
|
||||
|
||||
fetchUntilResults () {
|
||||
const self = this;
|
||||
let dataLengthBefore = self.getData(self.element.id).length;
|
||||
let _executeFetch = function() {
|
||||
let promise = self.activityservice.fetchMoreActivities(self.type, self.element.id);
|
||||
promise.then(function (data) {
|
||||
let dataLengthAfter = self.getData(self.element.id).length;
|
||||
if (data !== null && (dataLengthAfter <= dataLengthBefore || dataLengthAfter < self.activityservice.RESULT_PER_PAGE)) {
|
||||
_executeFetch();
|
||||
} else {
|
||||
self.loading = false;
|
||||
}
|
||||
}, function () {
|
||||
self.loading = false;
|
||||
self.$scope.$apply();
|
||||
});
|
||||
|
||||
};
|
||||
_executeFetch();
|
||||
}
|
||||
|
||||
getComments() {
|
||||
return this.activityservice.comments;
|
||||
}
|
||||
|
||||
getActivityStream() {
|
||||
let activities = this.activityservice.getData(this.type, this.element.id);
|
||||
return activities;
|
||||
}
|
||||
|
||||
page() {
|
||||
if (!this.activityservice.since[this.type][this.element.id].finished) {
|
||||
this.loading = true;
|
||||
this.fetchUntilResults();
|
||||
} else {
|
||||
this.loading = false;
|
||||
}
|
||||
}
|
||||
|
||||
loadingNewer() {
|
||||
return this.activityservice.runningNewer;
|
||||
}
|
||||
|
||||
t(text) {
|
||||
return t('deck', text);
|
||||
}
|
||||
}
|
||||
|
||||
let activityComponent = {
|
||||
templateUrl: OC.linkTo('deck', 'templates/part.card.activity.html'),
|
||||
controller: ActivityController,
|
||||
bindings: {
|
||||
type: '@',
|
||||
element: '='
|
||||
}
|
||||
};
|
||||
export default activityComponent;
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
import app from '../app/App.js';
|
||||
|
||||
/* globals oc_current_user: false */
|
||||
app.controller('AppController', function ($scope, $location, $http, $log, $rootScope, $attrs) {
|
||||
$rootScope.sidebar = {
|
||||
show: false
|
||||
};
|
||||
$scope.sidebar = $rootScope.sidebar;
|
||||
$scope.user = oc_current_user;
|
||||
$rootScope.config = JSON.parse($attrs.config);
|
||||
|
||||
$rootScope.compactMode = localStorage.getItem('deck.compactMode') === 'true';
|
||||
$scope.appNavigationHide = localStorage.getItem('deck.appNavigationHide') === 'true';
|
||||
|
||||
$scope.toggleSidebar = function() {
|
||||
if ($(window).width() > 768) {
|
||||
$log.debug($scope.appNavigationHide);
|
||||
$scope.appNavigationHide = !$scope.appNavigationHide;
|
||||
localStorage.setItem('deck.appNavigationHide', JSON.stringify($scope.appNavigationHide));
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2018 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/* global OC */
|
||||
|
||||
class AttachmentListController {
|
||||
constructor ($scope, CardService, FileService) {
|
||||
'ngInject';
|
||||
this.cardservice = CardService;
|
||||
this.fileservice = FileService;
|
||||
this.attachments = CardService.getCurrent().attachments;
|
||||
}
|
||||
|
||||
mimetypeForAttachment(attachment) {
|
||||
let url = OC.MimeType.getIconUrl(attachment.extendedData.mimetype);
|
||||
let styles = {
|
||||
'background-image': `url("${url}")`,
|
||||
};
|
||||
return styles;
|
||||
}
|
||||
|
||||
attachmentUrl(attachment) {
|
||||
let cardId = this.cardservice.getCurrent().id;
|
||||
let attachmentId = attachment.id;
|
||||
return OC.generateUrl(`/apps/deck/cards/${cardId}/attachment/${attachmentId}`);
|
||||
}
|
||||
|
||||
getAttachmentMarkdown(attachment) {
|
||||
const inlineMimetypes = ['image/png', 'image/jpg', 'image/jpeg'];
|
||||
let url = this.attachmentUrl(attachment);
|
||||
let filename = attachment.data;
|
||||
let insertText = `[📎 ${filename}](${url})`;
|
||||
if (inlineMimetypes.indexOf(attachment.extendedData.mimetype) > -1) {
|
||||
insertText = ``;
|
||||
}
|
||||
return insertText;
|
||||
}
|
||||
|
||||
select(attachment) {
|
||||
this.onSelect({attachment: this.getAttachmentMarkdown(attachment)});
|
||||
}
|
||||
|
||||
abort() {
|
||||
this.onAbort();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let attachmentListComponent = {
|
||||
templateUrl: '/card.attachments.html',
|
||||
controller: AttachmentListController,
|
||||
bindings: {
|
||||
isFileSelector: '<',
|
||||
attachments: '=',
|
||||
onSelect: '&',
|
||||
onAbort: '&'
|
||||
}
|
||||
};
|
||||
export default attachmentListComponent;
|
||||
@@ -1,568 +0,0 @@
|
||||
/*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
/* global oc_defaults oc_config OC OCP OCA t n */
|
||||
|
||||
import app from '../app/App.js';
|
||||
import Vue from 'vue';
|
||||
|
||||
Vue.prototype.t = t;
|
||||
Vue.prototype.n = n;
|
||||
Vue.prototype.OC = OC;
|
||||
|
||||
import CollaborationView from '../views/CollaborationView';
|
||||
|
||||
app.controller('BoardController', function ($rootScope, $scope, $element, $stateParams, StatusService, BoardService, StackService, CardService, LabelService, $state, $transitions, $filter, FileService) {
|
||||
|
||||
$scope.sidebar = $rootScope.sidebar;
|
||||
|
||||
$scope.id = $stateParams.boardId;
|
||||
$scope.status = {
|
||||
addCard: [],
|
||||
};
|
||||
$scope.newLabel = {};
|
||||
|
||||
$scope.OC = OC;
|
||||
$scope.stackservice = StackService;
|
||||
$scope.boardservice = BoardService;
|
||||
$scope.cardservice = CardService;
|
||||
$scope.statusservice = StatusService.getInstance();
|
||||
$scope.labelservice = LabelService;
|
||||
$scope.defaultColors = ['31CC7C', '317CCC', 'FF7A66', 'F1DB50', '7C31CC', 'CC317C', '3A3B3D', 'CACBCD'];
|
||||
$scope.board = BoardService.getCurrent();
|
||||
$scope.uploader = FileService.uploader;
|
||||
$scope.searchText = '';
|
||||
|
||||
$scope.startTitleEdit = function(card) {
|
||||
card.renameTitle = card.title;
|
||||
card.status = card.status || {};
|
||||
card.status.editCard = true;
|
||||
};
|
||||
|
||||
$scope.finishTitleEdit = function(card) {
|
||||
var newTitle;
|
||||
if (!card.renameTitle || !card.renameTitle.trim()) {
|
||||
newTitle = '';
|
||||
} else {
|
||||
newTitle = card.renameTitle.trim();
|
||||
}
|
||||
|
||||
if (newTitle === card.title) {
|
||||
// title unchanged
|
||||
card.status.editCard = false;
|
||||
delete card.renameTitle;
|
||||
} else if (newTitle !== '') {
|
||||
// title changed
|
||||
card.title = newTitle;
|
||||
CardService.update(card).then(function (data) {
|
||||
card.status.editCard = false;
|
||||
delete card.renameTitle;
|
||||
});
|
||||
} else {
|
||||
// empty title
|
||||
card.status.editCard = false;
|
||||
delete card.renameTitle;
|
||||
}
|
||||
};
|
||||
|
||||
$scope.$watch(function() {
|
||||
return $scope.params.tab;
|
||||
}, function (newTab, oldTab) {
|
||||
if (newTab === 2 && oldTab !== 2) {
|
||||
CardService.fetchDeleted($scope.id);
|
||||
StackService.fetchDeleted($scope.id);
|
||||
}
|
||||
});
|
||||
|
||||
// workaround for $stateParams changes not being propagated
|
||||
$scope.$watch(function() {
|
||||
return $state.params;
|
||||
}, function (params) {
|
||||
$scope.params = params;
|
||||
}, true);
|
||||
$scope.params = $state.params;
|
||||
|
||||
/**
|
||||
* Check for markdown checkboxes in description to render the counter
|
||||
*
|
||||
* This should probably be moved to the backend at some point
|
||||
*
|
||||
* @param text
|
||||
* @returns array of [finished, total] checkboxes
|
||||
*/
|
||||
$scope.getCheckboxes = function(text) {
|
||||
const regTotal = /\[(X|\s|\_|\-)\]/igm;
|
||||
const regFinished = /\[(X|\_|\-)\]/igm;
|
||||
return [
|
||||
((text || '').match(regFinished) || []).length,
|
||||
((text || '').match(regTotal) || []).length
|
||||
];
|
||||
};
|
||||
|
||||
$scope.search = function (searchText) {
|
||||
$scope.searchText = searchText;
|
||||
$scope.refreshData();
|
||||
};
|
||||
|
||||
$scope.$watch(function () {
|
||||
if (typeof BoardService.getCurrent() !== 'undefined') {
|
||||
return BoardService.getCurrent().title;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}, function () {
|
||||
$scope.setPageTitle();
|
||||
});
|
||||
$scope.setPageTitle = function () {
|
||||
if (BoardService.getCurrent()) {
|
||||
document.title = BoardService.getCurrent().title + ' | Deck - ' + oc_defaults.name;
|
||||
} else {
|
||||
document.title = 'Deck - ' + oc_defaults.name;
|
||||
}
|
||||
};
|
||||
|
||||
$scope.statusservice.retainWaiting();
|
||||
$scope.statusservice.retainWaiting();
|
||||
|
||||
// handle filter parameter for switching between archived/unarchived cards
|
||||
$scope.switchFilter = function (filter) {
|
||||
$state.go('.', {filter: filter});
|
||||
};
|
||||
$scope.$watch(function() {
|
||||
return $scope.params.filter;
|
||||
}, function (filter) {
|
||||
if (filter === 'archive') {
|
||||
$scope.loadArchived();
|
||||
} else {
|
||||
$scope.loadDefault();
|
||||
}
|
||||
});
|
||||
|
||||
if (parseInt(oc_config.version.split('.')[0]) >= 16) {
|
||||
const ComponentVM = new Vue({
|
||||
render: h => h(CollaborationView),
|
||||
data: {
|
||||
model: BoardService.getCurrent()
|
||||
},
|
||||
});
|
||||
$scope.mountCollections = function () {
|
||||
const MountingPoint = document.getElementById('collaborationResources');
|
||||
if (MountingPoint) {
|
||||
ComponentVM.model = BoardService.getCurrent();
|
||||
ComponentVM.$mount(MountingPoint);
|
||||
}
|
||||
};
|
||||
$scope.$$postDigest($scope.mountCollections);
|
||||
$scope.$watch(function () {
|
||||
return BoardService.getCurrent();
|
||||
}, function () {
|
||||
ComponentVM.model = BoardService.getCurrent();
|
||||
if ($scope.sidebar.show) {
|
||||
$scope.$$postDigest($scope.mountCollections);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$scope.toggleCompactMode = function() {
|
||||
$rootScope.compactMode = !$rootScope.compactMode;
|
||||
localStorage.setItem('deck.compactMode', JSON.stringify($rootScope.compactMode));
|
||||
};
|
||||
|
||||
$scope.stacksData = StackService;
|
||||
$scope.stacks = [];
|
||||
$scope.$watch('stacksData', function () {
|
||||
$scope.refreshData();
|
||||
}, true);
|
||||
$scope.refreshData = function () {
|
||||
if ($scope.params.filter === 'archive') {
|
||||
$scope.filterData('-lastModified', $scope.searchText);
|
||||
} else {
|
||||
$scope.filterData('order', $scope.searchText);
|
||||
}
|
||||
};
|
||||
$scope.checkCanEdit = function () {
|
||||
return !BoardService.getCurrent().archived;
|
||||
};
|
||||
|
||||
// filter cards here, as ng-sortable will not work nicely with html-inline filters
|
||||
$scope.filterData = function (order, text) {
|
||||
if ($scope.stacks === undefined) {
|
||||
return;
|
||||
}
|
||||
angular.copy(StackService.getData(), $scope.stacks);
|
||||
$scope.stacks = $filter('orderBy')($scope.stacks, 'order');
|
||||
angular.forEach($scope.stacks, function (value, key) {
|
||||
var cards = $filter('cardSearchFilter')(value.cards, text);
|
||||
cards = $filter('orderBy')(cards, order);
|
||||
$scope.stacks[key].cards = cards;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.loadDefault = function () {
|
||||
StackService.fetchAll($scope.id).then(function (data) {
|
||||
$scope.statusservice.releaseWaiting();
|
||||
}, function (error) {
|
||||
$scope.statusservice.setError('Error occured', error);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.loadArchived = function () {
|
||||
StackService.fetchArchived($scope.id).then(function (data) {
|
||||
$scope.statusservice.releaseWaiting();
|
||||
}, function (error) {
|
||||
$scope.statusservice.setError('Error occured', error);
|
||||
});
|
||||
};
|
||||
|
||||
// Handle initial Loading
|
||||
BoardService.fetchOne($scope.id).then(function (data) {
|
||||
$scope.statusservice.releaseWaiting();
|
||||
$scope.setPageTitle();
|
||||
}, function (error) {
|
||||
$scope.statusservice.setError('Error occured', error);
|
||||
});
|
||||
|
||||
$scope.searchForUser = function (search) {
|
||||
BoardService.searchUsers(search);
|
||||
};
|
||||
|
||||
$scope.newStack = {'boardId': $scope.id};
|
||||
$scope.newCard = {};
|
||||
|
||||
// Create a new Stack
|
||||
$scope.createStack = function () {
|
||||
StackService.create($scope.newStack).then(function (data) {
|
||||
$scope.newStack.title = '';
|
||||
});
|
||||
};
|
||||
|
||||
$scope.createCard = function (stack, title) {
|
||||
if (this['addCardForm' + stack].$valid) {
|
||||
var newCard = {
|
||||
'title': title,
|
||||
'stackId': stack,
|
||||
'type': 'plain'
|
||||
};
|
||||
CardService.create(newCard).then(function (data) {
|
||||
$scope.stackservice.addCard(data);
|
||||
$scope.newCard.title = '';
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
$scope.stackDelete = function (stack) {
|
||||
$scope.stackservice.delete(stack.id);
|
||||
};
|
||||
|
||||
$scope.stackUndoDelete = function (deletedStack) {
|
||||
return StackService.undoDelete(deletedStack);
|
||||
};
|
||||
|
||||
$scope.cardDelete = function (card) {
|
||||
CardService.delete(card.id).then(function () {
|
||||
StackService.removeCard(card);
|
||||
$scope.sidebar.show = false;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.cardOrCardAndStackUndoDelete = function (deletedCard) {
|
||||
var associatedDeletedStack = $scope.stackservice.deleted[deletedCard.stackId];
|
||||
if(associatedDeletedStack !== undefined) {
|
||||
$scope.cardAndStackUndoDeleteAskForConfirmation(deletedCard, associatedDeletedStack);
|
||||
} else {
|
||||
$scope.cardUndoDelete(deletedCard);
|
||||
}
|
||||
};
|
||||
|
||||
$scope.cardAndStackUndoDeleteAskForConfirmation = function(deletedCard, associatedDeletedStack) {
|
||||
OC.dialogs.confirm(
|
||||
t('deck', 'The associated stack is deleted as well, it will be restored as well.'),
|
||||
t('deck', 'Restore associated stack'),
|
||||
function(state) {
|
||||
if (state) {
|
||||
$scope.cardAndStackUndoDelete(deletedCard, associatedDeletedStack);
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
$scope.cardAndStackUndoDelete = function(deletedCard, associatedDeletedStack) {
|
||||
$scope.stackUndoDelete(associatedDeletedStack).then(function() {
|
||||
$scope.cardUndoDelete(deletedCard);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.cardUndoDelete = function(deletedCard) {
|
||||
CardService.undoDelete(deletedCard).then(function() {
|
||||
StackService.addCard(deletedCard);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.cardArchive = function (card) {
|
||||
CardService.archive(card);
|
||||
StackService.removeCard(card);
|
||||
};
|
||||
|
||||
$scope.isCurrentUserAssigned = function (card) {
|
||||
if (! CardService.get(card.id).assignedUsers) {
|
||||
return false;
|
||||
}
|
||||
var userList = CardService.get(card.id).assignedUsers.filter(function (obj) {
|
||||
return obj.participant.uid === OC.getCurrentUser().uid;
|
||||
});
|
||||
return userList.length === 1;
|
||||
};
|
||||
|
||||
$scope.cardAssignToMe = function (card) {
|
||||
CardService.assignUser(card, OC.getCurrentUser().uid)
|
||||
.then(
|
||||
function() {StackService.updateCard(card);}
|
||||
);
|
||||
// TODO: remove this jquery call. Fix and use appPopoverMenuUtils instead
|
||||
$('.popovermenu').addClass('hidden');
|
||||
};
|
||||
|
||||
$scope.cardUnassignFromMe = function (card) {
|
||||
CardService.unassignUser(card, OC.getCurrentUser().uid);
|
||||
StackService.updateCard(card);
|
||||
// TODO: remove this jquery call.Fix and use appPopoverMenuUtils instead
|
||||
$('.popovermenu').addClass('hidden');
|
||||
};
|
||||
$scope.cardUnarchive = function (card) {
|
||||
CardService.unarchive(card);
|
||||
StackService.removeCard(card);
|
||||
};
|
||||
|
||||
$scope.labelDelete = function (label) {
|
||||
LabelService.delete(label.id);
|
||||
// remove from board data
|
||||
var i = BoardService.getCurrent().labels.indexOf(label);
|
||||
BoardService.getCurrent().labels.splice(i, 1);
|
||||
|
||||
// remove from cards
|
||||
var cards = CardService.data;
|
||||
for (var card in cards) {
|
||||
if (Object.prototype.hasOwnProperty.call(cards, card)) {
|
||||
var labelsFromCard = cards[card].labels;
|
||||
|
||||
labelsFromCard.forEach(function (labelFromCard, index) {
|
||||
if (labelFromCard.id === label.id) {
|
||||
cards[card].labels.splice(index, 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$scope.labelCreate = function (label) {
|
||||
label.boardId = $scope.id;
|
||||
LabelService.create(label).then(function (data) {
|
||||
$scope.newStack.title = '';
|
||||
BoardService.getCurrent().labels.push(data);
|
||||
$scope.status.createLabel = false;
|
||||
$scope.newLabel = {};
|
||||
}).catch((err) => {
|
||||
OC.Notification.showTemporary(err);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.labelUpdateBefore = function (label) {
|
||||
label.renameTitle = label.title;
|
||||
};
|
||||
|
||||
$scope.labelUpdate = function (label) {
|
||||
label.edit = false;
|
||||
LabelService.update(label).catch((err) => {
|
||||
label.title = label.renameTitle;
|
||||
OC.Notification.showTemporary(err);
|
||||
});
|
||||
|
||||
// update labels in UI
|
||||
var cards = CardService.data;
|
||||
for (var card in cards) {
|
||||
if (Object.prototype.hasOwnProperty.call(cards, card)) {
|
||||
var labelsFromCard = cards[card].labels;
|
||||
|
||||
labelsFromCard.forEach(function (labelFromCard, index) {
|
||||
if (labelFromCard.id === label.id) {
|
||||
cards[card].labels[index] = label;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$scope.aclAdd = function (sharee) {
|
||||
sharee.boardId = $scope.id;
|
||||
BoardService.addAcl(sharee);
|
||||
$scope.status.addSharee = null;
|
||||
};
|
||||
|
||||
$scope.aclDelete = function (acl) {
|
||||
BoardService.deleteAcl(acl).then(function(data) {
|
||||
$scope.loadDefault();
|
||||
$scope.refreshData();
|
||||
});
|
||||
};
|
||||
|
||||
$scope.aclUpdate = function (acl) {
|
||||
BoardService.updateAcl(acl);
|
||||
};
|
||||
|
||||
$scope.aclTypeString = function (acl) {
|
||||
if (typeof acl === 'undefined') {
|
||||
return '';
|
||||
}
|
||||
switch (acl.type) {
|
||||
case OC.Share.SHARE_TYPE_USER:
|
||||
return 'user';
|
||||
case OC.Share.SHARE_TYPE_GROUP:
|
||||
return 'group';
|
||||
case OC.Share.SHARE_TYPE_CIRCLE:
|
||||
return 'circles';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
// settings for card sorting
|
||||
$scope.sortOptions = {
|
||||
id: 'card',
|
||||
itemMoved: function (event) {
|
||||
event.source.itemScope.modelValue.status = event.dest.sortableScope.$parent.column;
|
||||
var order = event.dest.index;
|
||||
var card = $scope.cardservice.get(event.source.itemScope.c.id);
|
||||
var newStack = event.dest.sortableScope.$parent.s.id;
|
||||
var oldStack = card.stackId;
|
||||
card.stackId = newStack;
|
||||
CardService.update(card);
|
||||
CardService.reorder(card, order).then(function (data) {
|
||||
StackService.addCard(card);
|
||||
StackService.reorderCard(card, order);
|
||||
StackService.removeCard({
|
||||
id: card.id,
|
||||
stackId: oldStack
|
||||
});
|
||||
});
|
||||
},
|
||||
orderChanged: function (event) {
|
||||
var order = event.dest.index;
|
||||
var card = $scope.cardservice.get(event.source.itemScope.c.id);
|
||||
var stack = event.dest.sortableScope.$parent.s.id;
|
||||
CardService.reorder(card, order).then(function (data) {
|
||||
StackService.reorderCard(card, order);
|
||||
$scope.refreshData();
|
||||
});
|
||||
},
|
||||
scrollableContainer: '#innerBoard',
|
||||
containerPositioning: 'relative',
|
||||
containment: '#innerBoard',
|
||||
longTouch: true,
|
||||
// auto scroll on drag
|
||||
dragMove: function (itemPosition, containment, eventObj) {
|
||||
if (eventObj) {
|
||||
var container = $('#board');
|
||||
var offset = container.offset();
|
||||
var targetX = eventObj.pageX - (offset.left || container.scrollLeft());
|
||||
var targetY = eventObj.pageY - (offset.top || container.scrollTop());
|
||||
if (targetX < offset.left) {
|
||||
container.scrollLeft(container.scrollLeft() - 25);
|
||||
} else if (targetX > container.width()) {
|
||||
container.scrollLeft(container.scrollLeft() + 25);
|
||||
}
|
||||
if (targetY < offset.top) {
|
||||
container.scrollTop(container.scrollTop() - 25);
|
||||
} else if (targetY > container.height()) {
|
||||
container.scrollTop(container.scrollTop() + 25);
|
||||
}
|
||||
}
|
||||
},
|
||||
accept: function (sourceItemHandleScope, destSortableScope, destItemScope) {
|
||||
return sourceItemHandleScope.sortableScope.options.id === 'card';
|
||||
}
|
||||
};
|
||||
|
||||
$scope.sortOptionsStack = {
|
||||
id: 'stack',
|
||||
orderChanged: function (event) {
|
||||
var order = event.dest.index;
|
||||
var stack = event.source.itemScope.s;
|
||||
StackService.reorder(stack, order).then(function (data) {
|
||||
$scope.refreshData();
|
||||
});
|
||||
},
|
||||
scrollableContainer: '#board',
|
||||
containerPositioning: 'relative',
|
||||
containment: '#innerBoard',
|
||||
dragMove: function (itemPosition, containment, eventObj) {
|
||||
if (eventObj) {
|
||||
var container = $('#board');
|
||||
var offset = container.offset();
|
||||
var targetX = eventObj.pageX - (offset.left || container.scrollLeft());
|
||||
var targetY = eventObj.pageY - (offset.top || container.scrollTop());
|
||||
if (targetX < offset.left) {
|
||||
container.scrollLeft(container.scrollLeft() - 50);
|
||||
} else if (targetX > container.width()) {
|
||||
container.scrollLeft(container.scrollLeft() + 50);
|
||||
}
|
||||
if (targetY < offset.top) {
|
||||
container.scrollTop(container.scrollTop() - 50);
|
||||
} else if (targetY > container.height()) {
|
||||
container.scrollTop(container.scrollTop() + 50);
|
||||
}
|
||||
}
|
||||
},
|
||||
accept: function (sourceItemHandleScope, destSortableScope, destItemScope) {
|
||||
return sourceItemHandleScope.sortableScope.options.id === 'stack';
|
||||
}
|
||||
};
|
||||
|
||||
$scope.labelStyle = function (color) {
|
||||
return {
|
||||
'background-color': '#' + color,
|
||||
'color': $filter('textColorFilter')(color)
|
||||
};
|
||||
};
|
||||
|
||||
$scope.colorValue = function(color) {
|
||||
const re = /^#([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/;
|
||||
if (re.test(color)) {
|
||||
return color;
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
$scope.attachmentCount = function(card) {
|
||||
if (Array.isArray(card.attachments)) {
|
||||
return card.attachments.filter((obj) => obj.deletedAt === 0).length;
|
||||
}
|
||||
return card.attachmentCount;
|
||||
};
|
||||
|
||||
$scope.unreadCommentCount = function(card) {
|
||||
return card.commentsUnread;
|
||||
};
|
||||
|
||||
$scope.isTimelineEnabled = function() {
|
||||
return OCP.Comments && OCA.Activity;
|
||||
};
|
||||
|
||||
});
|
||||
@@ -1,286 +0,0 @@
|
||||
/*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/* global app moment angular OC OCP OCA */
|
||||
import app from '../app/App.js';
|
||||
|
||||
app.controller('CardController', function ($scope, $rootScope, $sce, $location, $stateParams, $state, $interval, $timeout, $filter, BoardService, CardService, StackService, StatusService, markdownItConverter, FileService) {
|
||||
$scope.sidebar = $rootScope.sidebar;
|
||||
$scope.status = {
|
||||
renameTitle: '',
|
||||
lastEdit: 0,
|
||||
lastSave: Date.now()
|
||||
};
|
||||
|
||||
$scope.cardservice = CardService;
|
||||
$scope.fileservice = FileService;
|
||||
$scope.cardId = $stateParams.cardId;
|
||||
|
||||
$scope.statusservice = StatusService.getInstance();
|
||||
$scope.boardservice = BoardService;
|
||||
|
||||
$scope.isArray = angular.isArray;
|
||||
// workaround for $stateParams changes not being propagated
|
||||
$scope.$watch(function() {
|
||||
return $state.params;
|
||||
}, function (params) {
|
||||
$scope.params = params;
|
||||
$scope.fileservice.reset();
|
||||
}, true);
|
||||
$scope.params = $state.params;
|
||||
|
||||
$scope.addAttachmentToDescription = function(insertText) {
|
||||
let el = document.querySelectorAll('textarea')[0];
|
||||
let start = el.selectionStart;
|
||||
let end = el.selectionEnd;
|
||||
let text = $scope.status.edit.description || '';
|
||||
let before = text.substring(0, start);
|
||||
let after = text.substring(end, text.length);
|
||||
let newText = before + '\n' + insertText + '\n' + after;
|
||||
$scope.status.edit.description = newText;
|
||||
el.selectionStart = el.selectionEnd = start + newText.length;
|
||||
el.focus();
|
||||
$scope.status.continueEdit = false;
|
||||
$scope.cardEditDescriptionChanged();
|
||||
$scope.status.selectAttachment = false;
|
||||
};
|
||||
|
||||
$scope.abortAttachmentSelection = function() {
|
||||
$scope.status.continueEdit = false;
|
||||
$scope.status.selectAttachment = false;
|
||||
let el = document.querySelectorAll('textarea')[0];
|
||||
el.focus();
|
||||
};
|
||||
|
||||
$scope.statusservice.retainWaiting();
|
||||
|
||||
$scope.description = function() {
|
||||
return $scope.rendered;
|
||||
};
|
||||
|
||||
$scope.updateMarkdown = function(content) {
|
||||
// only trust the html from markdown-it-checkbox
|
||||
$scope.rendered = $sce.trustAsHtml(markdownItConverter.render(content || ''));
|
||||
};
|
||||
|
||||
CardService.fetchOne($scope.cardId).then(function (data) {
|
||||
$scope.statusservice.releaseWaiting();
|
||||
$scope.archived = CardService.getCurrent().archived;
|
||||
$scope.updateMarkdown(CardService.getCurrent().description);
|
||||
}, function (error) {
|
||||
});
|
||||
|
||||
$scope.cardRenameShow = function () {
|
||||
if ($scope.archived || !BoardService.canEdit()) {
|
||||
return false;
|
||||
} else {
|
||||
$scope.status.renameTitle = CardService.getCurrent().title;
|
||||
$scope.status.cardRename = true;
|
||||
}
|
||||
};
|
||||
|
||||
$scope.toggleCheckbox = function (id) {
|
||||
$('#markdown input[type=checkbox]').attr('disabled', true);
|
||||
$scope.status.edit = angular.copy(CardService.getCurrent());
|
||||
var reg = /\[(X|\s|\_|\-)\]/ig;
|
||||
var nth = 0;
|
||||
$scope.status.edit.description = $scope.status.edit.description.replace(reg, function (match, i, original) {
|
||||
var result = match;
|
||||
if ('' + nth++ === '' + id) {
|
||||
if (match.match(/^\[\s\]/i)) {
|
||||
result = match.replace(/\[\s\]/i, '[x]');
|
||||
}
|
||||
if (match.match(/^\[x\]/i)) {
|
||||
result = match.replace(/\[x\]/i, '[ ]');
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return match;
|
||||
});
|
||||
CardService.update($scope.status.edit).then(function (data) {
|
||||
var header = $('.tabDetails');
|
||||
header.find('.save-indicator.unsaved').hide();
|
||||
header.find('.save-indicator.saved').fadeIn(250).fadeOut(1000);
|
||||
});
|
||||
$('#markdown input[type=checkbox]').removeAttr('disabled');
|
||||
|
||||
};
|
||||
$scope.clickCardDescription = function ($event) {
|
||||
var checkboxId = $($event.target).data('id');
|
||||
if ($event.target.tagName === 'LABEL') {
|
||||
$scope.toggleCheckbox(checkboxId);
|
||||
$event.stopPropagation();
|
||||
return false;
|
||||
}
|
||||
if ($event.target.tagName === 'INPUT') {
|
||||
$event.stopPropagation();
|
||||
return;
|
||||
}
|
||||
if (BoardService.isArchived() || CardService.getCurrent().archived) {
|
||||
return false;
|
||||
}
|
||||
if ($scope.card.archived || !$scope.boardservice.canEdit()) {
|
||||
return false;
|
||||
}
|
||||
$scope.status.cardEditDescription = true;
|
||||
$scope.status.edit = angular.copy(CardService.getCurrent());
|
||||
return true;
|
||||
};
|
||||
$scope.cardEditDescriptionChanged = function ($event) {
|
||||
$scope.status.lastEdit = Date.now();
|
||||
var header = $('.tabDetails');
|
||||
header.find('.save-indicator.unsaved').show();
|
||||
header.find('.save-indicator.saved').hide();
|
||||
};
|
||||
$interval(function() {
|
||||
var currentTime = Date.now();
|
||||
var timeSinceEdit = currentTime-$scope.status.lastEdit;
|
||||
if (timeSinceEdit > 1000 && $scope.status.lastEdit > $scope.status.lastSave && !$scope.status.saving) {
|
||||
$scope.status.lastSave = currentTime;
|
||||
$scope.status.saving = true;
|
||||
var header = $('.tabDetails');
|
||||
header.find('.save-indicator.unsaved').fadeIn(500);
|
||||
CardService.update($scope.status.edit).then(function (data) {
|
||||
var header = $('.tabDetails');
|
||||
header.find('.save-indicator.unsaved').hide();
|
||||
header.find('.save-indicator.saved').fadeIn(250).fadeOut(1000);
|
||||
$scope.status.saving = false;
|
||||
});
|
||||
}
|
||||
}, 500, 0, false);
|
||||
|
||||
// handle rename to update information on the board as well
|
||||
$scope.cardRename = function (card) {
|
||||
var newTitle;
|
||||
if (!$scope.status.renameTitle || !$scope.status.renameTitle.trim()) {
|
||||
newTitle = '';
|
||||
} else {
|
||||
newTitle = $scope.status.renameTitle.trim();
|
||||
}
|
||||
|
||||
if (newTitle === card.title) {
|
||||
// title unchanged
|
||||
$scope.status.renameCard = false;
|
||||
} else if (newTitle !== '') {
|
||||
// title changed
|
||||
card.title = newTitle;
|
||||
CardService.rename(card).then(function (data) {
|
||||
$scope.status.renameCard = false;
|
||||
});
|
||||
} else {
|
||||
// empty title
|
||||
$scope.status.renameTitle = card.title;
|
||||
$scope.status.renameCard = false;
|
||||
}
|
||||
};
|
||||
$scope.cardUpdate = function (card) {
|
||||
CardService.update(card).then(function (data) {
|
||||
$scope.status.cardEditDescription = false;
|
||||
$scope.updateMarkdown($scope.status.edit.description);
|
||||
var header = $('.tabDetails');
|
||||
header.find('.save-indicator.unsaved').hide();
|
||||
header.find('.save-indicator.saved').fadeIn(500).fadeOut(1000);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.labelAssign = function (element, model) {
|
||||
CardService.assignLabel($scope.cardId, element.id).then(function (data) {
|
||||
});
|
||||
};
|
||||
|
||||
$scope.labelRemove = function (element, model) {
|
||||
CardService.removeLabel($scope.cardId, element.id).then(function (data) {
|
||||
});
|
||||
};
|
||||
|
||||
$scope.setDuedate = function (duedate) {
|
||||
var element = CardService.getCurrent();
|
||||
var newDate = moment(element.duedate);
|
||||
if(!newDate.isValid()) {
|
||||
newDate = moment();
|
||||
}
|
||||
newDate.date(duedate.date());
|
||||
newDate.month(duedate.month());
|
||||
newDate.year(duedate.year());
|
||||
element.duedate = newDate.toISOString();
|
||||
CardService.update(element);
|
||||
};
|
||||
$scope.setDuedateTime = function (time) {
|
||||
var element = CardService.getCurrent();
|
||||
var newDate = moment(element.duedate);
|
||||
if(!newDate.isValid()) {
|
||||
newDate = moment();
|
||||
}
|
||||
newDate.hour(time.hour());
|
||||
newDate.minute(time.minute());
|
||||
element.duedate = newDate.toISOString();
|
||||
CardService.update(element);
|
||||
};
|
||||
|
||||
$scope.resetDuedate = function () {
|
||||
var element = CardService.getCurrent();
|
||||
element.duedate = null;
|
||||
CardService.update(element);
|
||||
};
|
||||
|
||||
/**
|
||||
* Show ui-select field when clicking the add button
|
||||
*/
|
||||
$scope.toggleAssignUser = function() {
|
||||
$scope.status.showAssignUser = !$scope.status.showAssignUser;
|
||||
if ($scope.status.showAssignUser === true) {
|
||||
$timeout(function () {
|
||||
$('#assignUserSelect').find('a').click();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide ui-select when select list is closed
|
||||
*/
|
||||
$scope.assingUserOpenClose = function(isOpen) {
|
||||
$scope.status.showAssignUser = isOpen;
|
||||
};
|
||||
|
||||
$scope.addAssignedUser = function(item) {
|
||||
CardService.assignUser(CardService.getCurrent(), item.uid).then(function (data) {
|
||||
});
|
||||
$scope.status.showAssignUser = false;
|
||||
};
|
||||
|
||||
$scope.removeAssignedUser = function(uid) {
|
||||
CardService.unassignUser(CardService.getCurrent(), uid).then(function (data) {
|
||||
});
|
||||
};
|
||||
|
||||
$scope.labelStyle = function (color) {
|
||||
return {
|
||||
'background-color': '#' + color,
|
||||
'color': $filter('textColorFilter')(color)
|
||||
};
|
||||
};
|
||||
|
||||
$scope.isTimelineEnabled = function() {
|
||||
return OCP.Comments && OCA.Activity;
|
||||
};
|
||||
|
||||
});
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2018 Oskar Kurz <oskar.kurz@gmail.com>
|
||||
*
|
||||
* @author Oskar Kurz <oskar.kurz@gmail.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
import app from '../app/App.js';
|
||||
|
||||
/* global oc_defaults OC */
|
||||
app.controller('ColorPickerController', ['$scope', function ($scope) {
|
||||
$scope.hashedColor = '';
|
||||
|
||||
$scope.setColor = function (object, color) {
|
||||
object.color = color;
|
||||
object.hashedColor = '#' + color;
|
||||
|
||||
return object;
|
||||
};
|
||||
|
||||
$scope.setHashedColor = function (object) {
|
||||
object.color = object.hashedColor.substr(1);
|
||||
return object;
|
||||
};
|
||||
|
||||
$scope.getCustomBackground = function (color) {
|
||||
return {'background-color': color};
|
||||
};
|
||||
}]);
|
||||
@@ -1,255 +0,0 @@
|
||||
/*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/* global app angular oc_isadmin */
|
||||
|
||||
var ListController = function ($scope, $location, $filter, BoardService, $element, $timeout, $stateParams, $state, StatusService, $http, $q, $rootScope) {
|
||||
|
||||
function calculateNewColor() {
|
||||
var boards = BoardService.getAll();
|
||||
var boardKeys = Object.keys(boards);
|
||||
var colorOccurrences = [];
|
||||
|
||||
for (var i = 0; i < $scope.colors.length; i++) {
|
||||
colorOccurrences.push(0);
|
||||
}
|
||||
|
||||
for (var j = 0; j < boardKeys.length; j++) {
|
||||
var key = boardKeys[j];
|
||||
var board = boards[key];
|
||||
|
||||
if (board && $scope.colors.indexOf(board.color) !== -1) {
|
||||
colorOccurrences[$scope.colors.indexOf(board.color)]++;
|
||||
}
|
||||
}
|
||||
|
||||
return $scope.colors[colorOccurrences.indexOf(Math.min.apply(Math, colorOccurrences))];
|
||||
}
|
||||
|
||||
$scope.boards = [];
|
||||
$scope.newBoard = {};
|
||||
$scope.status = {
|
||||
deleteUndo: [],
|
||||
filter: $stateParams.filter ? $stateParams.filter : '',
|
||||
sidebar: false
|
||||
};
|
||||
$scope.colors = ['0082c9', '00c9c6','00c906', 'c92b00', 'F1DB50', '7C31CC', '3A3B3D', 'CACBCD'];
|
||||
$scope.boardservice = BoardService;
|
||||
$scope.updatingBoard = null;
|
||||
$scope.isAdmin = oc_isadmin;
|
||||
$scope.canCreate = $rootScope.config.canCreate;
|
||||
|
||||
if ($scope.isAdmin) {
|
||||
OC.Apps.enableDynamicSlideToggle();
|
||||
$scope.groups = [];
|
||||
$scope.groupLimit = [];
|
||||
$scope.groupLimitDisabled = true;
|
||||
let fetchGroups = function () {
|
||||
var deferred = $q.defer();
|
||||
// TODO: move to groups/details once 15 is min version
|
||||
$http.get(OC.linkToOCS('cloud', 2) + 'groups').then(function (response) {
|
||||
$scope.groups = response.data.ocs.data.groups.reduce((obj, item) => {
|
||||
obj.push({
|
||||
id: item,
|
||||
displayname: item,
|
||||
});
|
||||
return obj;
|
||||
}, []);
|
||||
deferred.resolve($scope.groups);
|
||||
}, function (error) {
|
||||
deferred.reject('Error while loading groups');
|
||||
});
|
||||
$http.get(OC.generateUrl('apps/deck/config')).then(function (response) {
|
||||
$scope.groupLimit = response.data.groupLimit;
|
||||
$scope.groupLimitDisabled = false;
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Error while loading groupLimit');
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
let updateConfig = function() {
|
||||
$scope.groupLimitDisabled = true;
|
||||
var deferred = $q.defer();
|
||||
$http.post(OC.generateUrl('apps/deck/config/groupLimit'), {value: $scope.groupLimit}).then(function (response) {
|
||||
$scope.groupLimitDisabled = false;
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Error while saving groupLimit');
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
$scope.groupLimitAdd = function (element, model) {
|
||||
$scope.groupLimit.push(element);
|
||||
updateConfig();
|
||||
};
|
||||
$scope.groupLimitRemove = function (element, model) {
|
||||
$scope.groupLimit = $scope.groupLimit.filter((el) => {
|
||||
return el.id !== element.id;
|
||||
});
|
||||
updateConfig();
|
||||
};
|
||||
fetchGroups();
|
||||
}
|
||||
|
||||
var filterData = function () {
|
||||
if($element.attr('id') === 'app-navigation') {
|
||||
$scope.boardservice.sidebar = $scope.boardservice.getData();
|
||||
$scope.boardservice.sidebar = $filter('orderBy')($scope.boardservice.sidebar, 'title');
|
||||
$scope.boardservice.sidebar = $filter('cardFilter')($scope.boardservice.sidebar, {archived: false});
|
||||
} else {
|
||||
$scope.boardservice.sorted = $scope.boardservice.getData();
|
||||
if ($scope.status.filter === 'archived') {
|
||||
var filter = {};
|
||||
filter[$scope.status.filter] = true;
|
||||
$scope.boardservice.sorted = $filter('cardFilter')($scope.boardservice.sorted, filter);
|
||||
} else if ($scope.status.filter === 'shared') {
|
||||
$scope.boardservice.sorted = $filter('cardFilter')($scope.boardservice.sorted, {archived: false});
|
||||
$scope.boardservice.sorted = $filter('boardFilterAcl')($scope.boardservice.sorted);
|
||||
} else {
|
||||
$scope.boardservice.sorted = $filter('cardFilter')($scope.boardservice.sorted, {archived: false});
|
||||
}
|
||||
$scope.boardservice.sorted = $filter('orderBy')($scope.boardservice.sorted, ['deletedAt', 'title']);
|
||||
}
|
||||
};
|
||||
|
||||
var finishedLoading = function() {
|
||||
filterData();
|
||||
$scope.newBoard.color = calculateNewColor();
|
||||
};
|
||||
|
||||
var initialize = function () {
|
||||
$scope.statusservice = StatusService.listStatus;
|
||||
|
||||
if($element.attr('id') === 'app-navigation') {
|
||||
$scope.statusservice.retainWaiting();
|
||||
BoardService.fetchAll().then(function(data) {
|
||||
finishedLoading();
|
||||
$scope.statusservice.releaseWaiting();
|
||||
BoardService.loaded = true;
|
||||
}, function (error) {
|
||||
$scope.statusservice.setError('Error occured', error);
|
||||
});
|
||||
} else {
|
||||
/* initialize main list controller when board list is loaded */
|
||||
var boardDataWatch = $scope.$watch(function () {
|
||||
return $scope.boardservice.loaded;
|
||||
}, function () {
|
||||
if (BoardService.loaded === true) {
|
||||
boardDataWatch();
|
||||
finishedLoading();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$scope.$watch(function () {
|
||||
return $scope.boardservice.data;
|
||||
}, function () {
|
||||
filterData();
|
||||
}, true);
|
||||
|
||||
/* Watch for board filter change */
|
||||
$scope.$watchCollection(function(){
|
||||
return $state.params;
|
||||
}, function(){
|
||||
$scope.status.filter = $state.params.filter;
|
||||
filterData();
|
||||
});
|
||||
};
|
||||
initialize();
|
||||
|
||||
$scope.selectColor = function(color) {
|
||||
$scope.newBoard.color = color;
|
||||
};
|
||||
|
||||
$scope.gotoBoard = function(board) {
|
||||
if(board.deletedAt > 0) {
|
||||
return false;
|
||||
}
|
||||
return $state.go('board', {boardId: board.id});
|
||||
};
|
||||
|
||||
$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 = calculateNewColor();
|
||||
$scope.status.addBoard=false;
|
||||
filterData();
|
||||
}, function(error) {
|
||||
$scope.status.createBoard = 'Unable to insert board: ' + error.message;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.boardUpdate = function(board) {
|
||||
BoardService.update(board).then(function(data) {
|
||||
board.status.edit = false;
|
||||
filterData();
|
||||
});
|
||||
};
|
||||
|
||||
$scope.boardUpdateBegin = function(board) {
|
||||
$scope.updatingBoard = angular.copy(board);
|
||||
};
|
||||
|
||||
$scope.boardUpdateReset = function(board) {
|
||||
board.title = $scope.updatingBoard.title;
|
||||
board.color = $scope.updatingBoard.color;
|
||||
filterData();
|
||||
board.status.edit = false;
|
||||
};
|
||||
|
||||
$scope.boardArchive = function (board) {
|
||||
board.archived = true;
|
||||
BoardService.update(board).then(function(data) {
|
||||
filterData();
|
||||
});
|
||||
};
|
||||
|
||||
$scope.boardUnarchive = function (board) {
|
||||
board.archived = false;
|
||||
BoardService.update(board).then(function(data) {
|
||||
filterData();
|
||||
});
|
||||
};
|
||||
|
||||
$scope.boardDelete = function(board) {
|
||||
BoardService.delete(board.id).then(function (data) {
|
||||
filterData();
|
||||
});
|
||||
};
|
||||
|
||||
$scope.boardDeleteUndo = function (board) {
|
||||
BoardService.deleteUndo(board.id).then(function (data) {
|
||||
filterData();
|
||||
});
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
export default ListController;
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
app.directive('appPopoverMenuUtils', function () {
|
||||
'use strict';
|
||||
return {
|
||||
restrict: 'C',
|
||||
link: function (scope, elm) {
|
||||
var menu = elm.find('.popovermenu');
|
||||
var button = elm.find('button');
|
||||
button.click(function (e) {
|
||||
var popovermenus = $('.popovermenu');
|
||||
var shouldShow = menu.hasClass('hidden');
|
||||
popovermenus.addClass('hidden');
|
||||
if (shouldShow) {
|
||||
menu.toggleClass('hidden');
|
||||
}
|
||||
e.stopPropagation();
|
||||
});
|
||||
scope.$on('documentClicked', function (scope, event) {
|
||||
/* prevent closing popover if target has no-close class */
|
||||
if (event.target !== button && !$(event.target).hasClass('no-close')) {
|
||||
menu.addClass('hidden');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
app.directive('autofocusOnInsert', function () {
|
||||
'use strict';
|
||||
return function (scope, elm) {
|
||||
elm.focus();
|
||||
};
|
||||
});
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
app.directive('avatar', function() {
|
||||
'use strict';
|
||||
return {
|
||||
restrict: 'AEC',
|
||||
transclude: true,
|
||||
replace: true,
|
||||
template: '<div class="avatardiv-container"><div class="avatardiv" data-toggle="tooltip" ng-transclude></div></div>',
|
||||
scope: { attr: '=' },
|
||||
link: function(scope, element, attr){
|
||||
scope.uid = attr.displayname;
|
||||
scope.displayname = attr.displayname;
|
||||
scope.size = attr.size;
|
||||
if (typeof scope.size === 'undefined') {
|
||||
scope.size = 32;
|
||||
}
|
||||
var value = attr.user;
|
||||
var avatardiv = $(element).find('.avatardiv');
|
||||
if(typeof attr.contactsmenu !== 'undefined' && attr.contactsmenu !== 'false') {
|
||||
avatardiv.contactsMenu(value, 0, $(element));
|
||||
avatardiv.addClass('has-contactsmenu');
|
||||
}
|
||||
if(typeof attr.tooltip !== 'undefined' && attr.tooltip !== 'false') {
|
||||
$(element).tooltip({
|
||||
title: scope.displayname,
|
||||
placement: 'top'
|
||||
});
|
||||
}
|
||||
avatardiv.avatar(value, scope.size, false, false, false, attr.displayname);
|
||||
},
|
||||
controller: function () {}
|
||||
};
|
||||
});
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2018 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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
app.directive('contactsmenudelete', function() {
|
||||
'use strict';
|
||||
return {
|
||||
restrict: 'A',
|
||||
priority: 1,
|
||||
link: function(scope, element, attr){
|
||||
var user = attr.user;
|
||||
var menu = $(element).parent().find('.contactsmenu-popover');
|
||||
if (oc_current_user === user) {
|
||||
menu.children(':first').remove();
|
||||
}
|
||||
var menuEntry = $('<li><a><span class="icon icon-delete"></span><span>' + t('deck', 'Remove user from card') + '</span></a></li>');
|
||||
menuEntry.on('click', function () {
|
||||
scope.removeAssignedUser(user);
|
||||
});
|
||||
$(menu).append(menuEntry);
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2018 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
import app from '../app/App';
|
||||
|
||||
app.directive('ngContenteditable', function($compile) {
|
||||
return {
|
||||
require: 'ngModel',
|
||||
restrict: 'A',
|
||||
scope: {
|
||||
submit: '&ngSubmit'
|
||||
},
|
||||
link: function(scope, element, attrs, ngModel) {
|
||||
|
||||
//read the text typed in the div (syncing model with the view)
|
||||
function read() {
|
||||
ngModel.$setViewValue(element.html());
|
||||
}
|
||||
|
||||
//render the data now in your model into your view
|
||||
//$render is invoked when the modelvalue differs from the viewvalue
|
||||
//see documentation: https://docs.angularjs.org/api/ng/type/ngModel.NgModelController#
|
||||
ngModel.$render = function() {
|
||||
element.html(ngModel.$viewValue || '');
|
||||
};
|
||||
|
||||
//do this whenever someone starts typing
|
||||
element.bind('blur keyup change', function(event) {
|
||||
scope.$apply(read);
|
||||
});
|
||||
|
||||
element.bind('keydown', function(event) {
|
||||
if(event.which === 13 && event.shiftKey) {
|
||||
scope.submit();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
/* global app */
|
||||
/* gloabl t */
|
||||
/* global moment */
|
||||
|
||||
app.directive('datepicker', function () {
|
||||
'use strict';
|
||||
return {
|
||||
link: function (scope, elm, attr) {
|
||||
return elm.datepicker({
|
||||
dateFormat: moment.localeData().longDateFormat('L').replace('YYYY', 'YY').toLowerCase(),
|
||||
onSelect: function(date, inst) {
|
||||
var selectedDate = $(this).datepicker('getDate');
|
||||
scope.setDuedate(moment(selectedDate));
|
||||
scope.$apply();
|
||||
},
|
||||
beforeShow: function(input, inst) {
|
||||
var dp, marginLeft;
|
||||
dp = $(inst).datepicker('widget');
|
||||
marginLeft = -Math.abs($(input).outerWidth() - dp.outerWidth()) / 2 + 'px';
|
||||
dp.css({
|
||||
'margin-left': marginLeft
|
||||
});
|
||||
$('div.ui-datepicker:before').css({
|
||||
'left': 100 + 'px'
|
||||
});
|
||||
return $('.hasDatepicker').datepicker();
|
||||
},
|
||||
minDate: null
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
// original idea from blockloop: http://stackoverflow.com/a/24090733
|
||||
app.directive('elastic', [
|
||||
'$timeout',
|
||||
function($timeout) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function($scope, element) {
|
||||
$scope.initialHeight = $scope.initialHeight || element[0].style.height;
|
||||
var resize = function() {
|
||||
element[0].style.height = $scope.initialHeight;
|
||||
element[0].style.height = "" + element[0].scrollHeight + "px";
|
||||
};
|
||||
element.on("input change", resize);
|
||||
$timeout(resize, 0);
|
||||
}
|
||||
};
|
||||
}
|
||||
]);
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
app.directive('search', function ($document, $location) {
|
||||
'use strict';
|
||||
|
||||
return {
|
||||
restrict: 'E',
|
||||
scope: {
|
||||
'onSearch': '='
|
||||
},
|
||||
link: function (scope) {
|
||||
if (OCA.Search && OCA.Search.Core) {
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const search = new OCA.Search((term) => {
|
||||
scope.$apply(function () {
|
||||
scope.onSearch(term);
|
||||
});
|
||||
}, () => {
|
||||
scope.$apply(function () {
|
||||
scope.onSearch('');
|
||||
});
|
||||
});
|
||||
} else {
|
||||
const box = $('#searchbox');
|
||||
box.val($location.search().search);
|
||||
|
||||
var doSearch = function () {
|
||||
var value = box.val();
|
||||
scope.$apply(function () {
|
||||
scope.onSearch(value);
|
||||
});
|
||||
};
|
||||
|
||||
box.on('search keyup', function (event) {
|
||||
doSearch();
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
import '../legacy/jquery.ui.timepicker.js';
|
||||
import 'legacy/jquery.ui.timepicker.css';
|
||||
|
||||
/* global app */
|
||||
/* global t */
|
||||
/* global moment */
|
||||
|
||||
app.directive('timepicker', function() {
|
||||
'use strict';
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function(scope, elm, attr) {
|
||||
return $(elm).timepicker({
|
||||
onSelect: function(date, inst) {
|
||||
scope.setDuedateTime(moment('2000-01-01 ' + date));
|
||||
scope.$apply();
|
||||
},
|
||||
myPosition: 'center top',
|
||||
atPosition: 'center bottom',
|
||||
hourText: t('deck', 'Hours'),
|
||||
minuteText: t('deck', 'Minutes'),
|
||||
showPeriodLabels: false
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
app.filter('boardFilterAcl', function() {
|
||||
return function(boards) {
|
||||
var _result = [];
|
||||
angular.forEach(boards, function(board){
|
||||
if(board.acl !== null && Object.keys(board.acl).length > 0) {
|
||||
_result.push(board);
|
||||
}
|
||||
});
|
||||
return _result;
|
||||
};
|
||||
});
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
// usage | cardFilter({ member: 'admin'})
|
||||
|
||||
app.filter('cardFilter', function() {
|
||||
return function(cards, rules) {
|
||||
var _result = [];
|
||||
angular.forEach(cards, function(card){
|
||||
var _card = card;
|
||||
var keys = Object.keys(rules);
|
||||
keys.some(function(key, condition) {
|
||||
if(_card[key]===rules[key]) {
|
||||
_result.push(_card);
|
||||
}
|
||||
});
|
||||
});
|
||||
return _result;
|
||||
};
|
||||
});
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
app.filter('cardSearchFilter', function() {
|
||||
return function(cards, searchString) {
|
||||
var _result = {};
|
||||
var rules = {
|
||||
title: searchString,
|
||||
//owner: searchString,
|
||||
};
|
||||
angular.forEach(cards, function(card){
|
||||
var _card = card;
|
||||
Object.keys(rules).some(function(rule) {
|
||||
var pattern = rules[rule];
|
||||
// eslint-disable-next-line detect-non-literal-regexp
|
||||
if(_card[rule].search(new RegExp(pattern, 'i'))>=0) {
|
||||
_result[_card.id] = _card;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return $.map(_result, function(value, index) {
|
||||
return [value];
|
||||
});
|
||||
};
|
||||
});
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
/* global app */
|
||||
/* global OC */
|
||||
/* global moment */
|
||||
|
||||
app.filter('relativeDateFilter', function() {
|
||||
return function (timestamp) {
|
||||
return OC.Util.relativeModifiedDate(timestamp*1000);
|
||||
};
|
||||
});
|
||||
|
||||
app.filter('relativeDateFilterString', function() {
|
||||
return function (date) {
|
||||
return OC.Util.relativeModifiedDate(Date.parse(date));
|
||||
};
|
||||
});
|
||||
|
||||
app.filter('dateToTimestamp', function() {
|
||||
return function (date) {
|
||||
return Date.parse(date);
|
||||
};
|
||||
});
|
||||
|
||||
app.filter('parseDate', function() {
|
||||
return function (date) {
|
||||
if(moment(date).isValid()) {
|
||||
var dateFormat = moment.localeData().longDateFormat('L');
|
||||
return moment(date).format(dateFormat);
|
||||
}
|
||||
return '';
|
||||
};
|
||||
});
|
||||
|
||||
app.filter('parseTime', function() {
|
||||
return function (date) {
|
||||
if(moment(date).isValid()) {
|
||||
return moment(date).format('HH:mm');
|
||||
}
|
||||
return '';
|
||||
};
|
||||
});
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
app.filter('iconWhiteFilter', function () {
|
||||
return function (hex) {
|
||||
// RGB2HLS by Garry Tan
|
||||
// http://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c
|
||||
var result = /^([A-Fa-f\d]{2})([A-Fa-f\d]{2})([A-Fa-f\d]{2})$/i.exec(hex);
|
||||
var color = result ? {
|
||||
r: parseInt(result[1], 16),
|
||||
g: parseInt(result[2], 16),
|
||||
b: parseInt(result[3], 16)
|
||||
} : null;
|
||||
if (result === null) {
|
||||
return '';
|
||||
}
|
||||
var r = color.r / 255;
|
||||
var g = color.g / 255;
|
||||
var b = color.b / 255;
|
||||
var max = Math.max(r, g, b), min = Math.min(r, g, b);
|
||||
var h, s, l = (max + min) / 2;
|
||||
|
||||
if (max === min) {
|
||||
h = s = 0; // achromatic
|
||||
} else {
|
||||
var d = max - min;
|
||||
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
||||
switch (max) {
|
||||
case r:
|
||||
h = (g - b) / d + (g < b ? 6 : 0);
|
||||
break;
|
||||
case g:
|
||||
h = (b - r) / d + 2;
|
||||
break;
|
||||
case b:
|
||||
h = (r - g) / d + 4;
|
||||
break;
|
||||
}
|
||||
h /= 6;
|
||||
}
|
||||
if (l < 0.5) {
|
||||
return '-white';
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
app.filter('lightenColorFilter', function() {
|
||||
return function (hex) {
|
||||
var result = /^([A-Fa-f\d]{2})([A-Fa-f\d]{2})([A-Fa-f\d]{2})$/i.exec(hex);
|
||||
var color = result ? {
|
||||
r: parseInt(result[1], 16),
|
||||
g: parseInt(result[2], 16),
|
||||
b: parseInt(result[3], 16)
|
||||
} : null;
|
||||
if (result !== null) {
|
||||
return 'rgba(' + color.r + ',' + color.g + ',' + color.b + ',0.7)';
|
||||
} else {
|
||||
return '#' + hex;
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
app.filter('orderObjectBy', function(){
|
||||
return function(input, attribute) {
|
||||
if (!angular.isObject(input)) {
|
||||
return input;
|
||||
}
|
||||
var array = [];
|
||||
for(var objectKey in input) {
|
||||
if ({}.hasOwnProperty.call(input, objectKey)) {
|
||||
array.push(input[objectKey]);
|
||||
}
|
||||
}
|
||||
|
||||
array.sort(function(a, b){
|
||||
a = parseInt(a[attribute]);
|
||||
b = parseInt(b[attribute]);
|
||||
return a < b;
|
||||
});
|
||||
return array;
|
||||
};
|
||||
});
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
app.filter('textColorFilter', function () {
|
||||
return function (hex) {
|
||||
// RGB2HLS by Garry Tan
|
||||
// http://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c
|
||||
var result = /^#?([A-Fa-f\d]{2})([A-Fa-f\d]{2})([A-Fa-f\d]{2})$/i.exec(hex);
|
||||
var color = result ? {
|
||||
r: parseInt(result[1], 16),
|
||||
g: parseInt(result[2], 16),
|
||||
b: parseInt(result[3], 16)
|
||||
} : null;
|
||||
if (result !== null) {
|
||||
var r = color.r / 255;
|
||||
var g = color.g / 255;
|
||||
var b = color.b / 255;
|
||||
var max = Math.max(r, g, b), min = Math.min(r, g, b);
|
||||
var h, s, l = (max + min) / 2;
|
||||
|
||||
if (max === min) {
|
||||
h = s = 0; // achromatic
|
||||
} else {
|
||||
var d = max - min;
|
||||
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
||||
switch (max) {
|
||||
case r:
|
||||
h = (g - b) / d + (g < b ? 6 : 0);
|
||||
break;
|
||||
case g:
|
||||
h = (b - r) / d + 2;
|
||||
break;
|
||||
case b:
|
||||
h = (r - g) / d + 4;
|
||||
break;
|
||||
}
|
||||
h /= 6;
|
||||
}
|
||||
if (l < 0.5) {
|
||||
return '#ffffff';
|
||||
} else {
|
||||
return '#000000';
|
||||
}
|
||||
} else {
|
||||
return '#000000';
|
||||
}
|
||||
|
||||
};
|
||||
});
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
/* global app */
|
||||
/* global angular */
|
||||
|
||||
/*
|
||||
* Remove all assignedUsers from users list
|
||||
*/
|
||||
app.filter('withoutAssignedUsers', function () {
|
||||
return function (users, assignedUsers) {
|
||||
var _result = [];
|
||||
angular.forEach(users, function (user) {
|
||||
var _found = false;
|
||||
angular.forEach(assignedUsers, function (assignedUser) {
|
||||
if (assignedUser.participant.uid === user.uid) {
|
||||
_found = true;
|
||||
}
|
||||
});
|
||||
if (_found === false) {
|
||||
_result.push(user);
|
||||
}
|
||||
});
|
||||
return _result;
|
||||
};
|
||||
});
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2019 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/* global __webpack_nonce__ __webpack_public_path__ OC t n */
|
||||
// eslint-disable-next-line
|
||||
__webpack_nonce__ = btoa(OC.requestToken);
|
||||
// eslint-disable-next-line
|
||||
__webpack_public_path__ = OC.linkTo('deck', 'js/build/');
|
||||
|
||||
import Vue from 'vue';
|
||||
|
||||
Vue.prototype.t = t;
|
||||
Vue.prototype.n = n;
|
||||
Vue.prototype.OC = OC;
|
||||
|
||||
import BoardSelector from './views/BoardSelector';
|
||||
|
||||
import './../css/collections.css';
|
||||
|
||||
((function(OCP) {
|
||||
|
||||
OCP.Collaboration.registerType('deck', {
|
||||
action: () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const container = document.createElement('div');
|
||||
container.id = 'deck-board-select';
|
||||
const body = document.getElementById('body-user');
|
||||
body.append(container);
|
||||
const ComponentVM = new Vue({
|
||||
render: h => h(BoardSelector),
|
||||
});
|
||||
ComponentVM.$mount(container);
|
||||
ComponentVM.$root.$on('close', () => {
|
||||
ComponentVM.$el.remove();
|
||||
ComponentVM.$destroy();
|
||||
reject();
|
||||
});
|
||||
ComponentVM.$root.$on('select', (id) => {
|
||||
resolve(id);
|
||||
ComponentVM.$el.remove();
|
||||
ComponentVM.$destroy();
|
||||
});
|
||||
});
|
||||
},
|
||||
typeString: t('deck', 'Link to a board'),
|
||||
typeIconClass: 'icon-deck'
|
||||
});
|
||||
})(window.OCP));
|
||||
38
js/init.js
38
js/init.js
@@ -1,38 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import "@babel/polyfill";
|
||||
|
||||
/* global __webpack_nonce__ __webpack_public_path__ OC t n */
|
||||
// eslint-disable-next-line
|
||||
__webpack_nonce__ = btoa(OC.requestToken);
|
||||
// eslint-disable-next-line
|
||||
__webpack_public_path__ = OC.linkTo('deck', 'js/build/');
|
||||
|
||||
// used for building a vendor stylesheet
|
||||
import 'ng-sortable/dist/ng-sortable.css';
|
||||
|
||||
import angular from 'angular';
|
||||
import markdownit from 'markdown-it';
|
||||
global.markdownit = markdownit;
|
||||
|
||||
import app from './app/App.js';
|
||||
import './app/Config.js';
|
||||
import './app/Run.js';
|
||||
|
||||
|
||||
import ListController from 'controller/ListController.js';
|
||||
import attachmentListComponent from './controller/AttachmentController.js';
|
||||
import activityComponent from './controller/ActivityController.js';
|
||||
|
||||
app.controller('ListController', ListController);
|
||||
app.component('attachmentListComponent', attachmentListComponent);
|
||||
app.component('activityComponent', activityComponent);
|
||||
|
||||
|
||||
// require all the js files from subdirectories
|
||||
var context = require.context('.', true, /(controller|service|filters|directive)\/(.*)\.js$/);
|
||||
|
||||
context.keys().forEach(function (key) {
|
||||
context(key);
|
||||
});
|
||||
|
||||
@@ -1,161 +0,0 @@
|
||||
/**
|
||||
* @licence
|
||||
*/
|
||||
|
||||
import CommentModel from './commentmodel.js';
|
||||
import CommentSummaryModel from './commentsummarymodel.js';
|
||||
|
||||
/**
|
||||
* @class CommentCollection
|
||||
* @classdesc
|
||||
*
|
||||
* Collection of comments assigned to a file
|
||||
*
|
||||
*/
|
||||
var CommentCollection = OC.Backbone.Collection.extend(
|
||||
/** @lends OCA.AnnouncementCenter.Comments.CommentCollection.prototype */ {
|
||||
|
||||
sync: OC.Backbone.davSync,
|
||||
|
||||
model: CommentModel,
|
||||
|
||||
/**
|
||||
* Object type
|
||||
*
|
||||
* @type string
|
||||
*/
|
||||
_objectType: 'deckCard',
|
||||
|
||||
/**
|
||||
* Object id
|
||||
*
|
||||
* @type string
|
||||
*/
|
||||
_objectId: null,
|
||||
|
||||
/**
|
||||
* True if there are no more page results left to fetch
|
||||
*
|
||||
* @type bool
|
||||
*/
|
||||
_endReached: false,
|
||||
|
||||
/**
|
||||
* Number of comments to fetch per page
|
||||
*
|
||||
* @type int
|
||||
*/
|
||||
_limit : 5,
|
||||
|
||||
/**
|
||||
* Initializes the collection
|
||||
*
|
||||
* @param {string} [options.objectType] object type
|
||||
* @param {string} [options.objectId] object id
|
||||
*/
|
||||
initialize: function(models, options) {
|
||||
options = options || {};
|
||||
if (options.objectType) {
|
||||
this._objectType = options.objectType;
|
||||
}
|
||||
if (options.objectId) {
|
||||
this._objectId = options.objectId;
|
||||
}
|
||||
},
|
||||
|
||||
url: function() {
|
||||
return OC.linkToRemote('dav') + '/comments/' +
|
||||
encodeURIComponent(this._objectType) + '/' +
|
||||
encodeURIComponent(this._objectId) + '/';
|
||||
},
|
||||
|
||||
setObjectId: function(objectId) {
|
||||
this._objectId = objectId;
|
||||
},
|
||||
|
||||
hasMoreResults: function() {
|
||||
return !this._endReached;
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
this._endReached = false;
|
||||
this._summaryModel = null;
|
||||
return OC.Backbone.Collection.prototype.reset.apply(this, arguments);
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetch the next set of results
|
||||
*/
|
||||
fetchNext: function(options) {
|
||||
var self = this;
|
||||
if (!this.hasMoreResults()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var body = '<?xml version="1.0" encoding="utf-8" ?>\n' +
|
||||
'<oc:filter-comments xmlns:D="DAV:" xmlns:oc="http://owncloud.org/ns">\n' +
|
||||
// load one more so we know there is more
|
||||
' <oc:limit>' + (this._limit + 1) + '</oc:limit>\n' +
|
||||
' <oc:offset>' + this.length + '</oc:offset>\n' +
|
||||
'</oc:filter-comments>\n';
|
||||
|
||||
options = options || {};
|
||||
var success = options.success;
|
||||
options = _.extend({
|
||||
remove: false,
|
||||
parse: true,
|
||||
data: body,
|
||||
davProperties: CommentCollection.prototype.model.prototype.davProperties,
|
||||
success: function(resp) {
|
||||
if (resp.length <= self._limit) {
|
||||
// no new entries, end reached
|
||||
self._endReached = true;
|
||||
} else {
|
||||
// remove last entry, for next page load
|
||||
resp = _.initial(resp);
|
||||
}
|
||||
if (!self.set(resp, options)) {
|
||||
return false;
|
||||
}
|
||||
if (success) {
|
||||
success.apply(null, arguments);
|
||||
}
|
||||
self.trigger('sync', 'REPORT', self, options);
|
||||
}
|
||||
}, options);
|
||||
|
||||
return this.sync('REPORT', this, options);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the matching summary model
|
||||
*
|
||||
* @return {OCA.AnnouncementCenter.Comments.CommentSummaryModel} summary model
|
||||
*/
|
||||
getSummaryModel: function() {
|
||||
if (!this._summaryModel) {
|
||||
this._summaryModel = new CommentSummaryModel({
|
||||
id: this._objectId,
|
||||
objectType: this._objectType
|
||||
});
|
||||
}
|
||||
return this._summaryModel;
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates the read marker for this comment thread
|
||||
*
|
||||
* @param {Date} [date] optional date, defaults to now
|
||||
* @param {Object} [options] backbone options
|
||||
*/
|
||||
updateReadMarker: function(date, options) {
|
||||
options = options || {};
|
||||
|
||||
return this.getSummaryModel().save({
|
||||
readMarker: (date || new Date()).toUTCString()
|
||||
}, options);
|
||||
}
|
||||
});
|
||||
|
||||
export default CommentCollection;
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3
|
||||
* or later.
|
||||
*
|
||||
* See the COPYING-README file.
|
||||
*
|
||||
*/
|
||||
|
||||
var NS_OWNCLOUD = 'http://owncloud.org/ns';
|
||||
/**
|
||||
* @class CommentModel
|
||||
* @classdesc
|
||||
*
|
||||
* Comment
|
||||
*
|
||||
*/
|
||||
var CommentModel = OC.Backbone.Model.extend(
|
||||
/** @lends OCA.Comments.CommentModel.prototype */ {
|
||||
sync: OC.Backbone.davSync,
|
||||
|
||||
/**
|
||||
* Object type
|
||||
*
|
||||
* @type string
|
||||
*/
|
||||
_objectType: 'deckCard',
|
||||
|
||||
/**
|
||||
* Object id
|
||||
*
|
||||
* @type string
|
||||
*/
|
||||
_objectId: null,
|
||||
|
||||
initialize: function(model, options) {
|
||||
options = options || {};
|
||||
if (options.objectType) {
|
||||
this._objectType = options.objectType;
|
||||
}
|
||||
if (options.objectId) {
|
||||
this._objectId = options.objectId;
|
||||
}
|
||||
},
|
||||
|
||||
defaults: {
|
||||
actorType: 'users',
|
||||
objectType: 'deckCard'
|
||||
},
|
||||
|
||||
davProperties: {
|
||||
'id': '{' + NS_OWNCLOUD + '}id',
|
||||
'message': '{' + NS_OWNCLOUD + '}message',
|
||||
'actorType': '{' + NS_OWNCLOUD + '}actorType',
|
||||
'actorId': '{' + NS_OWNCLOUD + '}actorId',
|
||||
'actorDisplayName': '{' + NS_OWNCLOUD + '}actorDisplayName',
|
||||
'creationDateTime': '{' + NS_OWNCLOUD + '}creationDateTime',
|
||||
'objectType': '{' + NS_OWNCLOUD + '}objectType',
|
||||
'objectId': '{' + NS_OWNCLOUD + '}objectId',
|
||||
'isUnread': '{' + NS_OWNCLOUD + '}isUnread',
|
||||
'mentions': '{' + NS_OWNCLOUD + '}mentions'
|
||||
},
|
||||
|
||||
parse: function(data) {
|
||||
return {
|
||||
id: data.id,
|
||||
message: data.message,
|
||||
actorType: data.actorType,
|
||||
actorId: data.actorId,
|
||||
actorDisplayName: data.actorDisplayName,
|
||||
creationDateTime: data.creationDateTime,
|
||||
objectType: data.objectType,
|
||||
objectId: data.objectId,
|
||||
isUnread: (data.isUnread === 'true'),
|
||||
mentions: this._parseMentions(data.mentions)
|
||||
};
|
||||
},
|
||||
|
||||
_parseMentions: function(mentions) {
|
||||
if(_.isUndefined(mentions)) {
|
||||
return {};
|
||||
}
|
||||
var result = {};
|
||||
for(var i in mentions) {
|
||||
var mention = mentions[i];
|
||||
if(_.isUndefined(mention.localName) || mention.localName !== 'mention') {
|
||||
continue;
|
||||
}
|
||||
result[i] = {};
|
||||
for (var child = mention.firstChild; child; child = child.nextSibling) {
|
||||
if(_.isUndefined(child.localName) || !child.localName.startsWith('mention')) {
|
||||
continue;
|
||||
}
|
||||
result[i][child.localName] = child.textContent;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
url: function() {
|
||||
let baseUrl;
|
||||
if (typeof this.collection === 'undefined') {
|
||||
baseUrl = OC.linkToRemote('dav') + '/comments/' +
|
||||
encodeURIComponent(this.get('objectType')) + '/' +
|
||||
encodeURIComponent(this.get('objectId')) + '/';
|
||||
} else {
|
||||
baseUrl = this.collection.url();
|
||||
}
|
||||
if (typeof this.get('id') !== 'undefined') {
|
||||
return baseUrl + this.get('id');
|
||||
} else {
|
||||
return baseUrl;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default CommentModel;
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
|
||||
var NS_OWNCLOUD = 'http://owncloud.org/ns';
|
||||
/**
|
||||
* @class OCA.AnnouncementCenter.Comments.CommentSummaryModel
|
||||
* @classdesc
|
||||
*
|
||||
* Model containing summary information related to comments
|
||||
* like the read marker.
|
||||
*
|
||||
*/
|
||||
var CommentSummaryModel = OC.Backbone.Model.extend(
|
||||
/** @lends OCA.AnnouncementCenter.Comments.CommentSummaryModel.prototype */ {
|
||||
sync: OC.Backbone.davSync,
|
||||
|
||||
/**
|
||||
* Object type
|
||||
*
|
||||
* @type string
|
||||
*/
|
||||
_objectType: 'deckCard',
|
||||
|
||||
/**
|
||||
* Object id
|
||||
*
|
||||
* @type string
|
||||
*/
|
||||
_objectId: null,
|
||||
|
||||
davProperties: {
|
||||
'readMarker': '{' + NS_OWNCLOUD + '}readMarker'
|
||||
},
|
||||
|
||||
/**
|
||||
* Initializes the summary model
|
||||
*
|
||||
* @param {string} [options.objectType] object type
|
||||
* @param {string} [options.objectId] object id
|
||||
*/
|
||||
initialize: function(attrs, options) {
|
||||
options = options || {};
|
||||
if (options.objectType) {
|
||||
this._objectType = options.objectType;
|
||||
}
|
||||
},
|
||||
|
||||
url: function() {
|
||||
return OC.linkToRemote('dav') + '/comments/' +
|
||||
encodeURIComponent(this._objectType) + '/' +
|
||||
encodeURIComponent(this.id) + '/';
|
||||
}
|
||||
});
|
||||
|
||||
export default CommentSummaryModel;
|
||||
|
||||
1
js/legacy/jquery.atwho.min.js
vendored
1
js/legacy/jquery.atwho.min.js
vendored
File diff suppressed because one or more lines are too long
561
js/legacy/jquery.caret.min.js
vendored
561
js/legacy/jquery.caret.min.js
vendored
@@ -1,561 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2018 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/>.
|
||||
*
|
||||
*/
|
||||
(function($, undefined) {
|
||||
|
||||
var _input = document.createElement('input');
|
||||
|
||||
var _support = {
|
||||
setSelectionRange: ('setSelectionRange' in _input) || ('selectionStart' in _input),
|
||||
createTextRange: ('createTextRange' in _input) || ('selection' in document)
|
||||
};
|
||||
|
||||
var _rNewlineIE = /\r\n/g,
|
||||
_rCarriageReturn = /\r/g;
|
||||
|
||||
var _getValue = function(input) {
|
||||
if (typeof(input.value) !== 'undefined') {
|
||||
return input.value;
|
||||
}
|
||||
return $(input).text();
|
||||
};
|
||||
|
||||
var _setValue = function(input, value) {
|
||||
if (typeof(input.value) !== 'undefined') {
|
||||
input.value = value;
|
||||
} else {
|
||||
$(input).text(value);
|
||||
}
|
||||
};
|
||||
|
||||
var _getIndex = function(input, pos) {
|
||||
var norm = _getValue(input).replace(_rCarriageReturn, '');
|
||||
var len = norm.length;
|
||||
|
||||
if (typeof(pos) === 'undefined') {
|
||||
pos = len;
|
||||
}
|
||||
|
||||
pos = Math.floor(pos);
|
||||
|
||||
// Negative index counts backward from the end of the input/textarea's value
|
||||
if (pos < 0) {
|
||||
pos = len + pos;
|
||||
}
|
||||
|
||||
// Enforce boundaries
|
||||
if (pos < 0) { pos = 0; }
|
||||
if (pos > len) { pos = len; }
|
||||
|
||||
return pos;
|
||||
};
|
||||
|
||||
var _hasAttr = function(input, attrName) {
|
||||
return input.hasAttribute ? input.hasAttribute(attrName) : (typeof(input[attrName]) !== 'undefined');
|
||||
};
|
||||
|
||||
/**
|
||||
* @class
|
||||
* @constructor
|
||||
*/
|
||||
var Range = function(start, end, length, text) {
|
||||
this.start = start || 0;
|
||||
this.end = end || 0;
|
||||
this.length = length || 0;
|
||||
this.text = text || '';
|
||||
};
|
||||
|
||||
Range.prototype.toString = function() {
|
||||
return JSON.stringify(this, null, ' ');
|
||||
};
|
||||
|
||||
var _getCaretW3 = function(input) {
|
||||
return input.selectionStart;
|
||||
};
|
||||
|
||||
/**
|
||||
* @see http://stackoverflow.com/q/6943000/467582
|
||||
*/
|
||||
var _getCaretIE = function(input) {
|
||||
var caret, range, textInputRange, rawValue, len, endRange;
|
||||
|
||||
// Yeah, you have to focus twice for IE 7 and 8. *cries*
|
||||
input.focus();
|
||||
input.focus();
|
||||
|
||||
range = document.selection.createRange();
|
||||
|
||||
if (range && range.parentElement() === input) {
|
||||
rawValue = _getValue(input);
|
||||
|
||||
len = rawValue.length;
|
||||
|
||||
// Create a working TextRange that lives only in the input
|
||||
textInputRange = input.createTextRange();
|
||||
textInputRange.moveToBookmark(range.getBookmark());
|
||||
|
||||
// Check if the start and end of the selection are at the very end
|
||||
// of the input, since moveStart/moveEnd doesn't return what we want
|
||||
// in those cases
|
||||
endRange = input.createTextRange();
|
||||
endRange.collapse(false);
|
||||
|
||||
if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
|
||||
caret = rawValue.replace(_rNewlineIE, '\n').length;
|
||||
} else {
|
||||
caret = -textInputRange.moveStart("character", -len);
|
||||
}
|
||||
|
||||
return caret;
|
||||
}
|
||||
|
||||
// NOTE: This occurs when you highlight part of a textarea and then click in the middle of the highlighted portion in IE 6-10.
|
||||
// There doesn't appear to be anything we can do about it.
|
||||
// alert("Your browser is incredibly stupid. I don't know what else to say.");
|
||||
// alert(range + '\n\n' + range.parentElement().tagName + '#' + range.parentElement().id);
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the position of the caret in the given input.
|
||||
* @param {HTMLInputElement|HTMLTextAreaElement} input input or textarea element
|
||||
* @returns {Number}
|
||||
* @see http://stackoverflow.com/questions/263743/how-to-get-cursor-position-in-textarea/263796#263796
|
||||
*/
|
||||
var _getCaret = function(input) {
|
||||
if (!input) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Mozilla, et al.
|
||||
if (_support.setSelectionRange) {
|
||||
return _getCaretW3(input);
|
||||
}
|
||||
// IE
|
||||
else if (_support.createTextRange) {
|
||||
return _getCaretIE(input);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
};
|
||||
|
||||
var _setCaretW3 = function(input, pos) {
|
||||
input.setSelectionRange(pos, pos);
|
||||
};
|
||||
|
||||
var _setCaretIE = function(input, pos) {
|
||||
var range = input.createTextRange();
|
||||
range.move('character', pos);
|
||||
range.select();
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the position of the caret in the given input.
|
||||
* @param {HTMLInputElement|HTMLTextAreaElement} input input or textarea element
|
||||
* @param {Number} pos
|
||||
* @see http://parentnode.org/javascript/working-with-the-cursor-position/
|
||||
*/
|
||||
var _setCaret = function(input, pos) {
|
||||
input.focus();
|
||||
|
||||
pos = _getIndex(input, pos);
|
||||
|
||||
// Mozilla, et al.
|
||||
if (_support.setSelectionRange) {
|
||||
_setCaretW3(input, pos);
|
||||
}
|
||||
// IE
|
||||
else if (_support.createTextRange) {
|
||||
_setCaretIE(input, pos);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Inserts the specified text at the current caret position in the given input.
|
||||
* @param {HTMLInputElement|HTMLTextAreaElement} input input or textarea element
|
||||
* @param {String} text
|
||||
* @see http://parentnode.org/javascript/working-with-the-cursor-position/
|
||||
*/
|
||||
var _insertAtCaret = function(input, text) {
|
||||
var curPos = _getCaret(input);
|
||||
|
||||
var oldValueNorm = _getValue(input).replace(_rCarriageReturn, '');
|
||||
|
||||
var newLength = +(curPos + text.length + (oldValueNorm.length - curPos));
|
||||
var maxLength = +input.getAttribute('maxlength');
|
||||
|
||||
if(_hasAttr(input, 'maxlength') && newLength > maxLength) {
|
||||
var delta = text.length - (newLength - maxLength);
|
||||
text = text.substr(0, delta);
|
||||
}
|
||||
|
||||
_setValue(input, oldValueNorm.substr(0, curPos) + text + oldValueNorm.substr(curPos));
|
||||
|
||||
_setCaret(input, curPos + text.length);
|
||||
};
|
||||
|
||||
var _getInputRangeW3 = function(input) {
|
||||
var range = new Range();
|
||||
|
||||
range.start = input.selectionStart;
|
||||
range.end = input.selectionEnd;
|
||||
|
||||
var min = Math.min(range.start, range.end);
|
||||
var max = Math.max(range.start, range.end);
|
||||
|
||||
range.length = max - min;
|
||||
range.text = _getValue(input).substring(min, max);
|
||||
|
||||
return range;
|
||||
};
|
||||
|
||||
/** @see http://stackoverflow.com/a/3648244/467582 */
|
||||
var _getInputRangeIE = function(input) {
|
||||
var range = new Range();
|
||||
|
||||
input.focus();
|
||||
|
||||
var selection = document.selection.createRange();
|
||||
|
||||
if (selection && selection.parentElement() === input) {
|
||||
var len, normalizedValue, textInputRange, endRange, start = 0, end = 0;
|
||||
var rawValue = _getValue(input);
|
||||
|
||||
len = rawValue.length;
|
||||
normalizedValue = rawValue.replace(/\r\n/g, "\n");
|
||||
|
||||
// Create a working TextRange that lives only in the input
|
||||
textInputRange = input.createTextRange();
|
||||
textInputRange.moveToBookmark(selection.getBookmark());
|
||||
|
||||
// Check if the start and end of the selection are at the very end
|
||||
// of the input, since moveStart/moveEnd doesn't return what we want
|
||||
// in those cases
|
||||
endRange = input.createTextRange();
|
||||
endRange.collapse(false);
|
||||
|
||||
if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
|
||||
start = end = len;
|
||||
} else {
|
||||
start = -textInputRange.moveStart("character", -len);
|
||||
start += normalizedValue.slice(0, start).split("\n").length - 1;
|
||||
|
||||
if (textInputRange.compareEndPoints("EndToEnd", endRange) > -1) {
|
||||
end = len;
|
||||
} else {
|
||||
end = -textInputRange.moveEnd("character", -len);
|
||||
end += normalizedValue.slice(0, end).split("\n").length - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/// normalize newlines
|
||||
start -= (rawValue.substring(0, start).split('\r\n').length - 1);
|
||||
end -= (rawValue.substring(0, end).split('\r\n').length - 1);
|
||||
/// normalize newlines
|
||||
|
||||
range.start = start;
|
||||
range.end = end;
|
||||
range.length = range.end - range.start;
|
||||
range.text = normalizedValue.substr(range.start, range.length);
|
||||
}
|
||||
|
||||
return range;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the selected text range of the given input.
|
||||
* @param {HTMLInputElement|HTMLTextAreaElement} input input or textarea element
|
||||
* @returns {Range}
|
||||
* @see http://stackoverflow.com/a/263796/467582
|
||||
* @see http://stackoverflow.com/a/2966703/467582
|
||||
*/
|
||||
var _getInputRange = function(input) {
|
||||
if (!input) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Mozilla, et al.
|
||||
if (_support.setSelectionRange) {
|
||||
return _getInputRangeW3(input);
|
||||
}
|
||||
// IE
|
||||
else if (_support.createTextRange) {
|
||||
return _getInputRangeIE(input);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
};
|
||||
|
||||
var _setInputRangeW3 = function(input, startPos, endPos) {
|
||||
input.setSelectionRange(startPos, endPos);
|
||||
};
|
||||
|
||||
var _setInputRangeIE = function(input, startPos, endPos) {
|
||||
var tr = input.createTextRange();
|
||||
tr.moveEnd('textedit', -1);
|
||||
tr.moveStart('character', startPos);
|
||||
tr.moveEnd('character', endPos - startPos);
|
||||
tr.select();
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the selected text range of (i.e., highlights text in) the given input.
|
||||
* @param {HTMLInputElement|HTMLTextAreaElement} input input or textarea element
|
||||
* @param {Number} startPos Zero-based index
|
||||
* @param {Number} endPos Zero-based index
|
||||
* @see http://parentnode.org/javascript/working-with-the-cursor-position/
|
||||
* @see http://stackoverflow.com/a/2966703/467582
|
||||
*/
|
||||
var _setInputRange = function(input, startPos, endPos) {
|
||||
startPos = _getIndex(input, startPos);
|
||||
endPos = _getIndex(input, endPos);
|
||||
|
||||
// Mozilla, et al.
|
||||
if (_support.setSelectionRange) {
|
||||
_setInputRangeW3(input, startPos, endPos);
|
||||
}
|
||||
// IE
|
||||
else if (_support.createTextRange) {
|
||||
_setInputRangeIE(input, startPos, endPos);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Replaces the currently selected text with the given string.
|
||||
* @param {HTMLInputElement|HTMLTextAreaElement} input input or textarea element
|
||||
* @param {String} text New text that will replace the currently selected text.
|
||||
* @see http://parentnode.org/javascript/working-with-the-cursor-position/
|
||||
*/
|
||||
var _replaceInputRange = function(input, text) {
|
||||
var $input = $(input);
|
||||
|
||||
var oldValue = $input.val();
|
||||
var selection = _getInputRange(input);
|
||||
|
||||
var newLength = +(selection.start + text.length + (oldValue.length - selection.end));
|
||||
var maxLength = +$input.attr('maxlength');
|
||||
|
||||
if($input.is('[maxlength]') && newLength > maxLength) {
|
||||
var delta = text.length - (newLength - maxLength);
|
||||
text = text.substr(0, delta);
|
||||
}
|
||||
|
||||
// Now that we know what the user selected, we can replace it
|
||||
var startText = oldValue.substr(0, selection.start);
|
||||
var endText = oldValue.substr(selection.end);
|
||||
|
||||
$input.val(startText + text + endText);
|
||||
|
||||
// Reset the selection
|
||||
var startPos = selection.start;
|
||||
var endPos = startPos + text.length;
|
||||
|
||||
_setInputRange(input, selection.length ? startPos : endPos, endPos);
|
||||
};
|
||||
|
||||
var _selectAllW3 = function(elem) {
|
||||
var selection = window.getSelection();
|
||||
var range = document.createRange();
|
||||
range.selectNodeContents(elem);
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
};
|
||||
|
||||
var _selectAllIE = function(elem) {
|
||||
var range = document.body.createTextRange();
|
||||
range.moveToElementText(elem);
|
||||
range.select();
|
||||
};
|
||||
|
||||
/**
|
||||
* Select all text in the given element.
|
||||
* @param {HTMLElement} elem Any block or inline element other than a form element.
|
||||
*/
|
||||
var _selectAll = function(elem) {
|
||||
var $elem = $(elem);
|
||||
if ($elem.is('input, textarea') || elem.select) {
|
||||
$elem.select();
|
||||
return;
|
||||
}
|
||||
|
||||
// Mozilla, et al.
|
||||
if (_support.setSelectionRange) {
|
||||
_selectAllW3(elem);
|
||||
}
|
||||
// IE
|
||||
else if (_support.createTextRange) {
|
||||
_selectAllIE(elem);
|
||||
}
|
||||
};
|
||||
|
||||
var _deselectAll = function() {
|
||||
if (document.selection) {
|
||||
document.selection.empty();
|
||||
}
|
||||
else if (window.getSelection) {
|
||||
window.getSelection().removeAllRanges();
|
||||
}
|
||||
};
|
||||
|
||||
$.extend($.fn, {
|
||||
|
||||
/**
|
||||
* Gets or sets the position of the caret or inserts text at the current caret position in an input or textarea element.
|
||||
* @returns {Number|jQuery} The current caret position if invoked as a getter (with no arguments)
|
||||
* or this jQuery object if invoked as a setter or inserter.
|
||||
* @see http://web.archive.org/web/20080704185920/http://parentnode.org/javascript/working-with-the-cursor-position/
|
||||
* @since 1.0.0
|
||||
* @example
|
||||
* <pre>
|
||||
* // Get position
|
||||
* var pos = $('input:first').caret();
|
||||
* </pre>
|
||||
* @example
|
||||
* <pre>
|
||||
* // Set position
|
||||
* $('input:first').caret(15);
|
||||
* $('input:first').caret(-3);
|
||||
* </pre>
|
||||
* @example
|
||||
* <pre>
|
||||
* // Insert text at current position
|
||||
* $('input:first').caret('Some text');
|
||||
* </pre>
|
||||
*/
|
||||
caret: function() {
|
||||
var $inputs = this.filter('input, textarea');
|
||||
|
||||
// getCaret()
|
||||
if (arguments.length === 0) {
|
||||
var input = $inputs.get(0);
|
||||
return _getCaret(input);
|
||||
}
|
||||
// setCaret(position)
|
||||
else if (typeof arguments[0] === 'number') {
|
||||
var pos = arguments[0];
|
||||
$inputs.each(function(_i, input) {
|
||||
_setCaret(input, pos);
|
||||
});
|
||||
}
|
||||
// insertAtCaret(text)
|
||||
else {
|
||||
var text = arguments[0];
|
||||
$inputs.each(function(_i, input) {
|
||||
_insertAtCaret(input, text);
|
||||
});
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets or sets the selection range or replaces the currently selected text in an input or textarea element.
|
||||
* @returns {Range|jQuery} The current selection range if invoked as a getter (with no arguments)
|
||||
* or this jQuery object if invoked as a setter or replacer.
|
||||
* @see http://stackoverflow.com/a/2966703/467582
|
||||
* @since 1.0.0
|
||||
* @example
|
||||
* <pre>
|
||||
* // Get selection range
|
||||
* var range = $('input:first').range();
|
||||
* </pre>
|
||||
* @example
|
||||
* <pre>
|
||||
* // Set selection range
|
||||
* $('input:first').range(15);
|
||||
* $('input:first').range(15, 20);
|
||||
* $('input:first').range(-3);
|
||||
* $('input:first').range(-8, -3);
|
||||
* </pre>
|
||||
* @example
|
||||
* <pre>
|
||||
* // Replace the currently selected text
|
||||
* $('input:first').range('Replacement text');
|
||||
* </pre>
|
||||
*/
|
||||
range: function() {
|
||||
var $inputs = this.filter('input, textarea');
|
||||
|
||||
// getRange() = { start: pos, end: pos }
|
||||
if (arguments.length === 0) {
|
||||
var input = $inputs.get(0);
|
||||
return _getInputRange(input);
|
||||
}
|
||||
// setRange(startPos, endPos)
|
||||
else if (typeof arguments[0] === 'number') {
|
||||
var startPos = arguments[0];
|
||||
var endPos = arguments[1];
|
||||
$inputs.each(function(_i, input) {
|
||||
_setInputRange(input, startPos, endPos);
|
||||
});
|
||||
}
|
||||
// replaceRange(text)
|
||||
else {
|
||||
var text = arguments[0];
|
||||
$inputs.each(function(_i, input) {
|
||||
_replaceInputRange(input, text);
|
||||
});
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Selects all text in each element of this jQuery object.
|
||||
* @returns {jQuery} This jQuery object
|
||||
* @see http://stackoverflow.com/a/11128179/467582
|
||||
* @since 1.5.0
|
||||
* @example
|
||||
* <pre>
|
||||
* // Select the contents of span elements when clicked
|
||||
* $('span').on('click', function() { $(this).highlight(); });
|
||||
* </pre>
|
||||
*/
|
||||
selectAll: function() {
|
||||
return this.each(function(_i, elem) {
|
||||
_selectAll(elem);
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
$.extend($, {
|
||||
/**
|
||||
* Deselects all text on the page.
|
||||
* @returns {jQuery} The jQuery function
|
||||
* @since 1.5.0
|
||||
* @example
|
||||
* <pre>
|
||||
* // Select some text
|
||||
* $('span').selectAll();
|
||||
*
|
||||
* // Deselect the text
|
||||
* $.deselectAll();
|
||||
* </pre>
|
||||
*/
|
||||
deselectAll: function() {
|
||||
_deselectAll();
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
}(window.jQuery || window.Zepto || window.$));
|
||||
57
js/legacy/jquery.ui.timepicker.css
vendored
57
js/legacy/jquery.ui.timepicker.css
vendored
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Timepicker stylesheet
|
||||
* Highly inspired from datepicker
|
||||
* FG - Nov 2010 - Web3R
|
||||
*
|
||||
* version 0.0.3 : Fixed some settings, more dynamic
|
||||
* version 0.0.4 : Removed width:100% on tables
|
||||
* version 0.1.1 : set width 0 on tables to fix an ie6 bug
|
||||
*/
|
||||
|
||||
.ui-timepicker-inline { display: inline; }
|
||||
|
||||
#ui-timepicker-div { padding: 0.2em; }
|
||||
.ui-timepicker-table { display: inline-table; width: 0; }
|
||||
.ui-timepicker-table table { margin:0.15em 0 0 0; border-collapse: collapse; }
|
||||
|
||||
.ui-timepicker-hours, .ui-timepicker-minutes { padding: 0.2em; }
|
||||
|
||||
.ui-timepicker-table .ui-timepicker-title { line-height: 1.8em; text-align: center; }
|
||||
.ui-timepicker-table td { padding: 0.1em; width: 2.2em; }
|
||||
.ui-timepicker-table th.periods { padding: 0.1em; width: 2.2em; }
|
||||
|
||||
/* span for disabled cells */
|
||||
.ui-timepicker-table td span {
|
||||
display:block;
|
||||
padding:0.2em 0.3em 0.2em 0.5em;
|
||||
width: 1.2em;
|
||||
|
||||
text-align:right;
|
||||
text-decoration:none;
|
||||
}
|
||||
/* anchors for clickable cells */
|
||||
.ui-timepicker-table td a {
|
||||
display:block;
|
||||
padding:0.2em 0.3em 0.2em 0.5em;
|
||||
width: 1.2em;
|
||||
cursor: pointer;
|
||||
text-align:right;
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
|
||||
/* buttons and button pane styling */
|
||||
.ui-timepicker .ui-timepicker-buttonpane {
|
||||
background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0;
|
||||
}
|
||||
.ui-timepicker .ui-timepicker-buttonpane button { margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
|
||||
/* The close button */
|
||||
.ui-timepicker .ui-timepicker-close { float: right }
|
||||
|
||||
/* the now button */
|
||||
.ui-timepicker .ui-timepicker-now { float: left; }
|
||||
|
||||
/* the deselect button */
|
||||
.ui-timepicker .ui-timepicker-deselect { float: left; }
|
||||
|
||||
|
||||
1496
js/legacy/jquery.ui.timepicker.js
vendored
1496
js/legacy/jquery.ui.timepicker.js
vendored
File diff suppressed because it is too large
Load Diff
@@ -1,120 +0,0 @@
|
||||
/**
|
||||
* Original source code from https://github.com/mcecot/markdown-it-checkbox
|
||||
* © 2015 Markus Cecot
|
||||
* licenced under MIT
|
||||
* https://github.com/mcecot/markdown-it-checkbox/blob/master/LICENSE
|
||||
*/
|
||||
var checkboxReplace;
|
||||
|
||||
checkboxReplace = function(md, options, Token) {
|
||||
"use strict";
|
||||
var arrayReplaceAt, createTokens, defaults, lastId, pattern, splitTextToken;
|
||||
arrayReplaceAt = md.utils.arrayReplaceAt;
|
||||
lastId = 0;
|
||||
defaults = {
|
||||
divWrap: false,
|
||||
divClass: 'checkbox',
|
||||
idPrefix: 'checkbox'
|
||||
};
|
||||
options = Object.assign(defaults, options);
|
||||
pattern = /(.*?)(\[(X|\s|\_|\-)\])(.*)/igm;
|
||||
createTokens = function(checked, label, Token, before) {
|
||||
var id, idNumeric, nodes, token;
|
||||
nodes = [];
|
||||
|
||||
token = new Token("text", "", 0);
|
||||
token.content = before;
|
||||
nodes.push(token);
|
||||
|
||||
/**
|
||||
* <div class="checkbox">
|
||||
*/
|
||||
if (options.divWrap) {
|
||||
token = new Token("checkbox_open", "div", 1);
|
||||
token.attrs = [["class", options.divClass]];
|
||||
nodes.push(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* <input type="checkbox" id="checkbox{n}" checked="true">
|
||||
*/
|
||||
id = options.idPrefix + lastId;
|
||||
idNumeric = lastId;
|
||||
lastId += 1;
|
||||
token = new Token("checkbox_input", "input", 0);
|
||||
token.attrs = [["type", "checkbox"], ["id", id], ["data-id", idNumeric]];
|
||||
if (checked === true) {
|
||||
token.attrs.push(["checked", "true"]);
|
||||
}
|
||||
token.attrs.push(["class", "checkbox"]);
|
||||
nodes.push(token);
|
||||
|
||||
/**
|
||||
* <label for="checkbox{n}">
|
||||
*/
|
||||
token = new Token("label_open", "label", 1);
|
||||
token.attrs = [["for", id], ["data-id", idNumeric]];
|
||||
nodes.push(token);
|
||||
|
||||
/**
|
||||
* content of label tag
|
||||
*/
|
||||
token = new Token("text", "", 0);
|
||||
token.content = label;
|
||||
nodes.push(token);
|
||||
|
||||
/**
|
||||
* closing tags
|
||||
*/
|
||||
nodes.push(new Token("label_close", "label", -1));
|
||||
if (options.divWrap) {
|
||||
nodes.push(new Token("checkbox_close", "div", -1));
|
||||
}
|
||||
return nodes;
|
||||
};
|
||||
splitTextToken = function(original, Token) {
|
||||
var checked, label, matches, text, value, before;
|
||||
text = original.content;
|
||||
matches = pattern.exec(text);
|
||||
if (matches === null) {
|
||||
return original;
|
||||
}
|
||||
checked = false;
|
||||
before = matches[1];
|
||||
value = matches[3];
|
||||
label = matches[4];
|
||||
if (value === "X" || value === "x") {
|
||||
checked = true;
|
||||
}
|
||||
return createTokens(checked, label, Token, before);
|
||||
};
|
||||
return function(state) {
|
||||
lastId = 0;
|
||||
var blockTokens, i, j, l, token, tokens;
|
||||
blockTokens = state.tokens;
|
||||
j = 0;
|
||||
l = blockTokens.length;
|
||||
while (j < l) {
|
||||
if (blockTokens[j].type !== "inline") {
|
||||
j++;
|
||||
continue;
|
||||
}
|
||||
tokens = blockTokens[j].children;
|
||||
i = 0;
|
||||
while (i < tokens.length) {
|
||||
token = tokens[i];
|
||||
blockTokens[j].children = tokens = arrayReplaceAt(tokens, i, splitTextToken(token, state.Token));
|
||||
i++;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/*global module */
|
||||
|
||||
module.exports = function(md, options) {
|
||||
"use strict";
|
||||
md.core.ruler.push("checkbox", checkboxReplace(md, options));
|
||||
};
|
||||
7750
js/package-lock.json
generated
7750
js/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,55 +0,0 @@
|
||||
{
|
||||
"name": "deck",
|
||||
"description": "Frontend for the Nextcloud Deck app",
|
||||
"repository": "https://github.com/nextcloud/deck",
|
||||
"version": "1.0.0",
|
||||
"directories": {
|
||||
"test": "tests"
|
||||
},
|
||||
"dependencies": {
|
||||
"@uirouter/angularjs": "^1.0.25",
|
||||
"angular": "^1.7.9",
|
||||
"angular-animate": "^1.7.9",
|
||||
"angular-file-upload": "^2.5.0",
|
||||
"angular-markdown-it": "^0.6.1",
|
||||
"angular-sanitize": "^1.7.9",
|
||||
"babel-polyfill": "^6.26.0",
|
||||
"markdown-it": "^10.0.0",
|
||||
"markdown-it-link-target": "^1.0.2",
|
||||
"nextcloud-axios": "^0.2.1",
|
||||
"nextcloud-vue": "^0.12.8",
|
||||
"nextcloud-vue-collections": "^0.6.0",
|
||||
"ng-infinite-scroll": "^1.3.0",
|
||||
"ng-sortable": "^1.3.8",
|
||||
"ui-select": "^0.19.8",
|
||||
"vue": "^2.6.11",
|
||||
"vuex": "^3.1.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.9.0",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
||||
"@babel/polyfill": "^7.8.7",
|
||||
"@babel/preset-env": "^7.9.0",
|
||||
"babel-loader": "^8.1.0",
|
||||
"css-loader": "^3.4.2",
|
||||
"karma": "^4.4.1",
|
||||
"mini-css-extract-plugin": "^0.9.0",
|
||||
"style-loader": "^1.1.3",
|
||||
"url-loader": "^4.0.0",
|
||||
"vue-loader": "^15.9.1",
|
||||
"vue-style-loader": "^4.1.2",
|
||||
"vue-template-compiler": "^2.6.11",
|
||||
"webpack": "^4.42.1",
|
||||
"webpack-cli": "^3.3.11",
|
||||
"webpack-merge": "^4.2.2"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "NODE_ENV=production ./node_modules/webpack-cli/bin/cli.js --mode production --config webpack.prod.config.js",
|
||||
"dev": "./node_modules/webpack-cli/bin/cli.js --mode development --config webpack.dev.config.js",
|
||||
"watch": "./node_modules/webpack-cli/bin/cli.js --mode development --config webpack.dev.config.js --watch",
|
||||
"test": "echo \"Warning: no test specified\" && exit 0"
|
||||
},
|
||||
"author": "",
|
||||
"license": "AGPL-3.0",
|
||||
"keywords": []
|
||||
}
|
||||
@@ -1,256 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2018 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
import app from '../app/App.js';
|
||||
import CommentCollection from '../legacy/commentcollection';
|
||||
import CommentModel from '../legacy/commentmodel';
|
||||
|
||||
const DECK_ACTIVITY_TYPE_BOARD = 'deck_board';
|
||||
const DECK_ACTIVITY_TYPE_CARD = 'deck_card';
|
||||
|
||||
/* global OC oc_requesttoken */
|
||||
class ActivityService {
|
||||
|
||||
static get RESULT_PER_PAGE() { return 50; }
|
||||
|
||||
constructor ($rootScope, $filter, $http, $q) {
|
||||
this.running = false;
|
||||
this.runningNewer = false;
|
||||
this.$filter = $filter;
|
||||
this.$http = $http;
|
||||
this.$q = $q;
|
||||
this.$rootScope = $rootScope;
|
||||
this.data = {};
|
||||
this.data[DECK_ACTIVITY_TYPE_BOARD] = {};
|
||||
this.data[DECK_ACTIVITY_TYPE_CARD] = {};
|
||||
this.toEnhanceWithComments = [];
|
||||
this.commentCollection = new CommentCollection();
|
||||
this.commentCollection._limit = ActivityService.RESULT_PER_PAGE;
|
||||
this.commentCollection.on('request', function() {
|
||||
}, this);
|
||||
this.commentCollection.on('sync', function(a) {
|
||||
for (let index in this.toEnhanceWithComments) {
|
||||
if (this.toEnhanceWithComments.hasOwnProperty(index)) {
|
||||
let item = this.toEnhanceWithComments[index];
|
||||
let commentId = Array.isArray(item.subject_rich[1].comment) ? item.subject_rich[1].comment.id : item.subject_rich[1].comment;
|
||||
item.commentModel = this.commentCollection.get(commentId);
|
||||
if (typeof item.commentModel !== 'undefined') {
|
||||
this.toEnhanceWithComments = this.toEnhanceWithComments.filter((entry) => entry.activity_id !== item.activity_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
var firstUnread = this.commentCollection.findWhere({isUnread: true});
|
||||
if (typeof firstUnread !== 'undefined') {
|
||||
this.commentCollection.updateReadMarker();
|
||||
}
|
||||
this.notify();
|
||||
}, this);
|
||||
this.commentCollection.on('add', function(model, collection, options) {
|
||||
// we need to update the model, because it consists of client data
|
||||
// only, but the server might add meta data, e.g. about mentions
|
||||
model.fetch();
|
||||
}, this);
|
||||
this.since = {
|
||||
deck_card: {
|
||||
|
||||
},
|
||||
deck_board: {
|
||||
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* We need a event here to properly update scope once the external data from
|
||||
* the comments backbone js code has changed
|
||||
*/
|
||||
subscribe(scope, callback) {
|
||||
let handler = this.$rootScope.$on('notify-comment-update', callback);
|
||||
scope.$on('$destroy', handler);
|
||||
}
|
||||
|
||||
notify() {
|
||||
this.$rootScope.$emit('notify-comment-update');
|
||||
}
|
||||
|
||||
static getUrl(type, id, since) {
|
||||
if (type === DECK_ACTIVITY_TYPE_CARD) {
|
||||
return OC.linkToOCS('apps/activity/api/v2/activity', 2) + 'filter?format=json&object_type=deck_card&object_id=' + id + '&limit=' + this.RESULT_PER_PAGE + '&since=' + since;
|
||||
}
|
||||
if (type === DECK_ACTIVITY_TYPE_BOARD) {
|
||||
return OC.linkToOCS('apps/activity/api/v2/activity', 2) + 'deck?format=json&limit=' + this.RESULT_PER_PAGE + '&since=' + since;
|
||||
}
|
||||
}
|
||||
|
||||
fetchCardActivities(type, id, since) {
|
||||
this.running = true;
|
||||
|
||||
this.checkData(type, id);
|
||||
const self = this;
|
||||
return this.$http.get(ActivityService.getUrl(type, id, since)).then(function (response) {
|
||||
const objects = response.data.ocs.data;
|
||||
|
||||
for (let index in objects) {
|
||||
if (objects.hasOwnProperty(index)) {
|
||||
let item = objects[index];
|
||||
self.addItem(type, id, item);
|
||||
if (item.activity_id > self.since[type][id].latest) {
|
||||
self.since[type][id].latest = item.activity_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
self.data[type][id].sort(function(a, b) {
|
||||
return b.activity_id - a.activity_id;
|
||||
});
|
||||
self.since[type][id].oldest = response.headers('X-Activity-Last-Given');
|
||||
self.running = false;
|
||||
return response;
|
||||
}, function (error) {
|
||||
if (error.status === 304 || error.status === 404) {
|
||||
self.since[type][id].finished = true;
|
||||
}
|
||||
self.running = false;
|
||||
});
|
||||
}
|
||||
|
||||
fetchMoreActivities(type, id, success) {
|
||||
const self = this;
|
||||
this.checkData(type, id);
|
||||
if (this.running === true) {
|
||||
return this.runningPromise;
|
||||
}
|
||||
if (!this.since[type][id].finished) {
|
||||
this.runningPromise = this.fetchCardActivities(type, id, this.since[type][id].oldest);
|
||||
this.runningPromise.then(function() {
|
||||
if (type === 'deck_card') {
|
||||
self.commentCollection.fetchNext();
|
||||
}
|
||||
});
|
||||
return this.runningPromise;
|
||||
}
|
||||
return Promise.reject();
|
||||
}
|
||||
checkData(type, id) {
|
||||
if (!Array.isArray(this.data[type][id])) {
|
||||
this.data[type][id] = [];
|
||||
}
|
||||
if (typeof this.since[type][id] === 'undefined') {
|
||||
this.since[type][id] = {
|
||||
latest: -1,
|
||||
oldestCatchedUp: false,
|
||||
oldest: '0',
|
||||
finished: false,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
addItem(type, id, item) {
|
||||
const self = this;
|
||||
const existingEntry = this.data[type][id].findIndex((entry) => { return entry.activity_id === item.activity_id; });
|
||||
if (existingEntry !== -1) {
|
||||
return;
|
||||
}
|
||||
/** check if the fetched item from all deck activities is actually related */
|
||||
const isUnrelatedBoard = (item.object_type === DECK_ACTIVITY_TYPE_BOARD && item.object_id !== id);
|
||||
const isUnrelatedCard = (item.object_type === DECK_ACTIVITY_TYPE_CARD && (
|
||||
(item.subject_rich[1].board && item.subject_rich[1].board.id !== id) || (typeof item.subject_rich[1].board === 'undefined'))
|
||||
);
|
||||
if (type === DECK_ACTIVITY_TYPE_BOARD && (isUnrelatedBoard || isUnrelatedCard)) {
|
||||
return;
|
||||
}
|
||||
item.timestamp = new Date(item.datetime).getTime();
|
||||
item.type = 'activity';
|
||||
if (item.subject_rich[1].comment) {
|
||||
item.type = 'comment';
|
||||
item.commentModel = this.commentCollection.get(item.subject_rich[1].comment);
|
||||
if (typeof item.commentModel === 'undefined') {
|
||||
this.toEnhanceWithComments.push(item);
|
||||
}
|
||||
}
|
||||
|
||||
this.data[type][id].push(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch newer activities starting from the latest ones that are in cache
|
||||
*
|
||||
* @param type
|
||||
* @param id
|
||||
*/
|
||||
fetchNewerActivities(type, id) {
|
||||
if (this.since[type][id].latest === 0) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
let self = this;
|
||||
return this.fetchNewer(type, id).then(function() {
|
||||
return self.fetchNewerActivities(type, id);
|
||||
});
|
||||
}
|
||||
|
||||
fetchNewer(type, id) {
|
||||
const deferred = this.$q.defer();
|
||||
this.running = true;
|
||||
this.runningNewer = true;
|
||||
const self = this;
|
||||
this.$http.get(ActivityService.getUrl(type, id, this.since[type][id].latest) + '&sort=asc').then(function (response) {
|
||||
let objects = response.data.ocs.data;
|
||||
|
||||
let data = [];
|
||||
for (let index in objects) {
|
||||
if (objects.hasOwnProperty(index)) {
|
||||
let item = objects[index];
|
||||
self.addItem(type, id, item);
|
||||
}
|
||||
}
|
||||
self.data[type][id].sort(function(a, b) {
|
||||
return b.activity_id - a.activity_id;
|
||||
});
|
||||
self.since[type][id].latest = response.headers('X-Activity-Last-Given');
|
||||
self.data[type][id] = data.concat(self.data[type][id]);
|
||||
self.running = false;
|
||||
self.runningNewer = false;
|
||||
deferred.resolve(objects);
|
||||
}, function (error) {
|
||||
self.runningNewer = false;
|
||||
self.running = false;
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
getData(type, id) {
|
||||
if (!Array.isArray(this.data[type][id])) {
|
||||
return [];
|
||||
}
|
||||
return this.data[type][id];
|
||||
}
|
||||
|
||||
loadComments(id) {
|
||||
this.commentCollection.reset();
|
||||
this.commentCollection.setObjectId(id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
app.service('ActivityService', ActivityService);
|
||||
|
||||
export default ActivityService;
|
||||
export {DECK_ACTIVITY_TYPE_BOARD, DECK_ACTIVITY_TYPE_CARD};
|
||||
@@ -1,232 +0,0 @@
|
||||
/*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
/** global: oc_defaults */
|
||||
app.factory('ApiService', function ($http, $q) {
|
||||
var ApiService = function (http, endpoint) {
|
||||
// Consider renaming endpoint to resource
|
||||
this.endpoint = endpoint;
|
||||
this.baseUrl = this.generateUrl(this.endpoint);
|
||||
this.http = http;
|
||||
this.q = $q;
|
||||
this.data = {};
|
||||
this.deleted = {};
|
||||
this.id = null;
|
||||
this.sorted = [];
|
||||
};
|
||||
|
||||
ApiService.prototype.generateUrl = function(path) {
|
||||
return OC.generateUrl('/apps/deck/' + path);
|
||||
};
|
||||
|
||||
ApiService.prototype.tryAllThenDeleted = function(id) {
|
||||
let object = this.data[id];
|
||||
if (object === undefined) {
|
||||
object = this.deleted[id];
|
||||
}
|
||||
return object;
|
||||
};
|
||||
|
||||
ApiService.prototype.fetchAll = function () {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
$http.get(this.baseUrl).then(function (response) {
|
||||
var objects = response.data;
|
||||
objects.forEach(function (obj) {
|
||||
self.data[obj.id] = obj;
|
||||
});
|
||||
deferred.resolve(self.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Fetching ' + self.endpoint + ' failed');
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
ApiService.prototype.fetchDeleted = function (scopeId) {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
self.deleted = {};
|
||||
$http.get(this.generateUrl(scopeId + '/' + this.endpoint + '/deleted')).then(function (response) {
|
||||
var objects = response.data;
|
||||
objects.forEach(function (obj) {
|
||||
if(self.deleted[obj.id] !== undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.deleted[obj.id] = obj;
|
||||
|
||||
if(self.afterFetch !== undefined) {
|
||||
self.afterFetch(obj);
|
||||
}
|
||||
});
|
||||
deferred.resolve(objects);
|
||||
}, function (error) {
|
||||
deferred.reject('Fetching ' + self.endpoint + ' failed');
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
|
||||
ApiService.prototype.fetchOne = function (id) {
|
||||
|
||||
this.id = id;
|
||||
var deferred = $q.defer();
|
||||
|
||||
if (id === undefined) {
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
$http.get(this.baseUrl + '/' + id).then(function (response) {
|
||||
var data = response.data;
|
||||
if (self.data[data.id] === undefined) {
|
||||
self.data[data.id] = response.data;
|
||||
}
|
||||
$.each(response.data, function (key, value) {
|
||||
self.data[data.id][key] = value;
|
||||
});
|
||||
deferred.resolve(response.data);
|
||||
|
||||
}, function (error) {
|
||||
deferred.reject('Fetching ' + self.endpoint + ' failed');
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
ApiService.prototype.create = function (entity) {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
$http.post(this.baseUrl, entity).then(function (response) {
|
||||
self.add(response.data);
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject(error.data.message);
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
ApiService.prototype.update = function (entity) {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
$http.put(this.baseUrl + '/' + entity.id, entity).then(function (response) {
|
||||
self.add(response.data);
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject(error.data.message);
|
||||
});
|
||||
return deferred.promise;
|
||||
|
||||
};
|
||||
|
||||
ApiService.prototype.delete = function (id) {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
|
||||
$http.delete(this.baseUrl + '/' + id).then(function (response) {
|
||||
self.deleted[id] = self.data[id];
|
||||
delete self.data[id];
|
||||
|
||||
let deletedAt = response.data.deletedAt;
|
||||
if (deletedAt !== undefined) {
|
||||
self.deleted[id].deletedAt = deletedAt;
|
||||
}
|
||||
|
||||
deferred.resolve(response.data);
|
||||
|
||||
}, function (error) {
|
||||
deferred.reject('Deleting ' + self.endpoint + ' failed');
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
ApiService.prototype.undoDelete = function(entity) {
|
||||
var self = this;
|
||||
entity.deletedAt = 0;
|
||||
|
||||
var promise = this.update(entity);
|
||||
|
||||
promise.then(() => {
|
||||
self.data[entity.id] = entity;
|
||||
delete this.deleted[entity.id];
|
||||
});
|
||||
|
||||
return promise;
|
||||
};
|
||||
|
||||
// methods for managing data
|
||||
ApiService.prototype.clear = function () {
|
||||
this.data = {};
|
||||
};
|
||||
|
||||
ApiService.prototype.add = function (entity) {
|
||||
var element = this.data[entity.id];
|
||||
if (element === undefined) {
|
||||
this.data[entity.id] = entity;
|
||||
} else {
|
||||
Object.keys(entity).forEach(function (key) {
|
||||
if (entity[key] !== null && element[key] !== entity[key]) {
|
||||
element[key] = entity[key];
|
||||
}
|
||||
});
|
||||
element.status = {};
|
||||
}
|
||||
};
|
||||
|
||||
ApiService.prototype.addAll = function (entities) {
|
||||
var self = this;
|
||||
angular.forEach(entities, function (entity) {
|
||||
self.add(entity);
|
||||
});
|
||||
};
|
||||
|
||||
ApiService.prototype.getCurrent = function () {
|
||||
return this.data[this.id];
|
||||
};
|
||||
|
||||
ApiService.prototype.unsetCurrrent = function () {
|
||||
this.id = null;
|
||||
};
|
||||
|
||||
|
||||
ApiService.prototype.getData = function () {
|
||||
return $.map(this.data, function (value, index) {
|
||||
return [value];
|
||||
});
|
||||
};
|
||||
|
||||
ApiService.prototype.getAll = function () {
|
||||
return this.data;
|
||||
};
|
||||
|
||||
ApiService.prototype.get = function (id) {
|
||||
return this.data[id];
|
||||
};
|
||||
|
||||
ApiService.prototype.getName = function () {
|
||||
var funcNameRegex = /function (.{1,})\(/;
|
||||
var results = (funcNameRegex).exec((this).constructor.toString());
|
||||
return (results && results.length > 1) ? results[1] : '';
|
||||
};
|
||||
|
||||
return ApiService;
|
||||
|
||||
});
|
||||
@@ -1,272 +0,0 @@
|
||||
/*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
/* global app OC angular */
|
||||
app.factory('BoardService', function (ApiService, $http, $q) {
|
||||
var BoardService = function ($http, ep, $q) {
|
||||
ApiService.call(this, $http, ep, $q);
|
||||
};
|
||||
BoardService.prototype = angular.copy(ApiService.prototype);
|
||||
|
||||
BoardService.prototype.delete = function (id) {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
|
||||
$http.delete(this.baseUrl + '/' + id).then(function (response) {
|
||||
self.data[id].deletedAt = response.data.deletedAt;
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Deleting ' + self.endpoint + ' failed');
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
BoardService.prototype.deleteUndo = function (id) {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
var _id = id;
|
||||
$http.post(this.baseUrl + '/' + id + '/deleteUndo').then(function (response) {
|
||||
self.data[_id].deletedAt = 0;
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Deleting ' + self.endpoint + ' failed');
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
BoardService.prototype.searchUsers = function (search) {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
var searchData = {
|
||||
format: 'json',
|
||||
perPage: 4,
|
||||
itemType: [0, 1, 7]
|
||||
};
|
||||
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 = [];
|
||||
|
||||
var users = response.ocs.data.exact.users.concat(response.ocs.data.users.slice(0, 4));
|
||||
var groups = response.ocs.data.exact.groups.concat(response.ocs.data.groups.slice(0, 4));
|
||||
var circles = response.ocs.data.exact.groups.concat(response.ocs.data.circles.slice(0, 4));
|
||||
|
||||
// filter out everyone who is already in the share list
|
||||
angular.forEach(users, function (item) {
|
||||
var acl = self.generateAcl(OC.Share.SHARE_TYPE_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(OC.Share.SHARE_TYPE_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);
|
||||
}
|
||||
});
|
||||
angular.forEach(circles, function (item) {
|
||||
var acl = self.generateAcl(OC.Share.SHARE_TYPE_CIRCLE, 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);
|
||||
}
|
||||
});
|
||||
|
||||
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: false,
|
||||
permissionShare: false,
|
||||
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;
|
||||
if (response.data.type === OC.Share.SHARE_TYPE_USER) {
|
||||
self._updateUsers();
|
||||
} else {
|
||||
self.fetchOne(response.data.boardId);
|
||||
}
|
||||
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();
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
$http.delete(this.baseUrl + '/' + acl.boardId + '/acl/' + acl.id).then(function (response) {
|
||||
var index = board.acl.findIndex((item) => item.id === response.data.id);
|
||||
delete board.acl[index];
|
||||
if (response.data.type === OC.Share.SHARE_TYPE_USER) {
|
||||
self._updateUsers();
|
||||
} else {
|
||||
self.fetchOne(response.data.boardId);
|
||||
}
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Error deleting ACL ' + acl.id);
|
||||
});
|
||||
acl = null;
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
BoardService.prototype.updateAcl = function (acl) {
|
||||
var board = this.getCurrent();
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
var _acl = acl;
|
||||
$http.put(this.baseUrl + '/' + acl.boardId + '/acl', _acl).then(function (response) {
|
||||
var index = board.acl.findIndex((item) => item.id === _acl.id);
|
||||
board.acl[index] = response.data;
|
||||
if (response.data.type === OC.Share.SHARE_TYPE_USER) {
|
||||
self._updateUsers();
|
||||
} else {
|
||||
self.fetchOne(response.data.boardId);
|
||||
}
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Error updating ACL ' + _acl);
|
||||
});
|
||||
acl = null;
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
BoardService.prototype._updateUsers = function () {
|
||||
if (!this.getCurrent() || !this.getCurrent().acl) {
|
||||
return [];
|
||||
}
|
||||
|
||||
this.getCurrent().users = [this.getCurrent().owner];
|
||||
let self = this;
|
||||
angular.forEach(this.getCurrent().acl, function(value, key) {
|
||||
if (value.type === OC.Share.SHARE_TYPE_USER) {
|
||||
self.getCurrent().users.push(value.participant);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
BoardService.prototype.getUsers = function () {
|
||||
if (this.getCurrent() && !this.getCurrent().users) {
|
||||
this._updateUsers();
|
||||
}
|
||||
return this.getCurrent().users;
|
||||
};
|
||||
|
||||
BoardService.prototype.canRead = function () {
|
||||
if (!this.getCurrent() || !this.getCurrent().permissions) {
|
||||
return false;
|
||||
}
|
||||
return this.getCurrent().permissions['PERMISSION_READ'];
|
||||
};
|
||||
|
||||
BoardService.prototype.canEdit = function () {
|
||||
if (!this.getCurrent() || !this.getCurrent().permissions) {
|
||||
return false;
|
||||
}
|
||||
return this.getCurrent().permissions['PERMISSION_EDIT'];
|
||||
};
|
||||
|
||||
BoardService.prototype.canManage = function (board) {
|
||||
if (board !== null && board !== undefined) {
|
||||
return board.permissions['PERMISSION_MANAGE'];
|
||||
}
|
||||
if (!this.getCurrent() || !this.getCurrent().permissions) {
|
||||
return false;
|
||||
}
|
||||
return this.getCurrent().permissions['PERMISSION_MANAGE'];
|
||||
};
|
||||
|
||||
BoardService.prototype.canShare = function () {
|
||||
if (!this.getCurrent() || !this.getCurrent().permissions) {
|
||||
return false;
|
||||
}
|
||||
return this.getCurrent().permissions['PERMISSION_SHARE'];
|
||||
};
|
||||
|
||||
BoardService.prototype.isArchived = function () {
|
||||
if (!this.getCurrent() || this.getCurrent().archived) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
return new BoardService($http, 'boards', $q);
|
||||
|
||||
});
|
||||
@@ -1,177 +0,0 @@
|
||||
/*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
app.factory('CardService', function (ApiService, $http, $q) {
|
||||
var CardService = function ($http, ep, $q) {
|
||||
ApiService.call(this, $http, ep, $q);
|
||||
};
|
||||
CardService.prototype = angular.copy(ApiService.prototype);
|
||||
|
||||
CardService.prototype.reorder = function (card, order) {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
$http.put(this.baseUrl + '/' + card.id + '/reorder', {
|
||||
cardId: card.id,
|
||||
order: order,
|
||||
stackId: card.stackId
|
||||
}).then(function (response) {
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Error while update ' + self.endpoint);
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
CardService.prototype.rename = function (card) {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
$http.put(this.baseUrl + '/' + card.id + '/rename', {
|
||||
cardId: card.id,
|
||||
title: card.title
|
||||
}).then(function (response) {
|
||||
self.data[card.id].title = card.title;
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Error while renaming ' + self.endpoint);
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
CardService.prototype.assignLabel = function (card, label) {
|
||||
var url = this.baseUrl + '/' + card + '/label/' + label;
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
$http.post(url).then(function (response) {
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Error while update ' + self.endpoint);
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
CardService.prototype.removeLabel = function (card, label) {
|
||||
var url = this.baseUrl + '/' + card + '/label/' + label;
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
$http.delete(url).then(function (response) {
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Error while update ' + self.endpoint);
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
CardService.prototype.archive = function (card) {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
$http.put(this.baseUrl + '/' + card.id + '/archive', {}).then(function (response) {
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Error while update ' + self.endpoint);
|
||||
});
|
||||
return deferred.promise;
|
||||
|
||||
};
|
||||
|
||||
CardService.prototype.unarchive = function (card) {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
$http.put(this.baseUrl + '/' + card.id + '/unarchive', {}).then(function (response) {
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Error while update ' + self.endpoint);
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
CardService.prototype.assignUser = function (card, user) {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
if (self.get(card.id).assignedUsers === null) {
|
||||
self.get(card.id).assignedUsers = [];
|
||||
}
|
||||
$http.post(this.baseUrl + '/' + card.id + '/assign', {'userId': user}).then(function (response) {
|
||||
self.get(card.id).assignedUsers.push(response.data);
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Error while update ' + self.endpoint);
|
||||
});
|
||||
return deferred.promise;
|
||||
|
||||
};
|
||||
|
||||
CardService.prototype.unassignUser = function (card, user) {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
$http.delete(this.baseUrl + '/' + card.id + '/assign/' + user, {}).then(function (response) {
|
||||
self.get(card.id).assignedUsers = self.get(card.id).assignedUsers.filter(function (obj) {
|
||||
return obj.participant.uid !== user;
|
||||
});
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Error while update ' + self.endpoint);
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
CardService.prototype.attachmentRemove = function (attachment) {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
$http.delete(this.baseUrl + '/' + this.getCurrent().id + '/attachment/' + attachment.id, {}).then(function (response) {
|
||||
if (response.data.deletedAt > 0) {
|
||||
let currentAttachment = self.getCurrent().attachments.find(function (obj) {
|
||||
if (obj.id === attachment.id) {
|
||||
obj.deletedAt = response.data.deletedAt;
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
self.getCurrent().attachments = self.getCurrent().attachments.filter(function (obj) {
|
||||
return obj.id !== attachment.id;
|
||||
});
|
||||
}
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Error when removing the attachment');
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
CardService.prototype.attachmentRemoveUndo = function (attachment) {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
$http.get(this.baseUrl + '/' + this.getCurrent().id + '/attachment/' + attachment.id + '/restore', {}).then(function (response) {
|
||||
let currentAttachment = self.getCurrent().attachments.find(function (obj) {
|
||||
if (obj.id === attachment.id) {
|
||||
obj.deletedAt = response.data.deletedAt;
|
||||
}
|
||||
});
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Error when restoring the attachment');
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
var service = new CardService($http, 'cards', $q);
|
||||
return service;
|
||||
});
|
||||
@@ -1,137 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2018 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
import app from '../app/App.js';
|
||||
|
||||
/* global OC oc_requesttoken */
|
||||
export default class FileService {
|
||||
|
||||
constructor (FileUploader, CardService, $rootScope, $filter) {
|
||||
this.$filter = $filter;
|
||||
this.uploader = new FileUploader();
|
||||
this.cardservice = CardService;
|
||||
this.uploader.onAfterAddingFile = this.onAfterAddingFile.bind(this);
|
||||
this.uploader.onSuccessItem = this.onSuccessItem.bind(this);
|
||||
this.uploader.onErrorItem = this.onErrorItem.bind(this);
|
||||
this.uploader.onCancelItem = this.onCancelItem.bind(this);
|
||||
|
||||
this.maxUploadSize = $rootScope.config.maxUploadSize;
|
||||
this.progress = [];
|
||||
this.status = null;
|
||||
}
|
||||
|
||||
reset () {
|
||||
this.status = null;
|
||||
}
|
||||
|
||||
runUpload (fileItem, attachmentId) {
|
||||
this.status = null;
|
||||
fileItem.url = OC.generateUrl('/apps/deck/cards/' + fileItem.cardId + '/attachment?type=deck_file');
|
||||
if (typeof attachmentId !== 'undefined') {
|
||||
fileItem.url = OC.generateUrl('/apps/deck/cards/' + fileItem.cardId + '/attachment/' + attachmentId + '?type=deck_file');
|
||||
} else {
|
||||
fileItem.formData = [
|
||||
{
|
||||
requesttoken: oc_requesttoken,
|
||||
type: 'deck_file',
|
||||
}
|
||||
];
|
||||
}
|
||||
fileItem.headers = {requesttoken: oc_requesttoken};
|
||||
|
||||
this.uploader.uploadItem(fileItem);
|
||||
}
|
||||
|
||||
onAfterAddingFile (fileItem) {
|
||||
if (this.maxUploadSize > 0 && fileItem.file.size > this.maxUploadSize) {
|
||||
this.status = {
|
||||
error: t('deck', `Failed to upload {name}`, {name: fileItem.file.name}),
|
||||
message: t('deck', 'Maximum file size of {size} exceeded', {size: this.$filter('bytes')(this.maxUploadSize)})
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
// Fetch card details before trying to upload so we can detect filename collisions properly
|
||||
let self = this;
|
||||
this.progress.push(fileItem);
|
||||
this.cardservice.fetchOne(fileItem.cardId).then(function (data) {
|
||||
let attachments = self.cardservice.get(fileItem.cardId).attachments;
|
||||
let existingFile = attachments.find((attachment) => {
|
||||
return attachment.data === fileItem.file.name;
|
||||
});
|
||||
if (typeof existingFile !== 'undefined') {
|
||||
OC.dialogs.confirm(
|
||||
t('deck', `A file with the name ${fileItem.file.name} already exists. Do you want to overwrite it?`),
|
||||
t('deck', 'File already exists'),
|
||||
function (result) {
|
||||
if (result) {
|
||||
self.runUpload(fileItem, existingFile.id);
|
||||
} else {
|
||||
let fileName = existingFile.extendedData.info.filename;
|
||||
let foundFilesMatching = attachments.filter((attachment) => {
|
||||
return attachment.extendedData.info.extension === existingFile.extendedData.info.extension
|
||||
&& attachment.extendedData.info.filename.startsWith(fileName);
|
||||
});
|
||||
let nextIndex = foundFilesMatching.length + 1;
|
||||
fileItem.file.name = fileName + ' (' + nextIndex + ').' + existingFile.extendedData.info.extension;
|
||||
self.runUpload(fileItem);
|
||||
}
|
||||
}
|
||||
);
|
||||
} else {
|
||||
self.runUpload(fileItem);
|
||||
}
|
||||
}, function (error) {
|
||||
this.progress = this.progress.filter((item) => (fileItem.file.name !== item.file.name));
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
onSuccessItem (item, response) {
|
||||
let attachments = this.cardservice.get(item.cardId).attachments;
|
||||
let index = attachments.indexOf(attachments.find((attachment) => attachment.id === response.id));
|
||||
if (~index) {
|
||||
attachments = attachments.splice(index, 1);
|
||||
}
|
||||
this.cardservice.get(item.cardId).attachments.push(response);
|
||||
this.progress = this.progress.filter((fileItem) => (fileItem.file.name !== item.file.name));
|
||||
}
|
||||
|
||||
onErrorItem (item, response) {
|
||||
this.progress = this.progress.filter((fileItem) => (fileItem.file.name !== item.file.name));
|
||||
this.status = {
|
||||
error: t('deck', `Failed to upload:`) + ' ' + item.file.name,
|
||||
message: response.message
|
||||
};
|
||||
}
|
||||
|
||||
onCancelItem (item) {
|
||||
this.progress = this.progress.filter((fileItem) => (fileItem.file.name !== item.file.name));
|
||||
}
|
||||
|
||||
getProgressItemsForCard (cardId) {
|
||||
return this.progress.filter((fileItem) => (fileItem.cardId === cardId));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
app.service('FileService', FileService);
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
app.factory('LabelService', function (ApiService, $http, $q) {
|
||||
var LabelService = function ($http, ep, $q) {
|
||||
ApiService.call(this, $http, ep, $q);
|
||||
};
|
||||
LabelService.prototype = angular.copy(ApiService.prototype);
|
||||
return new LabelService($http, 'labels', $q);
|
||||
});
|
||||
@@ -1,139 +0,0 @@
|
||||
/*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
/* global app angular */
|
||||
app.factory('StackService', function (ApiService, CardService, $http, $q) {
|
||||
var StackService = function ($http, ep, $q) {
|
||||
ApiService.call(this, $http, ep, $q);
|
||||
};
|
||||
StackService.prototype = angular.copy(ApiService.prototype);
|
||||
|
||||
StackService.prototype.afterFetch = function(stack) {
|
||||
CardService.addAll(stack.cards);
|
||||
};
|
||||
|
||||
StackService.prototype.fetchAll = function (boardId) {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
$http.get(this.baseUrl + '/' + boardId).then(function (response) {
|
||||
self.clear();
|
||||
self.addAll(response.data);
|
||||
// When loading a stack add cards to the CardService so we can fetch
|
||||
// information from there. That way we don't need to refresh the whole
|
||||
// stack data during digest if some value changes
|
||||
angular.forEach(response.data, function (entity) {
|
||||
CardService.addAll(entity.cards);
|
||||
});
|
||||
deferred.resolve(self.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Error while loading stacks');
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
StackService.prototype.fetchArchived = function (boardId) {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
$http.get(this.baseUrl + '/' + boardId + '/archived').then(function (response) {
|
||||
self.clear();
|
||||
self.addAll(response.data);
|
||||
angular.forEach(response.data, function (entity) {
|
||||
CardService.addAll(entity.cards);
|
||||
});
|
||||
deferred.resolve(self.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Error while loading stacks');
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
StackService.prototype.addCard = function (entity) {
|
||||
if (!this.data[entity.stackId].cards) {
|
||||
this.data[entity.stackId].cards = [];
|
||||
}
|
||||
this.data[entity.stackId].cards.push(entity);
|
||||
};
|
||||
|
||||
StackService.prototype.reorder = function (stack, order) {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
$http.put(this.baseUrl + '/' + stack.id + '/reorder', {
|
||||
stackId: stack.id,
|
||||
order: order
|
||||
}).then(function (response) {
|
||||
angular.forEach(response.data, function (value, key) {
|
||||
var id = value.id;
|
||||
self.data[id].order = value.order;
|
||||
});
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Error while update ' + self.endpoint);
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
StackService.prototype.reorderCard = function (entity, order) {
|
||||
// assign new order
|
||||
for (var i = 0, j = 0; i < this.data[entity.stackId].cards.length; i++) {
|
||||
if (this.data[entity.stackId].cards[i].id === entity.id) {
|
||||
this.data[entity.stackId].cards[i].order = order;
|
||||
}
|
||||
if (j === order) {
|
||||
j++;
|
||||
}
|
||||
if (this.data[entity.stackId].cards[i].id !== entity.id) {
|
||||
this.data[entity.stackId].cards[i].order = j++;
|
||||
}
|
||||
}
|
||||
// sort array by order
|
||||
this.data[entity.stackId].cards.sort(function (a, b) {
|
||||
if (a.order < b.order)
|
||||
{return -1;}
|
||||
if (a.order > b.order)
|
||||
{return 1;}
|
||||
return 0;
|
||||
});
|
||||
};
|
||||
|
||||
StackService.prototype.updateCard = function (entity) {
|
||||
var self = this;
|
||||
var cards = this.data[entity.stackId].cards;
|
||||
for (var i = 0; i < cards.length; i++) {
|
||||
if (cards[i].id === entity.id) {
|
||||
cards[i] = entity;
|
||||
}
|
||||
}
|
||||
};
|
||||
StackService.prototype.removeCard = function (entity) {
|
||||
var self = this;
|
||||
var cards = this.data[entity.stackId].cards;
|
||||
for (var i = 0; i < cards.length; i++) {
|
||||
if (cards[i].id === entity.id) {
|
||||
cards.splice(i, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var service = new StackService($http, 'stacks', $q);
|
||||
return service;
|
||||
});
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
app.factory('StatusService', function () {
|
||||
// Status Helper
|
||||
var StatusService = function () {
|
||||
this.active = true;
|
||||
this.icon = 'loading';
|
||||
this.title = '';
|
||||
this.text = '';
|
||||
this.counter = 0;
|
||||
};
|
||||
|
||||
|
||||
StatusService.prototype.setStatus = function ($icon, $title, $text) {
|
||||
this.active = true;
|
||||
this.icon = $icon;
|
||||
this.title = $title;
|
||||
this.text = $text;
|
||||
};
|
||||
|
||||
StatusService.prototype.setError = function ($title, $text) {
|
||||
this.active = true;
|
||||
this.icon = 'error';
|
||||
this.title = $title;
|
||||
this.text = $text;
|
||||
this.counter = 0;
|
||||
};
|
||||
|
||||
StatusService.prototype.releaseWaiting = function () {
|
||||
if (this.counter > 0) {
|
||||
this.counter--;
|
||||
}
|
||||
if (this.counter <= 0) {
|
||||
this.active = false;
|
||||
this.counter = 0;
|
||||
}
|
||||
};
|
||||
|
||||
StatusService.prototype.retainWaiting = function () {
|
||||
this.active = true;
|
||||
this.icon = 'loading';
|
||||
this.title = '';
|
||||
this.text = '';
|
||||
this.counter++;
|
||||
};
|
||||
|
||||
StatusService.prototype.unsetStatus = function () {
|
||||
this.active = false;
|
||||
};
|
||||
|
||||
return {
|
||||
getInstance: function () {
|
||||
return new StatusService();
|
||||
},
|
||||
/* Shared StatusService instance between both ListController instances */
|
||||
listStatus: new StatusService()
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
describe('BoardController', function() {
|
||||
'use strict';
|
||||
|
||||
var $controller;
|
||||
|
||||
beforeEach(inject(function(_$controller_){
|
||||
// The injector unwraps the underscores (_) from around the parameter names when matching
|
||||
$controller = _$controller_;
|
||||
}));
|
||||
|
||||
describe('$scope.rgblight', function() {
|
||||
it('converts rbg color to a lighter color', function() {
|
||||
var $scope = {};
|
||||
var controller = $controller('BoardController', { $scope: $scope });
|
||||
var hex = $scope.rgblight('red');
|
||||
expect(hex).toEqual('#red');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,76 +0,0 @@
|
||||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
const { VueLoaderPlugin } = require('vue-loader');
|
||||
|
||||
module.exports = {
|
||||
node: {
|
||||
fs: 'empty',
|
||||
},
|
||||
entry: {
|
||||
deck: ['./init.js'],
|
||||
collections: ['./init-collections.js']
|
||||
},
|
||||
output: {
|
||||
filename: '[name].js',
|
||||
path: __dirname + '/build'
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: ['vue-style-loader', 'style-loader', 'css-loader']
|
||||
},
|
||||
{
|
||||
test: /\.vue$/,
|
||||
loader: 'vue-loader'
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
exclude: /node_modules/,
|
||||
loader: 'babel-loader',
|
||||
query: {
|
||||
presets: ['@babel/preset-env'],
|
||||
plugins: ['@babel/plugin-syntax-dynamic-import']
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.scss$/,
|
||||
use: [
|
||||
'vue-style-loader',
|
||||
'css-loader',
|
||||
'sass-loader'
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpg|gif|svg)$/,
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
name: '[name].[ext]?[hash]'
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
/* use external jQuery from server */
|
||||
externals: {
|
||||
'jquery': 'jQuery'
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
vue$: 'vue/dist/vue.esm.js'
|
||||
},
|
||||
extensions: ['*', '.js', '.vue', '.json'],
|
||||
modules: [
|
||||
path.resolve(__dirname),
|
||||
path.join(__dirname, 'node_modules'),
|
||||
'node_modules'
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
new VueLoaderPlugin(),
|
||||
new webpack.ProvidePlugin({
|
||||
$: 'jquery',
|
||||
jQuery: 'jquery'
|
||||
})
|
||||
]
|
||||
};
|
||||
@@ -1,7 +0,0 @@
|
||||
const merge = require('webpack-merge');
|
||||
const baseConfig = require('./webpack.config.js');
|
||||
|
||||
module.exports = merge(baseConfig, {
|
||||
mode: 'development',
|
||||
devtool: 'source-map',
|
||||
});
|
||||
@@ -1,18 +0,0 @@
|
||||
const webpack = require('webpack');
|
||||
const merge = require('webpack-merge');
|
||||
const baseConfig = require('./webpack.config.js');
|
||||
const TerserPlugin = require('terser-webpack-plugin');
|
||||
|
||||
|
||||
module.exports = merge(baseConfig, {
|
||||
mode: 'production',
|
||||
devtool: '#source-map',
|
||||
optimization: {
|
||||
minimize: true,
|
||||
minimizer: [
|
||||
new TerserPlugin({
|
||||
test: /vendor\.js(\?.*)?$/i,
|
||||
}),
|
||||
],
|
||||
},
|
||||
});
|
||||
@@ -1,4 +1,38 @@
|
||||
[package]
|
||||
exclude = [
|
||||
"build/",
|
||||
".git",
|
||||
"js/node_modules",
|
||||
"js/tests",
|
||||
"js/legacy",
|
||||
"js/controller",
|
||||
"js/directive",
|
||||
"js/filters",
|
||||
"js/service",
|
||||
"js/bower.json",
|
||||
"js/.bowerrc",
|
||||
"js/.jshintrc",
|
||||
"js/Gruntfile.js",
|
||||
"js/package.json",
|
||||
"js/package-lock.json",
|
||||
"docs/",
|
||||
"tests",
|
||||
".codecov.yml",
|
||||
"composer.json",
|
||||
"composer.lock",
|
||||
"_config.yml",
|
||||
".drone.yml",
|
||||
".travis.yml",
|
||||
".eslintignore",
|
||||
".eslintrc.yml",
|
||||
".gitignore",
|
||||
"issue_template.md",
|
||||
"krankerl.toml",
|
||||
"Makefile",
|
||||
"mkdocs.yml",
|
||||
"run-eslint.sh"
|
||||
]
|
||||
|
||||
before_cmds = [
|
||||
'make clean-build',
|
||||
'make build'
|
||||
|
||||
33
l10n/af.js
33
l10n/af.js
@@ -1,33 +0,0 @@
|
||||
OC.L10N.register(
|
||||
"deck",
|
||||
{
|
||||
"Hours" : "Uur",
|
||||
"Minutes" : "Minute",
|
||||
"File already exists" : "Lêer bestaan reeds",
|
||||
"Personal" : "Persoonlik",
|
||||
"Done" : "Gereed",
|
||||
"The file was uploaded" : "Die lêer is opgelaai",
|
||||
"The uploaded file exceeds the upload_max_filesize directive in php.ini" : "Die opgelaaide lêer oorskry die upload_max_filesize riglyn in php.ini",
|
||||
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Die opgelaaide lêer oorskry die MAX_FILE_SIZE riglyn wat in die HTML vorm gespesifiseer is",
|
||||
"The file was only partially uploaded" : "Die lêer is slegs gedeeltelik op gelaai",
|
||||
"No file was uploaded" : "Geen lêer is opgelaai",
|
||||
"Missing a temporary folder" : "Ontbrekende tydelike gids",
|
||||
"A PHP extension stopped the file upload" : "’n PHP-uitbreiding het die oplaai gestaak",
|
||||
"Actions" : "Aksies",
|
||||
"Close" : "Sluit",
|
||||
"Tags" : "Etikette",
|
||||
"Group" : "Groep",
|
||||
"Loading" : "Laai tans..",
|
||||
"Edit" : "Wysig",
|
||||
"Share" : "Deel",
|
||||
"Create" : "Skep",
|
||||
"Title" : "Titel",
|
||||
"Cancel upload" : "Kanselleer oplaai",
|
||||
"by" : "deur",
|
||||
"Created:" : "Geskep:",
|
||||
"Due date" : "Sperdatum",
|
||||
"Description" : "Beskrywing",
|
||||
"Saved" : "Bewaar",
|
||||
"Settings" : "Instellings"
|
||||
},
|
||||
"nplurals=2; plural=(n != 1);");
|
||||
31
l10n/af.json
31
l10n/af.json
@@ -1,31 +0,0 @@
|
||||
{ "translations": {
|
||||
"Hours" : "Uur",
|
||||
"Minutes" : "Minute",
|
||||
"File already exists" : "Lêer bestaan reeds",
|
||||
"Personal" : "Persoonlik",
|
||||
"Done" : "Gereed",
|
||||
"The file was uploaded" : "Die lêer is opgelaai",
|
||||
"The uploaded file exceeds the upload_max_filesize directive in php.ini" : "Die opgelaaide lêer oorskry die upload_max_filesize riglyn in php.ini",
|
||||
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Die opgelaaide lêer oorskry die MAX_FILE_SIZE riglyn wat in die HTML vorm gespesifiseer is",
|
||||
"The file was only partially uploaded" : "Die lêer is slegs gedeeltelik op gelaai",
|
||||
"No file was uploaded" : "Geen lêer is opgelaai",
|
||||
"Missing a temporary folder" : "Ontbrekende tydelike gids",
|
||||
"A PHP extension stopped the file upload" : "’n PHP-uitbreiding het die oplaai gestaak",
|
||||
"Actions" : "Aksies",
|
||||
"Close" : "Sluit",
|
||||
"Tags" : "Etikette",
|
||||
"Group" : "Groep",
|
||||
"Loading" : "Laai tans..",
|
||||
"Edit" : "Wysig",
|
||||
"Share" : "Deel",
|
||||
"Create" : "Skep",
|
||||
"Title" : "Titel",
|
||||
"Cancel upload" : "Kanselleer oplaai",
|
||||
"by" : "deur",
|
||||
"Created:" : "Geskep:",
|
||||
"Due date" : "Sperdatum",
|
||||
"Description" : "Beskrywing",
|
||||
"Saved" : "Bewaar",
|
||||
"Settings" : "Instellings"
|
||||
},"pluralForm" :"nplurals=2; plural=(n != 1);"
|
||||
}
|
||||
24
l10n/ar.js
24
l10n/ar.js
@@ -4,39 +4,15 @@ OC.L10N.register(
|
||||
"Hours" : "ساعات",
|
||||
"Minutes" : "دقائق",
|
||||
"File already exists" : "الملف موجود مسبقاً",
|
||||
"Personal" : "شخصي",
|
||||
"Finished" : "مكتملة",
|
||||
"Done" : "تم",
|
||||
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "حجم الملف الذي تريد ترفيعه أعلى مما MAX_FILE_SIZE يسمح به في واجهة ال HTML.",
|
||||
"No file was uploaded" : "لم يتم رفع أي ملف",
|
||||
"Missing a temporary folder" : "المجلد المؤقت غير موجود",
|
||||
"Actions" : "الإجراءات",
|
||||
"Delete card" : "حذف البطاقة",
|
||||
"Close" : "إغلاق",
|
||||
"Sharing" : "المشاركة",
|
||||
"Tags" : "الوسوم",
|
||||
"Timeline" : "الخيط الزمني",
|
||||
"Group" : "الفريق",
|
||||
"Circle" : "حلقة",
|
||||
"Loading" : "Loading",
|
||||
"Edit" : "تعديل",
|
||||
"Share" : "شارك",
|
||||
"Update tag" : "تحديث الوسم",
|
||||
"Edit tag" : "تعديل الوسم",
|
||||
"Delete tag" : "حذف الوسم",
|
||||
"Create" : "إنشاء",
|
||||
"Status" : "الحالة",
|
||||
"Title" : "العنوان",
|
||||
"More actions" : "إجراءات أخرى",
|
||||
"Cancel upload" : "إلغاء الرفع",
|
||||
"by" : "من قبل",
|
||||
"Delete attachment" : "حذف المرفق",
|
||||
"Modified:" : "عُدل في :",
|
||||
"Created:" : "تاريخ الإنشاء :",
|
||||
"Description" : "الوصف",
|
||||
"Attachments" : "المرفقات",
|
||||
"Saved" : "تم الإحتفاظ به",
|
||||
"Upload attachment" : "رفع المرفقات",
|
||||
"Settings" : "الإعدادات"
|
||||
},
|
||||
"nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;");
|
||||
|
||||
24
l10n/ar.json
24
l10n/ar.json
@@ -2,39 +2,15 @@
|
||||
"Hours" : "ساعات",
|
||||
"Minutes" : "دقائق",
|
||||
"File already exists" : "الملف موجود مسبقاً",
|
||||
"Personal" : "شخصي",
|
||||
"Finished" : "مكتملة",
|
||||
"Done" : "تم",
|
||||
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "حجم الملف الذي تريد ترفيعه أعلى مما MAX_FILE_SIZE يسمح به في واجهة ال HTML.",
|
||||
"No file was uploaded" : "لم يتم رفع أي ملف",
|
||||
"Missing a temporary folder" : "المجلد المؤقت غير موجود",
|
||||
"Actions" : "الإجراءات",
|
||||
"Delete card" : "حذف البطاقة",
|
||||
"Close" : "إغلاق",
|
||||
"Sharing" : "المشاركة",
|
||||
"Tags" : "الوسوم",
|
||||
"Timeline" : "الخيط الزمني",
|
||||
"Group" : "الفريق",
|
||||
"Circle" : "حلقة",
|
||||
"Loading" : "Loading",
|
||||
"Edit" : "تعديل",
|
||||
"Share" : "شارك",
|
||||
"Update tag" : "تحديث الوسم",
|
||||
"Edit tag" : "تعديل الوسم",
|
||||
"Delete tag" : "حذف الوسم",
|
||||
"Create" : "إنشاء",
|
||||
"Status" : "الحالة",
|
||||
"Title" : "العنوان",
|
||||
"More actions" : "إجراءات أخرى",
|
||||
"Cancel upload" : "إلغاء الرفع",
|
||||
"by" : "من قبل",
|
||||
"Delete attachment" : "حذف المرفق",
|
||||
"Modified:" : "عُدل في :",
|
||||
"Created:" : "تاريخ الإنشاء :",
|
||||
"Description" : "الوصف",
|
||||
"Attachments" : "المرفقات",
|
||||
"Saved" : "تم الإحتفاظ به",
|
||||
"Upload attachment" : "رفع المرفقات",
|
||||
"Settings" : "الإعدادات"
|
||||
},"pluralForm" :"nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;"
|
||||
}
|
||||
23
l10n/ast.js
23
l10n/ast.js
@@ -3,48 +3,27 @@ OC.L10N.register(
|
||||
{
|
||||
"Hours" : "Hores",
|
||||
"Minutes" : "Minutos",
|
||||
"File already exists" : "Yá esiste'l ficheru",
|
||||
"Deck" : "Deck",
|
||||
"Personal" : "Personal",
|
||||
"Finished" : "Finó",
|
||||
"Action needed" : "Precísase aición",
|
||||
"Later" : "Más sero",
|
||||
"Done" : "Fecho",
|
||||
"The file was uploaded" : "Xubióse'l ficheru",
|
||||
"The uploaded file exceeds the upload_max_filesize directive in php.ini" : "El ficheru xubíu perpasa la direutiva de xuba upload_max_filesize en php.ini",
|
||||
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "El ficheru xubíu perpasa la direutiva \"MAX_FILE_SIZE\" especificada nel formulariu HTML",
|
||||
"No file was uploaded" : "Nun se xubieron fichjeros",
|
||||
"Missing a temporary folder" : "Falta un direutoriu temporal",
|
||||
"Could not write file to disk" : "Nun pudo escribise nel discu'l ficheru",
|
||||
"A PHP extension stopped the file upload" : "Una estensión de PHP paró la xuba de ficheros",
|
||||
"Submit" : "Unviar",
|
||||
"Show archived cards" : "Amosar tarxetes archivaes",
|
||||
"Actions" : "Aiciones",
|
||||
"Close" : "Zarrar",
|
||||
"Sharing" : "Compartiendo",
|
||||
"Tags" : "Etiquetes",
|
||||
"Select users or groups to share with" : "Esbilla usuarios o grupos colos que compartir",
|
||||
"Group" : "Group",
|
||||
"Circle" : "Círculu",
|
||||
"No matching user or group found." : "Nun s'alcontró dengún usuariu o grupu que concasara.",
|
||||
"Loading" : "Cargando",
|
||||
"Edit" : "Editar",
|
||||
"Share" : "Compartir",
|
||||
"Manage" : "Xestionar",
|
||||
"Discard share" : "Escartar compartición",
|
||||
"Create" : "Crear",
|
||||
"Status" : "Estáu",
|
||||
"Title" : "Títulu",
|
||||
"Members" : "Miembros",
|
||||
"More actions" : "Más aiciones",
|
||||
"Cancel upload" : "Encaboxar xuba",
|
||||
"by" : "por",
|
||||
"Modified:" : "Modificáu:",
|
||||
"Created:" : "Creóse'l",
|
||||
"Click to set" : "Primi p'afitar",
|
||||
"Description" : "Descripción",
|
||||
"Attachments" : "Axuntos",
|
||||
"Saved" : "Guardóse",
|
||||
"Settings" : "Settings"
|
||||
"Saved" : "Guardóse"
|
||||
},
|
||||
"nplurals=2; plural=(n != 1);");
|
||||
|
||||
@@ -1,48 +1,27 @@
|
||||
{ "translations": {
|
||||
"Hours" : "Hores",
|
||||
"Minutes" : "Minutos",
|
||||
"File already exists" : "Yá esiste'l ficheru",
|
||||
"Deck" : "Deck",
|
||||
"Personal" : "Personal",
|
||||
"Finished" : "Finó",
|
||||
"Action needed" : "Precísase aición",
|
||||
"Later" : "Más sero",
|
||||
"Done" : "Fecho",
|
||||
"The file was uploaded" : "Xubióse'l ficheru",
|
||||
"The uploaded file exceeds the upload_max_filesize directive in php.ini" : "El ficheru xubíu perpasa la direutiva de xuba upload_max_filesize en php.ini",
|
||||
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "El ficheru xubíu perpasa la direutiva \"MAX_FILE_SIZE\" especificada nel formulariu HTML",
|
||||
"No file was uploaded" : "Nun se xubieron fichjeros",
|
||||
"Missing a temporary folder" : "Falta un direutoriu temporal",
|
||||
"Could not write file to disk" : "Nun pudo escribise nel discu'l ficheru",
|
||||
"A PHP extension stopped the file upload" : "Una estensión de PHP paró la xuba de ficheros",
|
||||
"Submit" : "Unviar",
|
||||
"Show archived cards" : "Amosar tarxetes archivaes",
|
||||
"Actions" : "Aiciones",
|
||||
"Close" : "Zarrar",
|
||||
"Sharing" : "Compartiendo",
|
||||
"Tags" : "Etiquetes",
|
||||
"Select users or groups to share with" : "Esbilla usuarios o grupos colos que compartir",
|
||||
"Group" : "Group",
|
||||
"Circle" : "Círculu",
|
||||
"No matching user or group found." : "Nun s'alcontró dengún usuariu o grupu que concasara.",
|
||||
"Loading" : "Cargando",
|
||||
"Edit" : "Editar",
|
||||
"Share" : "Compartir",
|
||||
"Manage" : "Xestionar",
|
||||
"Discard share" : "Escartar compartición",
|
||||
"Create" : "Crear",
|
||||
"Status" : "Estáu",
|
||||
"Title" : "Títulu",
|
||||
"Members" : "Miembros",
|
||||
"More actions" : "Más aiciones",
|
||||
"Cancel upload" : "Encaboxar xuba",
|
||||
"by" : "por",
|
||||
"Modified:" : "Modificáu:",
|
||||
"Created:" : "Creóse'l",
|
||||
"Click to set" : "Primi p'afitar",
|
||||
"Description" : "Descripción",
|
||||
"Attachments" : "Axuntos",
|
||||
"Saved" : "Guardóse",
|
||||
"Settings" : "Settings"
|
||||
"Saved" : "Guardóse"
|
||||
},"pluralForm" :"nplurals=2; plural=(n != 1);"
|
||||
}
|
||||
29
l10n/az.js
29
l10n/az.js
@@ -1,29 +0,0 @@
|
||||
OC.L10N.register(
|
||||
"deck",
|
||||
{
|
||||
"Hours" : "Saatlar",
|
||||
"Minutes" : "Dəqiqələr",
|
||||
"Personal" : "Şəxsi",
|
||||
"Done" : "Done",
|
||||
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Yüklənilən faylın həcmi HTML formasinda olan MAX_FILE_SIZE direktivində təyin dilmiş həcmi aşır.",
|
||||
"No file was uploaded" : "Heç bir fayl yüklənilmədi",
|
||||
"Missing a temporary folder" : "Müvəqqəti qovluq çatışmır",
|
||||
"Actions" : "İşlər",
|
||||
"Close" : "Bağla",
|
||||
"Sharing" : "Paylaşılır",
|
||||
"Tags" : "Işarələr",
|
||||
"Group" : "Qrup",
|
||||
"Loading" : "Loading",
|
||||
"Edit" : "Dəyişiklik et",
|
||||
"Share" : "Paylaş",
|
||||
"Create" : "Yarat",
|
||||
"Title" : "Başlıq",
|
||||
"Cancel upload" : "Yüklənməni dayandır",
|
||||
"by" : "onunla",
|
||||
"Modified:" : "Dəyişdirildi:",
|
||||
"Created:" : "Yaradıldı:",
|
||||
"Description" : "Açıqlanma",
|
||||
"Saved" : "Saxlanıldı",
|
||||
"Settings" : "Quraşdırmalar"
|
||||
},
|
||||
"nplurals=2; plural=(n != 1);");
|
||||
27
l10n/az.json
27
l10n/az.json
@@ -1,27 +0,0 @@
|
||||
{ "translations": {
|
||||
"Hours" : "Saatlar",
|
||||
"Minutes" : "Dəqiqələr",
|
||||
"Personal" : "Şəxsi",
|
||||
"Done" : "Done",
|
||||
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Yüklənilən faylın həcmi HTML formasinda olan MAX_FILE_SIZE direktivində təyin dilmiş həcmi aşır.",
|
||||
"No file was uploaded" : "Heç bir fayl yüklənilmədi",
|
||||
"Missing a temporary folder" : "Müvəqqəti qovluq çatışmır",
|
||||
"Actions" : "İşlər",
|
||||
"Close" : "Bağla",
|
||||
"Sharing" : "Paylaşılır",
|
||||
"Tags" : "Işarələr",
|
||||
"Group" : "Qrup",
|
||||
"Loading" : "Loading",
|
||||
"Edit" : "Dəyişiklik et",
|
||||
"Share" : "Paylaş",
|
||||
"Create" : "Yarat",
|
||||
"Title" : "Başlıq",
|
||||
"Cancel upload" : "Yüklənməni dayandır",
|
||||
"by" : "onunla",
|
||||
"Modified:" : "Dəyişdirildi:",
|
||||
"Created:" : "Yaradıldı:",
|
||||
"Description" : "Açıqlanma",
|
||||
"Saved" : "Saxlanıldı",
|
||||
"Settings" : "Quraşdırmalar"
|
||||
},"pluralForm" :"nplurals=2; plural=(n != 1);"
|
||||
}
|
||||
14
l10n/bg.js
14
l10n/bg.js
@@ -3,39 +3,25 @@ OC.L10N.register(
|
||||
{
|
||||
"Hours" : "Часове",
|
||||
"Minutes" : "Минути",
|
||||
"File already exists" : "Файлът вече съществува",
|
||||
"Personal" : "Лични",
|
||||
"Finished" : "Готово",
|
||||
"To review" : "За преглед",
|
||||
"Action needed" : "Необходимо е действие",
|
||||
"Later" : "По-късно",
|
||||
"Done" : "Готово",
|
||||
"The file was uploaded" : "Файлът е качен",
|
||||
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Размерът на файла надвишава максималния размер определен от MAX_FILE_SIZE в HTML формата.",
|
||||
"The file was only partially uploaded" : "Файлът е качен частично",
|
||||
"No file was uploaded" : "Нито един файл не е качен",
|
||||
"Missing a temporary folder" : "Липсва временна папка",
|
||||
"Submit" : "Изпращане",
|
||||
"Actions" : "Действия",
|
||||
"Close" : "Затваряне",
|
||||
"Sharing" : "Споделяне",
|
||||
"Tags" : "Етикети",
|
||||
"Select users or groups to share with" : "Споделяне с потребители или групи",
|
||||
"Group" : "Група",
|
||||
"Circle" : "Кръг",
|
||||
"No matching user or group found." : "Не са намерени съвпадащи потребители или групи",
|
||||
"Loading" : "Зареждане",
|
||||
"Edit" : "Редакция",
|
||||
"Share" : "Сподели",
|
||||
"Manage" : "Управление",
|
||||
"Discard share" : "Отхвърляне на споделяне",
|
||||
"Delete tag" : "Изтрий таг",
|
||||
"Create" : "Създай",
|
||||
"Create a new tag" : "Създаване на нов етикет",
|
||||
"Status" : "Състояние",
|
||||
"Title" : "Име",
|
||||
"Members" : "Членове",
|
||||
"More actions" : "Още действия",
|
||||
"Cancel upload" : "Откажи качването",
|
||||
"by" : "от",
|
||||
"Modified:" : "Променена:",
|
||||
|
||||
14
l10n/bg.json
14
l10n/bg.json
@@ -1,39 +1,25 @@
|
||||
{ "translations": {
|
||||
"Hours" : "Часове",
|
||||
"Minutes" : "Минути",
|
||||
"File already exists" : "Файлът вече съществува",
|
||||
"Personal" : "Лични",
|
||||
"Finished" : "Готово",
|
||||
"To review" : "За преглед",
|
||||
"Action needed" : "Необходимо е действие",
|
||||
"Later" : "По-късно",
|
||||
"Done" : "Готово",
|
||||
"The file was uploaded" : "Файлът е качен",
|
||||
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Размерът на файла надвишава максималния размер определен от MAX_FILE_SIZE в HTML формата.",
|
||||
"The file was only partially uploaded" : "Файлът е качен частично",
|
||||
"No file was uploaded" : "Нито един файл не е качен",
|
||||
"Missing a temporary folder" : "Липсва временна папка",
|
||||
"Submit" : "Изпращане",
|
||||
"Actions" : "Действия",
|
||||
"Close" : "Затваряне",
|
||||
"Sharing" : "Споделяне",
|
||||
"Tags" : "Етикети",
|
||||
"Select users or groups to share with" : "Споделяне с потребители или групи",
|
||||
"Group" : "Група",
|
||||
"Circle" : "Кръг",
|
||||
"No matching user or group found." : "Не са намерени съвпадащи потребители или групи",
|
||||
"Loading" : "Зареждане",
|
||||
"Edit" : "Редакция",
|
||||
"Share" : "Сподели",
|
||||
"Manage" : "Управление",
|
||||
"Discard share" : "Отхвърляне на споделяне",
|
||||
"Delete tag" : "Изтрий таг",
|
||||
"Create" : "Създай",
|
||||
"Create a new tag" : "Създаване на нов етикет",
|
||||
"Status" : "Състояние",
|
||||
"Title" : "Име",
|
||||
"Members" : "Членове",
|
||||
"More actions" : "Още действия",
|
||||
"Cancel upload" : "Откажи качването",
|
||||
"by" : "от",
|
||||
"Modified:" : "Променена:",
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
OC.L10N.register(
|
||||
"deck",
|
||||
{
|
||||
"Hours" : "ঘন্টা",
|
||||
"Minutes" : "মিনিট",
|
||||
"Personal" : "ব্যক্তিগত",
|
||||
"Done" : "Done",
|
||||
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "আপলোড করা ফাইলটি HTML ফর্মে উল্লিখিত MAX_FILE_SIZE নির্ধারিত ফাইলের সর্বোচ্চ আকার অতিক্রম করতে চলেছে ",
|
||||
"No file was uploaded" : "কোন ফাইল আপলোড করা হয় নি",
|
||||
"Missing a temporary folder" : "অস্থায়ী ফোল্ডারটি হারানো গিয়েছে",
|
||||
"Actions" : "পদক্ষেপসমূহ",
|
||||
"Close" : "বন্ধ",
|
||||
"Sharing" : "ভাগাভাগিরত",
|
||||
"Tags" : "ট্যাগ",
|
||||
"Group" : "গোষ্ঠীসমূহ",
|
||||
"Loading" : "Loading",
|
||||
"Edit" : "সম্পাদনা",
|
||||
"Share" : "ভাগাভাগি কর",
|
||||
"Create" : "তৈরী কর",
|
||||
"Title" : "শিরোনাম",
|
||||
"Cancel upload" : "আপলোড বাতিল কর",
|
||||
"by" : "কর্তৃক",
|
||||
"Modified:" : "পরিবর্তিতঃ",
|
||||
"Created:" : "তৈরীর নির্ঘন্টঃ",
|
||||
"Description" : "বিবরণ",
|
||||
"Saved" : "সংরক্ষণ করা হলো",
|
||||
"Settings" : "সেটিংস"
|
||||
},
|
||||
"nplurals=2; plural=(n != 1);");
|
||||
@@ -1,27 +0,0 @@
|
||||
{ "translations": {
|
||||
"Hours" : "ঘন্টা",
|
||||
"Minutes" : "মিনিট",
|
||||
"Personal" : "ব্যক্তিগত",
|
||||
"Done" : "Done",
|
||||
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "আপলোড করা ফাইলটি HTML ফর্মে উল্লিখিত MAX_FILE_SIZE নির্ধারিত ফাইলের সর্বোচ্চ আকার অতিক্রম করতে চলেছে ",
|
||||
"No file was uploaded" : "কোন ফাইল আপলোড করা হয় নি",
|
||||
"Missing a temporary folder" : "অস্থায়ী ফোল্ডারটি হারানো গিয়েছে",
|
||||
"Actions" : "পদক্ষেপসমূহ",
|
||||
"Close" : "বন্ধ",
|
||||
"Sharing" : "ভাগাভাগিরত",
|
||||
"Tags" : "ট্যাগ",
|
||||
"Group" : "গোষ্ঠীসমূহ",
|
||||
"Loading" : "Loading",
|
||||
"Edit" : "সম্পাদনা",
|
||||
"Share" : "ভাগাভাগি কর",
|
||||
"Create" : "তৈরী কর",
|
||||
"Title" : "শিরোনাম",
|
||||
"Cancel upload" : "আপলোড বাতিল কর",
|
||||
"by" : "কর্তৃক",
|
||||
"Modified:" : "পরিবর্তিতঃ",
|
||||
"Created:" : "তৈরীর নির্ঘন্টঃ",
|
||||
"Description" : "বিবরণ",
|
||||
"Saved" : "সংরক্ষণ করা হলো",
|
||||
"Settings" : "সেটিংস"
|
||||
},"pluralForm" :"nplurals=2; plural=(n != 1);"
|
||||
}
|
||||
15
l10n/bs.js
15
l10n/bs.js
@@ -4,27 +4,12 @@ OC.L10N.register(
|
||||
"Hours" : "Sati",
|
||||
"Minutes" : "Minute",
|
||||
"Maximum file size of {size} exceeded" : "Maksimalna veličina datoteke prekoračena",
|
||||
"Personal" : "Osobno",
|
||||
"Done" : "Done",
|
||||
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Učitana datoteka premašuje maksimalnu dopuštenu veličinu datoteke MAX_FILE_SIZE navedenu u HTML formi",
|
||||
"No file was uploaded" : "Nijedna datoteka nije učitana.",
|
||||
"Missing a temporary folder" : "Nedostaje privremeni direktorij.",
|
||||
"Actions" : "Radnje",
|
||||
"Close" : "Zatvori",
|
||||
"Sharing" : "Dijeljenje",
|
||||
"Group" : "Grupa",
|
||||
"Circle" : "Krug",
|
||||
"Loading" : "Loading",
|
||||
"Edit" : "Izmjeni",
|
||||
"Share" : "Podjeli",
|
||||
"Create" : "Ustvari",
|
||||
"Status" : "Status",
|
||||
"Title" : "Naslov",
|
||||
"Members" : "Članovi",
|
||||
"Cancel upload" : "Prekini učitavanje",
|
||||
"by" : "od strane",
|
||||
"Description" : "Opis",
|
||||
"Saved" : "Spremljeno",
|
||||
"Settings" : "Podešavanje"
|
||||
},
|
||||
"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);");
|
||||
|
||||
15
l10n/bs.json
15
l10n/bs.json
@@ -2,27 +2,12 @@
|
||||
"Hours" : "Sati",
|
||||
"Minutes" : "Minute",
|
||||
"Maximum file size of {size} exceeded" : "Maksimalna veličina datoteke prekoračena",
|
||||
"Personal" : "Osobno",
|
||||
"Done" : "Done",
|
||||
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Učitana datoteka premašuje maksimalnu dopuštenu veličinu datoteke MAX_FILE_SIZE navedenu u HTML formi",
|
||||
"No file was uploaded" : "Nijedna datoteka nije učitana.",
|
||||
"Missing a temporary folder" : "Nedostaje privremeni direktorij.",
|
||||
"Actions" : "Radnje",
|
||||
"Close" : "Zatvori",
|
||||
"Sharing" : "Dijeljenje",
|
||||
"Group" : "Grupa",
|
||||
"Circle" : "Krug",
|
||||
"Loading" : "Loading",
|
||||
"Edit" : "Izmjeni",
|
||||
"Share" : "Podjeli",
|
||||
"Create" : "Ustvari",
|
||||
"Status" : "Status",
|
||||
"Title" : "Naslov",
|
||||
"Members" : "Članovi",
|
||||
"Cancel upload" : "Prekini učitavanje",
|
||||
"by" : "od strane",
|
||||
"Description" : "Opis",
|
||||
"Saved" : "Spremljeno",
|
||||
"Settings" : "Podešavanje"
|
||||
},"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"
|
||||
}
|
||||
@@ -67,7 +67,9 @@ OC.L10N.register(
|
||||
"You have added the attachment {attachment} to card {card}" : "Heu afegit l'adjunt {attachment} a la targeta {card}",
|
||||
"{user} has added the attachment {attachment} to card {card}" : "{user} ha afegit l'adjunt {attachment} a la targeta {card}",
|
||||
"You have updated the attachment {attachment} on card {card}" : "Heu actualitzat l'adjunt {attachment} a la targeta {card}",
|
||||
"{user} has updated the attachment {attachment} to card {card}" : "{user} ha actualitzat l'adjunt {attachment} a la targeta {card}",
|
||||
"You have deleted the attachment {attachment} from card {card}" : "Heu suprimit l'adjunt {attachment} de la targeta {card}",
|
||||
"{user} has deleted the attachment {attachment} to card {card}" : "{user} ha suprimit l'adjunt {attachment} de la targeta {card}",
|
||||
"You have restored the attachment {attachment} to card {card}" : "Heu restaurat l'adjunt {attachment} a la targeta {card}",
|
||||
"{user} has restored the attachment {attachment} to card {card}" : "{user} ha restaurat l'adjunt {attachment} a la targeta {card}",
|
||||
"You have commented on card {card}" : "Heu comentat la targeta {card}",
|
||||
|
||||
@@ -65,7 +65,9 @@
|
||||
"You have added the attachment {attachment} to card {card}" : "Heu afegit l'adjunt {attachment} a la targeta {card}",
|
||||
"{user} has added the attachment {attachment} to card {card}" : "{user} ha afegit l'adjunt {attachment} a la targeta {card}",
|
||||
"You have updated the attachment {attachment} on card {card}" : "Heu actualitzat l'adjunt {attachment} a la targeta {card}",
|
||||
"{user} has updated the attachment {attachment} to card {card}" : "{user} ha actualitzat l'adjunt {attachment} a la targeta {card}",
|
||||
"You have deleted the attachment {attachment} from card {card}" : "Heu suprimit l'adjunt {attachment} de la targeta {card}",
|
||||
"{user} has deleted the attachment {attachment} to card {card}" : "{user} ha suprimit l'adjunt {attachment} de la targeta {card}",
|
||||
"You have restored the attachment {attachment} to card {card}" : "Heu restaurat l'adjunt {attachment} a la targeta {card}",
|
||||
"{user} has restored the attachment {attachment} to card {card}" : "{user} ha restaurat l'adjunt {attachment} a la targeta {card}",
|
||||
"You have commented on card {card}" : "Heu comentat la targeta {card}",
|
||||
|
||||
202
l10n/cs.js
202
l10n/cs.js
@@ -4,89 +4,86 @@ OC.L10N.register(
|
||||
"Please provide a content for your comment." : "Zadejte obsah svého komentáře.",
|
||||
"Posting the comment failed." : "Odeslání komentáře se nezdařilo.",
|
||||
"The comment has been deleted" : "Komentář byl smazán",
|
||||
"The associated stack is deleted as well, it will be restored as well." : "Související sloupec je také smazaný a bude také obnoven.",
|
||||
"Restore associated stack" : "Obnovit související sloupec",
|
||||
"The associated stack is deleted as well, it will be restored as well." : "Související stack je také smazaný a bude také obnoven.",
|
||||
"Restore associated stack" : "Obnovit související stack",
|
||||
"Remove user from card" : "Odebrat uživatele z karty",
|
||||
"Hours" : "Hodiny",
|
||||
"Minutes" : "Minuty",
|
||||
"Link to a board" : "Propojit s tabulí",
|
||||
"Maximum file size of {size} exceeded" : "Překročena nejvyšší umožněná velikost souboru {size}",
|
||||
"Maximum file size of {size} exceeded" : "U souboru {size} překročena nejvyšší umožněná velikost",
|
||||
"File already exists" : "Soubor už existuje",
|
||||
"You have created a new board {board}" : "Vytvořili jste tabuli {board}",
|
||||
"{user} has created a new board {board}" : "{user} vytvořil(a) novou tabuli {board}",
|
||||
"You have deleted the board {board}" : "Smazali jste tabuli {board}",
|
||||
"{user} has deleted the board {board}" : "{user} smazal(a) tabuli {board}",
|
||||
"You have restored the board {board}" : "Obnovili jste tabuli {board}",
|
||||
"{user} has restored the board {board}" : "{user} obnovil(a) tabuli {board}",
|
||||
"You have shared the board {board} with {acl}" : "Nasdíleli jste tabuli {board} s {acl}",
|
||||
"{user} has shared the board {board} with {acl}" : "{user} nasdílel(a) tabuli {board} s {acl}",
|
||||
"You have removed {acl} from the board {board}" : "Odebrali jste {acl} z tabule {board}",
|
||||
"{user} has removed {acl} from the board {board}" : "{user} odebral(a) {acl} z tabule {board}",
|
||||
"You have renamed the board {before} to {board}" : "Přejmenovali jste tabuli {before} na {board}",
|
||||
"{user} has renamed the board {before} to {board}" : "{user} přejmenoval(a) tabuli {before} na {board}",
|
||||
"You have archived the board {board}" : "Zaarchivovali jste tabuli {board}",
|
||||
"{user} has archived the board {before}" : "{user} zaarchivoval(a) tabuli {before}",
|
||||
"You have unarchived the board {board}" : "Vrátili jste zpět z archivace tabuli {board}",
|
||||
"{user} has unarchived the board {before}" : "{user} vrátil(a) tabuli {before} zpět z archivace",
|
||||
"You have created a new stack {stack} on board {board}" : "Vytvořili jste nový sloupec {stack} na tabuli {board}",
|
||||
"{user} has created a new stack {stack} on board {board}" : "{user} vytvořil(a) nový sloupec {stack} na tabuli {board}",
|
||||
"You have renamed stack {before} to {stack} on board {board}" : "Přejmenovali jste sloupec {before} na {stack} na tabuli {board}",
|
||||
"{user} has renamed stack {before} to {stack} on board {board}" : "{user} přejmenoval(a) sloupec {before} na {stack} na tabuli {board}",
|
||||
"You have deleted stack {stack} on board {board}" : "Smazali jste sloupec {stack} na tabuli {board}",
|
||||
"{user} has deleted stack {stack} on board {board}" : "{user} smazal(a) sloupec {stack} na tabuli {board}",
|
||||
"You have created card {card} in stack {stack} on board {board}" : "Vytvořili jste kartu {card} ve sloupci {stack} na tabuli {board}",
|
||||
"{user} has created card {card} in stack {stack} on board {board}" : "{user} vytvořil(a) kartu {card} ve sloupci {stack} na tabuli {board}",
|
||||
"You have deleted card {card} in stack {stack} on board {board}" : "Smazali jste kartu {card} ve sloupci {stack} na tabuli {board}",
|
||||
"{user} has deleted card {card} in stack {stack} on board {board}" : "{user} smazal(a) kartu {card} ve sloupci {board} na tabuli {board}",
|
||||
"You have created a new board {board}" : "Vytvořili jste nástěnku {board}",
|
||||
"{user} has created a new board {board}" : "{user} vytvořil(a) novou nástěnku {board}",
|
||||
"You have deleted the board {board}" : "Smazali jste nástěnku {board}",
|
||||
"{user} has deleted the board {board}" : "{user} smazal(a) nástěnku {board}",
|
||||
"You have restored the board {board}" : "Obnovili jste nástěnku {board}",
|
||||
"{user} has restored the board {board}" : "{user} obnovil(a) nástěnku {board}",
|
||||
"You have shared the board {board} with {acl}" : "Nasdíleli jste nástěnku {board} s {acl}",
|
||||
"You have removed {acl} from the board {board}" : "Odebrali jste {acl} z nástěnky {board}",
|
||||
"{user} has removed {acl} from the board {board}" : "{user} odebral(a) {acl} z nástěnky {board}",
|
||||
"You have renamed the board {before} to {board}" : "Přejmenovali jste nástěnku {before} na {board}",
|
||||
"{user} has renamed the board {before} to {board}" : "{user} přejmenoval(a) desku {before} na {board}",
|
||||
"You have archived the board {board}" : "Zaarchivovali jste nástěnku {board}",
|
||||
"{user} has archived the board {before}" : "{user} zaarchivoval(a) nástěnku {before}",
|
||||
"You have unarchived the board {board}" : "Zrušili jste archivaci nástěnky {board}",
|
||||
"{user} has unarchived the board {before}" : "{user} zrušil(a) archivaci nástěnky {before}",
|
||||
"You have created a new stack {stack} on board {board}" : "Vytvořili jste novou hromádku {stack} na desce {board}",
|
||||
"{user} has created a new stack {stack} on board {board}" : "{user} vytvořil(a) nový balíček {stack} na desce {board}",
|
||||
"You have renamed stack {before} to {stack} on board {board}" : "Přejmenovali jste hromádku {before} na {stack} na desce {board}",
|
||||
"{user} has renamed stack {before} to {stack} on board {board}" : "{user} přejmenoval(a) hromádku {before} na {stack} na desce {board}",
|
||||
"You have deleted stack {stack} on board {board}" : "Smazali jste balíček {stack} na desce {board}",
|
||||
"{user} has deleted stack {stack} on board {board}" : "{user} smazal(a) balíček {stack} na desce {board}",
|
||||
"You have created card {card} in stack {stack} on board {board}" : "Vytvořili jste kartu {card} v balíčku {stack} na kartě {board}",
|
||||
"{user} has created card {card} in stack {stack} on board {board}" : "{user} vytvořil(a) kartu {card} na hromádce {stack} na desce {board}",
|
||||
"You have deleted card {card} in stack {stack} on board {board}" : "Smazali jste kartu {card} na hromádce {stack} na desce {board}",
|
||||
"{user} has deleted card {card} in stack {stack} on board {board}" : "{user} smazal(a) kartu {card} v balíčku {board} na desce {board}",
|
||||
"You have renamed the card {before} to {card}" : "Přejmenovali jste kartu {before} na {card}",
|
||||
"{user} has renamed the card {before} to {card}" : "{user} přejmenoval(a) {before} na {card}",
|
||||
"You have added a description to card {card} in stack {stack} on board {board}" : "Přidali jste popis ke kartě {card} ve sloupci {stack} na tabuli {board}",
|
||||
"{user} has added a description to card {card} in stack {stack} on board {board}" : "{user} přidal(a) popis ke kartě {card} ve sloupci {stack} na tabuli {board}",
|
||||
"You have updated the description of card {card} in stack {stack} on board {board}" : "Aktualizovali jste popis karty {card} ve sloupci {stack} na tabuli {board}",
|
||||
"{user} has updated the description of the card {card} in stack {stack} on board {board}" : "{user} aktualizoval(a) popis karty {card} ve sloupci {stack} na tabuli {board}",
|
||||
"You have archived card {card} in stack {stack} on board {board}" : "Zaarchivovali kartu {card} ve sloupci {stack} na tabuli {board}",
|
||||
"{user} has archived card {card} in stack {stack} on board {board}" : "{user} zaarchivoval(a) kartu {card} ve sloupci {stack} na tabuli {board}",
|
||||
"You have unarchived card {card} in stack {stack} on board {board}" : "Zrušili jste archivaci karty {card} ve sloupci {stack} na tabuli {board}",
|
||||
"{user} has unarchived card {card} in stack {stack} on board {board}" : "{user} zrušil(a) archivaci karty {card} ve sloupci {stack} na tabuli {board}",
|
||||
"You have removed the due date of card {card}" : "Odebrali jste termín u karty {card}",
|
||||
"{user} has removed the due date of card {card}" : "{user} odebral(a) termín u karty {card}",
|
||||
"You have set the due date of card {card} to {after}" : "Nastavili jste termín u karty {card} na {after}",
|
||||
"{user} has set the due date of card {card} to {after}" : "{user} nastavil(a) termín u karty {card} na {after}",
|
||||
"You have updated the due date of card {card} to {after}" : "Změnili jste termín u karty {card} na {after}",
|
||||
"{user} has updated the due date of card {card} to {after}" : "{user} aktualizoval(a) termín u karty {card} na {after}",
|
||||
"You have added the tag {label} to card {card} in stack {stack} on board {board}" : "Přidali jste štítek {label} kartě {card} ve sloupci {stack} na tabuli {board}",
|
||||
"{user} has added the tag {label} to card {card} in stack {stack} on board {board}" : "{user} přidal(a) štítek {label} ke kartě {card} ve sloupci {stack} na tabuli {board}",
|
||||
"You have removed the tag {label} from card {card} in stack {stack} on board {board}" : "Odebrali jste štítek {label} z karty {card} ve sloupci {stack} na tabuli {board}",
|
||||
"{user} has removed the tag {label} from card {card} in stack {stack} on board {board}" : "{user} odebral(a) štítek {label} z karty {card} ve sloupci {stack} na tabuli {board}",
|
||||
"You have assigned {assigneduser} to card {card} on board {board}" : "Přiřadili jste {assigneduser} ke kartě {card} na tabuli {board}",
|
||||
"{user} has assigned {assigneduser} to card {card} on board {board}" : "{user} přiřadil(a) {assigneduser} ke kartě {card} na tabuli {board}",
|
||||
"You have unassigned {assigneduser} from card {card} on board {board}" : "Zrušili jste přiřazení {assigneduser} u karty {card} na tabuli {board}",
|
||||
"{user} has unassigned {assigneduser} from card {card} on board {board}" : "{user} zrušil(a) přiřazení {assigneduser} z karty {card} na tabuli {board}",
|
||||
"You have moved the card {card} from stack {stackBefore} to {stack}" : "Přesunuli jste kartu {card} ze sloupce {stackBefore} do {stack}",
|
||||
"{user} has moved the card {card} from stack {stackBefore} to {stack}" : "{user} přesunul(a) kartu {card} ze sloupce {stackBefore} do {stack}",
|
||||
"You have added a description to card {card} in stack {stack} on board {board}" : "Přidali jste popis ke kartě {card} v hromádce {stack} na desce {board}",
|
||||
"{user} has added a description to card {card} in stack {stack} on board {board}" : "{user} přidal(a) popis ke kartě {card} v hromádce {stack} na desce {board}",
|
||||
"You have updated the description of card {card} in stack {stack} on board {board}" : "Aktualizovali jste popis karty {card} v hromádce {stack} na desce {board}",
|
||||
"{user} has updated the description of the card {card} in stack {stack} on board {board}" : "{user} aktualizoval(a) popis karty {card} na hromádce {stack} na nástěnce {board}",
|
||||
"You have archived card {card} in stack {stack} on board {board}" : "Zaarchivovali kartu {card} v balíčku {stack} na desce {board}",
|
||||
"{user} has archived card {card} in stack {stack} on board {board}" : "{user} zaarchivoval(a) kartu {card} v balíčku {stack} na desce {board}",
|
||||
"You have unarchived card {card} in stack {stack} on board {board}" : "Zrušili jste archivaci karty {card} na hromádce {stack} na desce {board}",
|
||||
"{user} has unarchived card {card} in stack {stack} on board {board}" : "{user} zrušil(a) archivaci karty {card} na hromádce {stack} na desce {board}",
|
||||
"You have removed the due date of card {card}" : "Odebrali jste termín karty {card}",
|
||||
"{user} has removed the due date of card {card}" : "{user} odebral(a) termín karty {card}",
|
||||
"You have set the due date of card {card} to {after}" : "Nastavili jste termín na kartě {card} na {after}",
|
||||
"{user} has set the due date of card {card} to {after}" : "{user} nastavil(a) termín karty {card} na {after}",
|
||||
"You have updated the due date of card {card} to {after}" : "Změnili jste termín na kartě {card} na {after}",
|
||||
"{user} has updated the due date of card {card} to {after}" : "{user} aktualizoval termín karty {card} na {after}",
|
||||
"You have added the tag {label} to card {card} in stack {stack} on board {board}" : "Přidali jste štítek {label} kartě {card} v hromádce {stack} na nástěnce {board}",
|
||||
"{user} has added the tag {label} to card {card} in stack {stack} on board {board}" : "{user} přidal(a) štítek {label} ke kartě {card} v hromádce {stack} na nástěnce {board}",
|
||||
"You have removed the tag {label} from card {card} in stack {stack} on board {board}" : "Odebrali jste štítek {label} z karty {card} v hromádce {stack} na desce {board}",
|
||||
"{user} has removed the tag {label} from card {card} in stack {stack} on board {board}" : "{user} odebral(a) štítek {label} z karty {card} na hromádce {stack} na desce {board}",
|
||||
"You have assigned {assigneduser} to card {card} on board {board}" : "Přiřadili jste {assigneduser} ke kartě {card} na desce {board}",
|
||||
"{user} has assigned {assigneduser} to card {card} on board {board}" : "{user} přiřadil(a) {assigneduser} ke kartě {card} na desce {board}",
|
||||
"You have unassigned {assigneduser} from card {card} on board {board}" : "Zrušili jste přiřazení {assigneduser} u karty {card} na nástěnce {board}",
|
||||
"{user} has unassigned {assigneduser} from card {card} on board {board}" : "{user} zrušil(a) přiřazení {assigneduser} z karty {card} na desce {board}",
|
||||
"You have moved the card {card} from stack {stackBefore} to {stack}" : "Přesunuli jste kartu {card} z balíčku {stackBefore} do {stack}",
|
||||
"{user} has moved the card {card} from stack {stackBefore} to {stack}" : "{user} přesunul(a) kartu {card} z balíčku {stackBefore} do {stack}",
|
||||
"You have added the attachment {attachment} to card {card}" : "Přidali jste přílohu {attachment} ke kartě {card}",
|
||||
"{user} has added the attachment {attachment} to card {card}" : "{user} přidal(a) přílohu {attachment} ke kartě {card}",
|
||||
"You have updated the attachment {attachment} on card {card}" : "Aktualizovali jste přílohu {attachment} u karty {card}",
|
||||
"{user} has updated the attachment {attachment} on card {card}" : "{user} aktualizoval(a) přílohu {attachment} u karty {card}",
|
||||
"You have updated the attachment {attachment} on card {card}" : "Aktualizovali jste přílohu {attachment} na kartě {card}",
|
||||
"{user} has updated the attachment {attachment} to card {card}" : "{user} aktualizoval(a) přílohu {attachment} ke kartě {card}",
|
||||
"You have deleted the attachment {attachment} from card {card}" : "Smazali jste přílohu {attachment} u karty {card}",
|
||||
"{user} has deleted the attachment {attachment} from card {card}" : "{user} smazal(a) přílohu {attachment} u karty {card}",
|
||||
"{user} has deleted the attachment {attachment} to card {card}" : "{user} smazal(a) přílohu {attachment} u karty {card}",
|
||||
"You have restored the attachment {attachment} to card {card}" : "Obnovili jste přílohu {attachment} ke kartě {card}",
|
||||
"{user} has restored the attachment {attachment} to card {card}" : "{user} obnovil(a) přílohu {attachment} ke kartě {card}",
|
||||
"You have commented on card {card}" : "Přidali jste komentář na kartě {card}",
|
||||
"{user} has commented on card {card}" : "{user} přidal(a) komentář na kartě {card}",
|
||||
"A <strong>card description</strong> inside the Deck app has been changed" : "<strong>Popis karty</strong> v aplikaci Deck byl změněn",
|
||||
"Deck" : "Deck",
|
||||
"Changes in the <strong>Deck app</strong>" : "Změny v <strong>aplikaci Deck</strong>",
|
||||
"A <strong>comment</strong> was created on a card" : "Na kartě byl vytvořen <strong>komentář</strong>",
|
||||
"A <strong>card description</strong> inside the Deck app has been changed" : "<strong>Popis mapy</strong> v Deck-aplikace byl změněn",
|
||||
"Deck" : "Balík",
|
||||
"Changes in the <strong>Deck app</strong>" : "Změny v <strong>Deck aplikace</strong>",
|
||||
"Personal" : "Osobní",
|
||||
"The card \"%s\" on \"%s\" has been assigned to you by %s." : "Kartu „%s“ na „%s“ vám přiřadil(a) %s.",
|
||||
"{user} has assigned the card \"%s\" on \"%s\" to you." : "{user} vám přiřadil(a) kartu „%s“ na „%s“.",
|
||||
"The card \"%s\" on \"%s\" has reached its due date." : "U karty „%s“ z tabule „%s“ nastalo plánované datum dokončení.",
|
||||
"The card \"%s\" on \"%s\" has reached its due date." : "U karty \"%s\" z tabule \"%s\" nastalo plánované datum dokončení.",
|
||||
"%s has mentioned you in a comment on \"%s\"." : "%s vás zmínil(a) v komentáři k „%s“.",
|
||||
"{user} has mentioned you in a comment on \"%s\"." : "{user} vás zmínil(a) v komentáři v „%s“.",
|
||||
"The board \"%s\" has been shared with you by %s." : "Uživatel %s vám nasdílel(a) tabuli „%s“.",
|
||||
"{user} has shared the board %s with you." : "{user} vám nasdílel(a) tabuli %s.",
|
||||
"No data was provided to create an attachment." : "Nebyla poskytnuta žádná data pro vytvoření přílohy.",
|
||||
"The board \"%s\" has been shared with you by %s." : "Tabule \"%s\" s vámi byla nasdílena uživatelem %s.",
|
||||
"{user} has shared the board %s with you." : "{user} s vámi nasdílel tabuli %s.",
|
||||
"No data was provided to create an attachment." : "Žádná data k vytvoření přílohy.",
|
||||
"Finished" : "Dokončeno",
|
||||
"To review" : "K revizi",
|
||||
"Action needed" : "Nutná akce",
|
||||
@@ -98,7 +95,7 @@ OC.L10N.register(
|
||||
"Example Task 2" : "Druhý úkol pro ukázku",
|
||||
"Example Task 1" : "První úkol pro ukázku",
|
||||
"The file was uploaded" : "Soubor byl nahrán",
|
||||
"The uploaded file exceeds the upload_max_filesize directive in php.ini" : "Velikost nahrávaného souboru překračuje limit nastavení direktivou upload_max_filesize v php.ini",
|
||||
"The uploaded file exceeds the upload_max_filesize directive in php.ini" : "Nahrávaný soubor přesahuje nastavení upload_max_filesize v php.ini",
|
||||
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Nahrávaný soubor přesáhl svou velikostí hodnotu direktivy MAX_FILE_SIZE, určenou v HTML formuláři",
|
||||
"The file was only partially uploaded" : "Soubor byl nahrán pouze z části",
|
||||
"No file was uploaded" : "Nebyl nahrán žádný soubor",
|
||||
@@ -107,21 +104,20 @@ OC.L10N.register(
|
||||
"A PHP extension stopped the file upload" : "PHP rozšíření zastavilo nahrávání souboru.",
|
||||
"No file uploaded or file size exceeds maximum of %s" : "Nebyl nahrán žádný soubor nebo jeho velikost přesáhla %s",
|
||||
"A kanban style project and personal management tool for Nextcloud" : "Nástroj pro projektový a osobní řízení ve stylu Kanban.",
|
||||
"Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deck je nástroj cílený na osobní nebo projektové plánování týmů v Kanban stylu, vestavěný v Nextcloud.\n\n\n- 📥 Zadávejte a uspořádávejte své úkoly do karet\n- 📄 Zapisujte si dodatečné poznámky \n- 🔖 Přiřazujte štítky pro ještě lepší organizaci\n- 👥 Sdílejte se svým týmem, přáteli nebo rodinou\n- 🚀 Dostaňte svůj projekt pod kontrolu",
|
||||
"Select the board to link to a project" : "Vyberte tabuli kterou propojit s projektem",
|
||||
"Select board" : "Vybrat tabuli",
|
||||
"Add a new stack" : "Přidat nový sloupec",
|
||||
"Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Karty jsou nástroj zacílený na osobní nebo projektové plánování týmů v Kanban stylu, vestavěný v Nextcloud.\n\n\n- 📥 Zadávejte a uspořádávejte své úkoly do karet\n- 📄 Zapisujte si dodatečné poznámky \n- 🔖 Přiřazujte štítky pro ještě lepší organizaci\n- 👥 Sdílejte se svým týmem, přáteli nebo rodinou\n- 🚀 Dostaňte svůj projekt pod kontrolu",
|
||||
"Select board" : "Vybrat nástěnku",
|
||||
"Add a new stack" : "Přidat nový zásobník",
|
||||
"Submit" : "Odeslat",
|
||||
"Show archived cards" : "Zobrazit archivované karty",
|
||||
"Hide archived cards" : "Skrýt archivované karty",
|
||||
"Toggle compact mode" : "Vyp/zap. kompaktní režim",
|
||||
"Show board details" : "Zobrazit podrobnosti o tabuli",
|
||||
"All Boards" : "Všechny tabule",
|
||||
"Archived boards" : "Archivované tabule",
|
||||
"Share board" : "Sdílet tabuli",
|
||||
"Show board details" : "Zobrazit podrobnosti o desce",
|
||||
"All Boards" : "Všechny desky",
|
||||
"Archived boards" : "Archivované desky",
|
||||
"Share board" : "Sdílet nástěnku",
|
||||
"Archived cards" : "Archivované karty",
|
||||
"Actions" : "Akce",
|
||||
"Drop your files here to upload it to the card" : "Soubory ke kartě připojíte přetažením sem",
|
||||
"Drop your files here to upload it to the card" : "Přetáhněte soubor sem, pokud jej chcete připojit ke kartě.",
|
||||
"Assign card to me" : "Přiřadit kartu mě",
|
||||
"Unassign card from me" : "Zrušit přiřazení karty mě",
|
||||
"Archive card" : "Archivovat kartu",
|
||||
@@ -131,7 +127,7 @@ OC.L10N.register(
|
||||
"Add card" : "Přidat kartu",
|
||||
"Close" : "Zavřít",
|
||||
"Sharing" : "Sdílení",
|
||||
"Tags" : "Štítky",
|
||||
"Tags" : "Značky",
|
||||
"Deleted items" : "Smazané položky",
|
||||
"Timeline" : "Časová osa",
|
||||
"Select users or groups to share with" : "Vyberte uživatele nebo skupiny pro sdílení",
|
||||
@@ -142,48 +138,48 @@ OC.L10N.register(
|
||||
"Edit" : "Upravit",
|
||||
"Share" : "Sdílet",
|
||||
"Manage" : "Spravovat",
|
||||
"Discard share" : "Zahodit sdílení",
|
||||
"Sharing has been disabled for your account." : "Sdílení bylo pro váš účet zakázáno.",
|
||||
"Discard share" : "Zrušit sdílení",
|
||||
"Sharing has been disabled for your account." : "Sdílení bylo zakázáno pro váš konto.",
|
||||
"Update tag" : "Aktualizovat štítek",
|
||||
"Edit tag" : "Upravit štítek",
|
||||
"Delete tag" : "Smazat štítek",
|
||||
"Create" : "Vytvořit",
|
||||
"Create a new tag" : "Vytvořit nový štítek",
|
||||
"Deleted stacks" : "Smazané sloupce",
|
||||
"Deleted stacks" : "Smazané zásobníky",
|
||||
"Deleted cards" : "Smazané karty",
|
||||
"Status" : "Stav",
|
||||
"No archived boards to display" : "Žádné archivované tabule k zobrazení",
|
||||
"No shared boards to display" : "Žádné sdílené tabule k zobrazení",
|
||||
"No archived boards to display" : "Žádné archivované nástěnky k zobrazení",
|
||||
"No shared boards to display" : "Žádné sdílené nástěnky k zobrazení",
|
||||
"Title" : "Název",
|
||||
"Members" : "Členové",
|
||||
"More actions" : "Více akcí",
|
||||
"Edit board" : "Upravit tabuli",
|
||||
"Archive board" : "Archivovat tabuli",
|
||||
"Unarchive board" : "Vrátit tabuli zpět z archivu",
|
||||
"Delete board" : "Smazat tabuli",
|
||||
"Update board" : "Aktualizovat tabuli",
|
||||
"Reset board" : "Vrátit tabuli do předchozího stavu",
|
||||
"Undo board deletion - Otherwise the board will be deleted during the next cronjob run." : "Vrátit smazání tabule – jinak bude nadobro odstraněna během příštího spuštění naplánovaných úloh.",
|
||||
"Create new board" : "Vytvořit novou tabuli",
|
||||
"New board title" : "Název nové tabule",
|
||||
"Create board" : "Vytvořit tabuli",
|
||||
"Edit board" : "Upravit desku",
|
||||
"Archive board" : "Archivovaná deska",
|
||||
"Unarchive board" : "Odarchivovat desku",
|
||||
"Delete board" : "Smazat desku",
|
||||
"Update board" : "Aktualizovat desku",
|
||||
"Reset board" : "Resetovat nástěnku",
|
||||
"Undo board deletion - Otherwise the board will be deleted during the next cronjob run." : "Vrátit smazání tabule - Tabule bude jinak trvale odstraněna během příštího běhu cronjobu.",
|
||||
"Create new board" : "Vytvořit novou desku",
|
||||
"New board title" : "Nadpis nové desky",
|
||||
"Create board" : "Vytvořit nástěnku",
|
||||
"Select an attachment" : "Vybrat přílohu",
|
||||
"Cancel upload" : "Zrušit nahrávání",
|
||||
"by" : "od",
|
||||
"Undo file deletion - Otherwise the file will be deleted during the next cronjob run." : "Vrátit smazání souboru – jinak bude trvale smazán při dalším běhu naplánované úlohy.",
|
||||
"Undo file deletion - Otherwise the file will be deleted during the next cronjob run." : "Vrátit smazání souboru – v opačném případě bude soubor trvale smazán při dalším běhu cronjobu.",
|
||||
"Undo file deletion" : "Vzít zpět smazání souboru",
|
||||
"Insert the file into the description" : "Vložte soubor do popisu",
|
||||
"Insert the file into the description" : "Vložte soubor do popisku.",
|
||||
"Delete attachment" : "Smazat přílohu",
|
||||
"Modified:" : "Změněno:",
|
||||
"Modified:" : "Upraveno:",
|
||||
"Created:" : "Vytvořeno:",
|
||||
"Choose a tag" : "Zvolte štítek",
|
||||
"Choose a tag" : "Vyberte štítek",
|
||||
"Add a tag" : "Přidat štítek",
|
||||
"Select tags" : "Výběr štítků",
|
||||
"Assign users" : "Přiřadit uživatele",
|
||||
"Choose a user to assign" : "Zvolte uživatele kterého přiřadit",
|
||||
"Assign this card to a user" : "Přiřadit tuto kartu uživateli",
|
||||
"Assign this card to a user" : "Přiřadit kartu uživateli",
|
||||
"Due date" : "Termín",
|
||||
"Click to set" : "Klikn. vyberte",
|
||||
"Click to set" : "Klikněte pro výběr",
|
||||
"Remove due date" : "Odstranit termín",
|
||||
"Description" : "Popis",
|
||||
"Attachments" : "Přílohy",
|
||||
@@ -192,12 +188,12 @@ OC.L10N.register(
|
||||
"Insert attachment" : "Vložit přílohu",
|
||||
"Formatting help" : "Nápověda k formátování",
|
||||
"Upload attachment" : "Nahrát přílohu",
|
||||
"Add a card description…" : "Přidejte popis karty…",
|
||||
"Shared boards" : "Sdílené tabule",
|
||||
"Move board to archive" : "Přesunout tabuli do archivu",
|
||||
"Create a new board" : "Vytvořit novou tabuli",
|
||||
"Add a card description…" : "Přidat popis karty…",
|
||||
"Shared boards" : "Sdílené desky",
|
||||
"Move board to archive" : "Přesunout desku do archivu",
|
||||
"Create a new board" : "Vytvořit novou desku",
|
||||
"Settings" : "Nastavení",
|
||||
"Limit deck to groups" : "Omezit Deck na skupiny",
|
||||
"Limiting Deck will block users not part of those groups from creating their own boards. Users will still be able to work on boards that have been shared with them." : "Omezení nastavené pro Deck brání uživatelům, kteří nejsou součástí těchto skupin, ve vytváření vlastních tabulí. Nicméně i tak ale pořád budou moci pracovat na tabulích, které jsou jim nasdíleny."
|
||||
"Limit deck to groups" : "Omezte Deck na skupiny",
|
||||
"Limiting Deck will block users not part of those groups from creating their own boards. Users will still be able to work on boards that have been shared with them." : "Omezení Decků brání uživatelům, kteří nejsou součástí těchto skupin, při vytváření vlastních desek. Uživatelé mohou stále pracovat na deskách, které jsou s nimi sdíleny."
|
||||
},
|
||||
"nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;");
|
||||
|
||||
202
l10n/cs.json
202
l10n/cs.json
@@ -2,89 +2,86 @@
|
||||
"Please provide a content for your comment." : "Zadejte obsah svého komentáře.",
|
||||
"Posting the comment failed." : "Odeslání komentáře se nezdařilo.",
|
||||
"The comment has been deleted" : "Komentář byl smazán",
|
||||
"The associated stack is deleted as well, it will be restored as well." : "Související sloupec je také smazaný a bude také obnoven.",
|
||||
"Restore associated stack" : "Obnovit související sloupec",
|
||||
"The associated stack is deleted as well, it will be restored as well." : "Související stack je také smazaný a bude také obnoven.",
|
||||
"Restore associated stack" : "Obnovit související stack",
|
||||
"Remove user from card" : "Odebrat uživatele z karty",
|
||||
"Hours" : "Hodiny",
|
||||
"Minutes" : "Minuty",
|
||||
"Link to a board" : "Propojit s tabulí",
|
||||
"Maximum file size of {size} exceeded" : "Překročena nejvyšší umožněná velikost souboru {size}",
|
||||
"Maximum file size of {size} exceeded" : "U souboru {size} překročena nejvyšší umožněná velikost",
|
||||
"File already exists" : "Soubor už existuje",
|
||||
"You have created a new board {board}" : "Vytvořili jste tabuli {board}",
|
||||
"{user} has created a new board {board}" : "{user} vytvořil(a) novou tabuli {board}",
|
||||
"You have deleted the board {board}" : "Smazali jste tabuli {board}",
|
||||
"{user} has deleted the board {board}" : "{user} smazal(a) tabuli {board}",
|
||||
"You have restored the board {board}" : "Obnovili jste tabuli {board}",
|
||||
"{user} has restored the board {board}" : "{user} obnovil(a) tabuli {board}",
|
||||
"You have shared the board {board} with {acl}" : "Nasdíleli jste tabuli {board} s {acl}",
|
||||
"{user} has shared the board {board} with {acl}" : "{user} nasdílel(a) tabuli {board} s {acl}",
|
||||
"You have removed {acl} from the board {board}" : "Odebrali jste {acl} z tabule {board}",
|
||||
"{user} has removed {acl} from the board {board}" : "{user} odebral(a) {acl} z tabule {board}",
|
||||
"You have renamed the board {before} to {board}" : "Přejmenovali jste tabuli {before} na {board}",
|
||||
"{user} has renamed the board {before} to {board}" : "{user} přejmenoval(a) tabuli {before} na {board}",
|
||||
"You have archived the board {board}" : "Zaarchivovali jste tabuli {board}",
|
||||
"{user} has archived the board {before}" : "{user} zaarchivoval(a) tabuli {before}",
|
||||
"You have unarchived the board {board}" : "Vrátili jste zpět z archivace tabuli {board}",
|
||||
"{user} has unarchived the board {before}" : "{user} vrátil(a) tabuli {before} zpět z archivace",
|
||||
"You have created a new stack {stack} on board {board}" : "Vytvořili jste nový sloupec {stack} na tabuli {board}",
|
||||
"{user} has created a new stack {stack} on board {board}" : "{user} vytvořil(a) nový sloupec {stack} na tabuli {board}",
|
||||
"You have renamed stack {before} to {stack} on board {board}" : "Přejmenovali jste sloupec {before} na {stack} na tabuli {board}",
|
||||
"{user} has renamed stack {before} to {stack} on board {board}" : "{user} přejmenoval(a) sloupec {before} na {stack} na tabuli {board}",
|
||||
"You have deleted stack {stack} on board {board}" : "Smazali jste sloupec {stack} na tabuli {board}",
|
||||
"{user} has deleted stack {stack} on board {board}" : "{user} smazal(a) sloupec {stack} na tabuli {board}",
|
||||
"You have created card {card} in stack {stack} on board {board}" : "Vytvořili jste kartu {card} ve sloupci {stack} na tabuli {board}",
|
||||
"{user} has created card {card} in stack {stack} on board {board}" : "{user} vytvořil(a) kartu {card} ve sloupci {stack} na tabuli {board}",
|
||||
"You have deleted card {card} in stack {stack} on board {board}" : "Smazali jste kartu {card} ve sloupci {stack} na tabuli {board}",
|
||||
"{user} has deleted card {card} in stack {stack} on board {board}" : "{user} smazal(a) kartu {card} ve sloupci {board} na tabuli {board}",
|
||||
"You have created a new board {board}" : "Vytvořili jste nástěnku {board}",
|
||||
"{user} has created a new board {board}" : "{user} vytvořil(a) novou nástěnku {board}",
|
||||
"You have deleted the board {board}" : "Smazali jste nástěnku {board}",
|
||||
"{user} has deleted the board {board}" : "{user} smazal(a) nástěnku {board}",
|
||||
"You have restored the board {board}" : "Obnovili jste nástěnku {board}",
|
||||
"{user} has restored the board {board}" : "{user} obnovil(a) nástěnku {board}",
|
||||
"You have shared the board {board} with {acl}" : "Nasdíleli jste nástěnku {board} s {acl}",
|
||||
"You have removed {acl} from the board {board}" : "Odebrali jste {acl} z nástěnky {board}",
|
||||
"{user} has removed {acl} from the board {board}" : "{user} odebral(a) {acl} z nástěnky {board}",
|
||||
"You have renamed the board {before} to {board}" : "Přejmenovali jste nástěnku {before} na {board}",
|
||||
"{user} has renamed the board {before} to {board}" : "{user} přejmenoval(a) desku {before} na {board}",
|
||||
"You have archived the board {board}" : "Zaarchivovali jste nástěnku {board}",
|
||||
"{user} has archived the board {before}" : "{user} zaarchivoval(a) nástěnku {before}",
|
||||
"You have unarchived the board {board}" : "Zrušili jste archivaci nástěnky {board}",
|
||||
"{user} has unarchived the board {before}" : "{user} zrušil(a) archivaci nástěnky {before}",
|
||||
"You have created a new stack {stack} on board {board}" : "Vytvořili jste novou hromádku {stack} na desce {board}",
|
||||
"{user} has created a new stack {stack} on board {board}" : "{user} vytvořil(a) nový balíček {stack} na desce {board}",
|
||||
"You have renamed stack {before} to {stack} on board {board}" : "Přejmenovali jste hromádku {before} na {stack} na desce {board}",
|
||||
"{user} has renamed stack {before} to {stack} on board {board}" : "{user} přejmenoval(a) hromádku {before} na {stack} na desce {board}",
|
||||
"You have deleted stack {stack} on board {board}" : "Smazali jste balíček {stack} na desce {board}",
|
||||
"{user} has deleted stack {stack} on board {board}" : "{user} smazal(a) balíček {stack} na desce {board}",
|
||||
"You have created card {card} in stack {stack} on board {board}" : "Vytvořili jste kartu {card} v balíčku {stack} na kartě {board}",
|
||||
"{user} has created card {card} in stack {stack} on board {board}" : "{user} vytvořil(a) kartu {card} na hromádce {stack} na desce {board}",
|
||||
"You have deleted card {card} in stack {stack} on board {board}" : "Smazali jste kartu {card} na hromádce {stack} na desce {board}",
|
||||
"{user} has deleted card {card} in stack {stack} on board {board}" : "{user} smazal(a) kartu {card} v balíčku {board} na desce {board}",
|
||||
"You have renamed the card {before} to {card}" : "Přejmenovali jste kartu {before} na {card}",
|
||||
"{user} has renamed the card {before} to {card}" : "{user} přejmenoval(a) {before} na {card}",
|
||||
"You have added a description to card {card} in stack {stack} on board {board}" : "Přidali jste popis ke kartě {card} ve sloupci {stack} na tabuli {board}",
|
||||
"{user} has added a description to card {card} in stack {stack} on board {board}" : "{user} přidal(a) popis ke kartě {card} ve sloupci {stack} na tabuli {board}",
|
||||
"You have updated the description of card {card} in stack {stack} on board {board}" : "Aktualizovali jste popis karty {card} ve sloupci {stack} na tabuli {board}",
|
||||
"{user} has updated the description of the card {card} in stack {stack} on board {board}" : "{user} aktualizoval(a) popis karty {card} ve sloupci {stack} na tabuli {board}",
|
||||
"You have archived card {card} in stack {stack} on board {board}" : "Zaarchivovali kartu {card} ve sloupci {stack} na tabuli {board}",
|
||||
"{user} has archived card {card} in stack {stack} on board {board}" : "{user} zaarchivoval(a) kartu {card} ve sloupci {stack} na tabuli {board}",
|
||||
"You have unarchived card {card} in stack {stack} on board {board}" : "Zrušili jste archivaci karty {card} ve sloupci {stack} na tabuli {board}",
|
||||
"{user} has unarchived card {card} in stack {stack} on board {board}" : "{user} zrušil(a) archivaci karty {card} ve sloupci {stack} na tabuli {board}",
|
||||
"You have removed the due date of card {card}" : "Odebrali jste termín u karty {card}",
|
||||
"{user} has removed the due date of card {card}" : "{user} odebral(a) termín u karty {card}",
|
||||
"You have set the due date of card {card} to {after}" : "Nastavili jste termín u karty {card} na {after}",
|
||||
"{user} has set the due date of card {card} to {after}" : "{user} nastavil(a) termín u karty {card} na {after}",
|
||||
"You have updated the due date of card {card} to {after}" : "Změnili jste termín u karty {card} na {after}",
|
||||
"{user} has updated the due date of card {card} to {after}" : "{user} aktualizoval(a) termín u karty {card} na {after}",
|
||||
"You have added the tag {label} to card {card} in stack {stack} on board {board}" : "Přidali jste štítek {label} kartě {card} ve sloupci {stack} na tabuli {board}",
|
||||
"{user} has added the tag {label} to card {card} in stack {stack} on board {board}" : "{user} přidal(a) štítek {label} ke kartě {card} ve sloupci {stack} na tabuli {board}",
|
||||
"You have removed the tag {label} from card {card} in stack {stack} on board {board}" : "Odebrali jste štítek {label} z karty {card} ve sloupci {stack} na tabuli {board}",
|
||||
"{user} has removed the tag {label} from card {card} in stack {stack} on board {board}" : "{user} odebral(a) štítek {label} z karty {card} ve sloupci {stack} na tabuli {board}",
|
||||
"You have assigned {assigneduser} to card {card} on board {board}" : "Přiřadili jste {assigneduser} ke kartě {card} na tabuli {board}",
|
||||
"{user} has assigned {assigneduser} to card {card} on board {board}" : "{user} přiřadil(a) {assigneduser} ke kartě {card} na tabuli {board}",
|
||||
"You have unassigned {assigneduser} from card {card} on board {board}" : "Zrušili jste přiřazení {assigneduser} u karty {card} na tabuli {board}",
|
||||
"{user} has unassigned {assigneduser} from card {card} on board {board}" : "{user} zrušil(a) přiřazení {assigneduser} z karty {card} na tabuli {board}",
|
||||
"You have moved the card {card} from stack {stackBefore} to {stack}" : "Přesunuli jste kartu {card} ze sloupce {stackBefore} do {stack}",
|
||||
"{user} has moved the card {card} from stack {stackBefore} to {stack}" : "{user} přesunul(a) kartu {card} ze sloupce {stackBefore} do {stack}",
|
||||
"You have added a description to card {card} in stack {stack} on board {board}" : "Přidali jste popis ke kartě {card} v hromádce {stack} na desce {board}",
|
||||
"{user} has added a description to card {card} in stack {stack} on board {board}" : "{user} přidal(a) popis ke kartě {card} v hromádce {stack} na desce {board}",
|
||||
"You have updated the description of card {card} in stack {stack} on board {board}" : "Aktualizovali jste popis karty {card} v hromádce {stack} na desce {board}",
|
||||
"{user} has updated the description of the card {card} in stack {stack} on board {board}" : "{user} aktualizoval(a) popis karty {card} na hromádce {stack} na nástěnce {board}",
|
||||
"You have archived card {card} in stack {stack} on board {board}" : "Zaarchivovali kartu {card} v balíčku {stack} na desce {board}",
|
||||
"{user} has archived card {card} in stack {stack} on board {board}" : "{user} zaarchivoval(a) kartu {card} v balíčku {stack} na desce {board}",
|
||||
"You have unarchived card {card} in stack {stack} on board {board}" : "Zrušili jste archivaci karty {card} na hromádce {stack} na desce {board}",
|
||||
"{user} has unarchived card {card} in stack {stack} on board {board}" : "{user} zrušil(a) archivaci karty {card} na hromádce {stack} na desce {board}",
|
||||
"You have removed the due date of card {card}" : "Odebrali jste termín karty {card}",
|
||||
"{user} has removed the due date of card {card}" : "{user} odebral(a) termín karty {card}",
|
||||
"You have set the due date of card {card} to {after}" : "Nastavili jste termín na kartě {card} na {after}",
|
||||
"{user} has set the due date of card {card} to {after}" : "{user} nastavil(a) termín karty {card} na {after}",
|
||||
"You have updated the due date of card {card} to {after}" : "Změnili jste termín na kartě {card} na {after}",
|
||||
"{user} has updated the due date of card {card} to {after}" : "{user} aktualizoval termín karty {card} na {after}",
|
||||
"You have added the tag {label} to card {card} in stack {stack} on board {board}" : "Přidali jste štítek {label} kartě {card} v hromádce {stack} na nástěnce {board}",
|
||||
"{user} has added the tag {label} to card {card} in stack {stack} on board {board}" : "{user} přidal(a) štítek {label} ke kartě {card} v hromádce {stack} na nástěnce {board}",
|
||||
"You have removed the tag {label} from card {card} in stack {stack} on board {board}" : "Odebrali jste štítek {label} z karty {card} v hromádce {stack} na desce {board}",
|
||||
"{user} has removed the tag {label} from card {card} in stack {stack} on board {board}" : "{user} odebral(a) štítek {label} z karty {card} na hromádce {stack} na desce {board}",
|
||||
"You have assigned {assigneduser} to card {card} on board {board}" : "Přiřadili jste {assigneduser} ke kartě {card} na desce {board}",
|
||||
"{user} has assigned {assigneduser} to card {card} on board {board}" : "{user} přiřadil(a) {assigneduser} ke kartě {card} na desce {board}",
|
||||
"You have unassigned {assigneduser} from card {card} on board {board}" : "Zrušili jste přiřazení {assigneduser} u karty {card} na nástěnce {board}",
|
||||
"{user} has unassigned {assigneduser} from card {card} on board {board}" : "{user} zrušil(a) přiřazení {assigneduser} z karty {card} na desce {board}",
|
||||
"You have moved the card {card} from stack {stackBefore} to {stack}" : "Přesunuli jste kartu {card} z balíčku {stackBefore} do {stack}",
|
||||
"{user} has moved the card {card} from stack {stackBefore} to {stack}" : "{user} přesunul(a) kartu {card} z balíčku {stackBefore} do {stack}",
|
||||
"You have added the attachment {attachment} to card {card}" : "Přidali jste přílohu {attachment} ke kartě {card}",
|
||||
"{user} has added the attachment {attachment} to card {card}" : "{user} přidal(a) přílohu {attachment} ke kartě {card}",
|
||||
"You have updated the attachment {attachment} on card {card}" : "Aktualizovali jste přílohu {attachment} u karty {card}",
|
||||
"{user} has updated the attachment {attachment} on card {card}" : "{user} aktualizoval(a) přílohu {attachment} u karty {card}",
|
||||
"You have updated the attachment {attachment} on card {card}" : "Aktualizovali jste přílohu {attachment} na kartě {card}",
|
||||
"{user} has updated the attachment {attachment} to card {card}" : "{user} aktualizoval(a) přílohu {attachment} ke kartě {card}",
|
||||
"You have deleted the attachment {attachment} from card {card}" : "Smazali jste přílohu {attachment} u karty {card}",
|
||||
"{user} has deleted the attachment {attachment} from card {card}" : "{user} smazal(a) přílohu {attachment} u karty {card}",
|
||||
"{user} has deleted the attachment {attachment} to card {card}" : "{user} smazal(a) přílohu {attachment} u karty {card}",
|
||||
"You have restored the attachment {attachment} to card {card}" : "Obnovili jste přílohu {attachment} ke kartě {card}",
|
||||
"{user} has restored the attachment {attachment} to card {card}" : "{user} obnovil(a) přílohu {attachment} ke kartě {card}",
|
||||
"You have commented on card {card}" : "Přidali jste komentář na kartě {card}",
|
||||
"{user} has commented on card {card}" : "{user} přidal(a) komentář na kartě {card}",
|
||||
"A <strong>card description</strong> inside the Deck app has been changed" : "<strong>Popis karty</strong> v aplikaci Deck byl změněn",
|
||||
"Deck" : "Deck",
|
||||
"Changes in the <strong>Deck app</strong>" : "Změny v <strong>aplikaci Deck</strong>",
|
||||
"A <strong>comment</strong> was created on a card" : "Na kartě byl vytvořen <strong>komentář</strong>",
|
||||
"A <strong>card description</strong> inside the Deck app has been changed" : "<strong>Popis mapy</strong> v Deck-aplikace byl změněn",
|
||||
"Deck" : "Balík",
|
||||
"Changes in the <strong>Deck app</strong>" : "Změny v <strong>Deck aplikace</strong>",
|
||||
"Personal" : "Osobní",
|
||||
"The card \"%s\" on \"%s\" has been assigned to you by %s." : "Kartu „%s“ na „%s“ vám přiřadil(a) %s.",
|
||||
"{user} has assigned the card \"%s\" on \"%s\" to you." : "{user} vám přiřadil(a) kartu „%s“ na „%s“.",
|
||||
"The card \"%s\" on \"%s\" has reached its due date." : "U karty „%s“ z tabule „%s“ nastalo plánované datum dokončení.",
|
||||
"The card \"%s\" on \"%s\" has reached its due date." : "U karty \"%s\" z tabule \"%s\" nastalo plánované datum dokončení.",
|
||||
"%s has mentioned you in a comment on \"%s\"." : "%s vás zmínil(a) v komentáři k „%s“.",
|
||||
"{user} has mentioned you in a comment on \"%s\"." : "{user} vás zmínil(a) v komentáři v „%s“.",
|
||||
"The board \"%s\" has been shared with you by %s." : "Uživatel %s vám nasdílel(a) tabuli „%s“.",
|
||||
"{user} has shared the board %s with you." : "{user} vám nasdílel(a) tabuli %s.",
|
||||
"No data was provided to create an attachment." : "Nebyla poskytnuta žádná data pro vytvoření přílohy.",
|
||||
"The board \"%s\" has been shared with you by %s." : "Tabule \"%s\" s vámi byla nasdílena uživatelem %s.",
|
||||
"{user} has shared the board %s with you." : "{user} s vámi nasdílel tabuli %s.",
|
||||
"No data was provided to create an attachment." : "Žádná data k vytvoření přílohy.",
|
||||
"Finished" : "Dokončeno",
|
||||
"To review" : "K revizi",
|
||||
"Action needed" : "Nutná akce",
|
||||
@@ -96,7 +93,7 @@
|
||||
"Example Task 2" : "Druhý úkol pro ukázku",
|
||||
"Example Task 1" : "První úkol pro ukázku",
|
||||
"The file was uploaded" : "Soubor byl nahrán",
|
||||
"The uploaded file exceeds the upload_max_filesize directive in php.ini" : "Velikost nahrávaného souboru překračuje limit nastavení direktivou upload_max_filesize v php.ini",
|
||||
"The uploaded file exceeds the upload_max_filesize directive in php.ini" : "Nahrávaný soubor přesahuje nastavení upload_max_filesize v php.ini",
|
||||
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Nahrávaný soubor přesáhl svou velikostí hodnotu direktivy MAX_FILE_SIZE, určenou v HTML formuláři",
|
||||
"The file was only partially uploaded" : "Soubor byl nahrán pouze z části",
|
||||
"No file was uploaded" : "Nebyl nahrán žádný soubor",
|
||||
@@ -105,21 +102,20 @@
|
||||
"A PHP extension stopped the file upload" : "PHP rozšíření zastavilo nahrávání souboru.",
|
||||
"No file uploaded or file size exceeds maximum of %s" : "Nebyl nahrán žádný soubor nebo jeho velikost přesáhla %s",
|
||||
"A kanban style project and personal management tool for Nextcloud" : "Nástroj pro projektový a osobní řízení ve stylu Kanban.",
|
||||
"Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deck je nástroj cílený na osobní nebo projektové plánování týmů v Kanban stylu, vestavěný v Nextcloud.\n\n\n- 📥 Zadávejte a uspořádávejte své úkoly do karet\n- 📄 Zapisujte si dodatečné poznámky \n- 🔖 Přiřazujte štítky pro ještě lepší organizaci\n- 👥 Sdílejte se svým týmem, přáteli nebo rodinou\n- 🚀 Dostaňte svůj projekt pod kontrolu",
|
||||
"Select the board to link to a project" : "Vyberte tabuli kterou propojit s projektem",
|
||||
"Select board" : "Vybrat tabuli",
|
||||
"Add a new stack" : "Přidat nový sloupec",
|
||||
"Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Karty jsou nástroj zacílený na osobní nebo projektové plánování týmů v Kanban stylu, vestavěný v Nextcloud.\n\n\n- 📥 Zadávejte a uspořádávejte své úkoly do karet\n- 📄 Zapisujte si dodatečné poznámky \n- 🔖 Přiřazujte štítky pro ještě lepší organizaci\n- 👥 Sdílejte se svým týmem, přáteli nebo rodinou\n- 🚀 Dostaňte svůj projekt pod kontrolu",
|
||||
"Select board" : "Vybrat nástěnku",
|
||||
"Add a new stack" : "Přidat nový zásobník",
|
||||
"Submit" : "Odeslat",
|
||||
"Show archived cards" : "Zobrazit archivované karty",
|
||||
"Hide archived cards" : "Skrýt archivované karty",
|
||||
"Toggle compact mode" : "Vyp/zap. kompaktní režim",
|
||||
"Show board details" : "Zobrazit podrobnosti o tabuli",
|
||||
"All Boards" : "Všechny tabule",
|
||||
"Archived boards" : "Archivované tabule",
|
||||
"Share board" : "Sdílet tabuli",
|
||||
"Show board details" : "Zobrazit podrobnosti o desce",
|
||||
"All Boards" : "Všechny desky",
|
||||
"Archived boards" : "Archivované desky",
|
||||
"Share board" : "Sdílet nástěnku",
|
||||
"Archived cards" : "Archivované karty",
|
||||
"Actions" : "Akce",
|
||||
"Drop your files here to upload it to the card" : "Soubory ke kartě připojíte přetažením sem",
|
||||
"Drop your files here to upload it to the card" : "Přetáhněte soubor sem, pokud jej chcete připojit ke kartě.",
|
||||
"Assign card to me" : "Přiřadit kartu mě",
|
||||
"Unassign card from me" : "Zrušit přiřazení karty mě",
|
||||
"Archive card" : "Archivovat kartu",
|
||||
@@ -129,7 +125,7 @@
|
||||
"Add card" : "Přidat kartu",
|
||||
"Close" : "Zavřít",
|
||||
"Sharing" : "Sdílení",
|
||||
"Tags" : "Štítky",
|
||||
"Tags" : "Značky",
|
||||
"Deleted items" : "Smazané položky",
|
||||
"Timeline" : "Časová osa",
|
||||
"Select users or groups to share with" : "Vyberte uživatele nebo skupiny pro sdílení",
|
||||
@@ -140,48 +136,48 @@
|
||||
"Edit" : "Upravit",
|
||||
"Share" : "Sdílet",
|
||||
"Manage" : "Spravovat",
|
||||
"Discard share" : "Zahodit sdílení",
|
||||
"Sharing has been disabled for your account." : "Sdílení bylo pro váš účet zakázáno.",
|
||||
"Discard share" : "Zrušit sdílení",
|
||||
"Sharing has been disabled for your account." : "Sdílení bylo zakázáno pro váš konto.",
|
||||
"Update tag" : "Aktualizovat štítek",
|
||||
"Edit tag" : "Upravit štítek",
|
||||
"Delete tag" : "Smazat štítek",
|
||||
"Create" : "Vytvořit",
|
||||
"Create a new tag" : "Vytvořit nový štítek",
|
||||
"Deleted stacks" : "Smazané sloupce",
|
||||
"Deleted stacks" : "Smazané zásobníky",
|
||||
"Deleted cards" : "Smazané karty",
|
||||
"Status" : "Stav",
|
||||
"No archived boards to display" : "Žádné archivované tabule k zobrazení",
|
||||
"No shared boards to display" : "Žádné sdílené tabule k zobrazení",
|
||||
"No archived boards to display" : "Žádné archivované nástěnky k zobrazení",
|
||||
"No shared boards to display" : "Žádné sdílené nástěnky k zobrazení",
|
||||
"Title" : "Název",
|
||||
"Members" : "Členové",
|
||||
"More actions" : "Více akcí",
|
||||
"Edit board" : "Upravit tabuli",
|
||||
"Archive board" : "Archivovat tabuli",
|
||||
"Unarchive board" : "Vrátit tabuli zpět z archivu",
|
||||
"Delete board" : "Smazat tabuli",
|
||||
"Update board" : "Aktualizovat tabuli",
|
||||
"Reset board" : "Vrátit tabuli do předchozího stavu",
|
||||
"Undo board deletion - Otherwise the board will be deleted during the next cronjob run." : "Vrátit smazání tabule – jinak bude nadobro odstraněna během příštího spuštění naplánovaných úloh.",
|
||||
"Create new board" : "Vytvořit novou tabuli",
|
||||
"New board title" : "Název nové tabule",
|
||||
"Create board" : "Vytvořit tabuli",
|
||||
"Edit board" : "Upravit desku",
|
||||
"Archive board" : "Archivovaná deska",
|
||||
"Unarchive board" : "Odarchivovat desku",
|
||||
"Delete board" : "Smazat desku",
|
||||
"Update board" : "Aktualizovat desku",
|
||||
"Reset board" : "Resetovat nástěnku",
|
||||
"Undo board deletion - Otherwise the board will be deleted during the next cronjob run." : "Vrátit smazání tabule - Tabule bude jinak trvale odstraněna během příštího běhu cronjobu.",
|
||||
"Create new board" : "Vytvořit novou desku",
|
||||
"New board title" : "Nadpis nové desky",
|
||||
"Create board" : "Vytvořit nástěnku",
|
||||
"Select an attachment" : "Vybrat přílohu",
|
||||
"Cancel upload" : "Zrušit nahrávání",
|
||||
"by" : "od",
|
||||
"Undo file deletion - Otherwise the file will be deleted during the next cronjob run." : "Vrátit smazání souboru – jinak bude trvale smazán při dalším běhu naplánované úlohy.",
|
||||
"Undo file deletion - Otherwise the file will be deleted during the next cronjob run." : "Vrátit smazání souboru – v opačném případě bude soubor trvale smazán při dalším běhu cronjobu.",
|
||||
"Undo file deletion" : "Vzít zpět smazání souboru",
|
||||
"Insert the file into the description" : "Vložte soubor do popisu",
|
||||
"Insert the file into the description" : "Vložte soubor do popisku.",
|
||||
"Delete attachment" : "Smazat přílohu",
|
||||
"Modified:" : "Změněno:",
|
||||
"Modified:" : "Upraveno:",
|
||||
"Created:" : "Vytvořeno:",
|
||||
"Choose a tag" : "Zvolte štítek",
|
||||
"Choose a tag" : "Vyberte štítek",
|
||||
"Add a tag" : "Přidat štítek",
|
||||
"Select tags" : "Výběr štítků",
|
||||
"Assign users" : "Přiřadit uživatele",
|
||||
"Choose a user to assign" : "Zvolte uživatele kterého přiřadit",
|
||||
"Assign this card to a user" : "Přiřadit tuto kartu uživateli",
|
||||
"Assign this card to a user" : "Přiřadit kartu uživateli",
|
||||
"Due date" : "Termín",
|
||||
"Click to set" : "Klikn. vyberte",
|
||||
"Click to set" : "Klikněte pro výběr",
|
||||
"Remove due date" : "Odstranit termín",
|
||||
"Description" : "Popis",
|
||||
"Attachments" : "Přílohy",
|
||||
@@ -190,12 +186,12 @@
|
||||
"Insert attachment" : "Vložit přílohu",
|
||||
"Formatting help" : "Nápověda k formátování",
|
||||
"Upload attachment" : "Nahrát přílohu",
|
||||
"Add a card description…" : "Přidejte popis karty…",
|
||||
"Shared boards" : "Sdílené tabule",
|
||||
"Move board to archive" : "Přesunout tabuli do archivu",
|
||||
"Create a new board" : "Vytvořit novou tabuli",
|
||||
"Add a card description…" : "Přidat popis karty…",
|
||||
"Shared boards" : "Sdílené desky",
|
||||
"Move board to archive" : "Přesunout desku do archivu",
|
||||
"Create a new board" : "Vytvořit novou desku",
|
||||
"Settings" : "Nastavení",
|
||||
"Limit deck to groups" : "Omezit Deck na skupiny",
|
||||
"Limiting Deck will block users not part of those groups from creating their own boards. Users will still be able to work on boards that have been shared with them." : "Omezení nastavené pro Deck brání uživatelům, kteří nejsou součástí těchto skupin, ve vytváření vlastních tabulí. Nicméně i tak ale pořád budou moci pracovat na tabulích, které jsou jim nasdíleny."
|
||||
"Limit deck to groups" : "Omezte Deck na skupiny",
|
||||
"Limiting Deck will block users not part of those groups from creating their own boards. Users will still be able to work on boards that have been shared with them." : "Omezení Decků brání uživatelům, kteří nejsou součástí těchto skupin, při vytváření vlastních desek. Uživatelé mohou stále pracovat na deskách, které jsou s nimi sdíleny."
|
||||
},"pluralForm" :"nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;"
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
OC.L10N.register(
|
||||
"deck",
|
||||
{
|
||||
"Personal" : "Personol",
|
||||
"Done" : "Done",
|
||||
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Mae'r ffeil lwythwyd i fyny'n fwy na chyfarwyddeb MAX_FILE_SIZE bennwyd yn y ffurflen HTML",
|
||||
"No file was uploaded" : "Ni lwythwyd ffeil i fyny",
|
||||
"Missing a temporary folder" : "Plygell dros dro yn eisiau",
|
||||
"Actions" : "Gweithredoedd",
|
||||
"Close" : "Cau",
|
||||
"Tags" : "Tagiau",
|
||||
"Group" : "Grŵp",
|
||||
"Loading" : "Llwytho",
|
||||
"Edit" : "Golygu",
|
||||
"Share" : "Rhannu",
|
||||
"Create" : "Creu",
|
||||
"Title" : "Teitl",
|
||||
"Cancel upload" : "Diddymu llwytho i fyny",
|
||||
"by" : "gan",
|
||||
"Modified:" : "Addaswyd:",
|
||||
"Created:" : "Crewyd:",
|
||||
"Description" : "Disgrifiad",
|
||||
"Saved" : "Wedi'u cadw",
|
||||
"Upload attachment" : "Llwytho atodiad",
|
||||
"Settings" : "Gosodiadau"
|
||||
},
|
||||
"nplurals=4; plural=(n==1) ? 0 : (n==2) ? 1 : (n != 8 && n != 11) ? 2 : 3;");
|
||||
@@ -1,25 +0,0 @@
|
||||
{ "translations": {
|
||||
"Personal" : "Personol",
|
||||
"Done" : "Done",
|
||||
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Mae'r ffeil lwythwyd i fyny'n fwy na chyfarwyddeb MAX_FILE_SIZE bennwyd yn y ffurflen HTML",
|
||||
"No file was uploaded" : "Ni lwythwyd ffeil i fyny",
|
||||
"Missing a temporary folder" : "Plygell dros dro yn eisiau",
|
||||
"Actions" : "Gweithredoedd",
|
||||
"Close" : "Cau",
|
||||
"Tags" : "Tagiau",
|
||||
"Group" : "Grŵp",
|
||||
"Loading" : "Llwytho",
|
||||
"Edit" : "Golygu",
|
||||
"Share" : "Rhannu",
|
||||
"Create" : "Creu",
|
||||
"Title" : "Teitl",
|
||||
"Cancel upload" : "Diddymu llwytho i fyny",
|
||||
"by" : "gan",
|
||||
"Modified:" : "Addaswyd:",
|
||||
"Created:" : "Crewyd:",
|
||||
"Description" : "Disgrifiad",
|
||||
"Saved" : "Wedi'u cadw",
|
||||
"Upload attachment" : "Llwytho atodiad",
|
||||
"Settings" : "Gosodiadau"
|
||||
},"pluralForm" :"nplurals=4; plural=(n==1) ? 0 : (n==2) ? 1 : (n != 8 && n != 11) ? 2 : 3;"
|
||||
}
|
||||
16
l10n/da.js
16
l10n/da.js
@@ -4,9 +4,7 @@ OC.L10N.register(
|
||||
"Remove user from card" : "Fjern bruger fra kort",
|
||||
"Hours" : "Timer",
|
||||
"Minutes" : "Minutter",
|
||||
"File already exists" : "Fil findes allerede",
|
||||
"Deck" : "Deck",
|
||||
"Personal" : "Personlig",
|
||||
"The card \"%s\" on \"%s\" has reached its due date." : "Kortet \"%s\" på \"%s\" har nået sin udløbsdato.",
|
||||
"The board \"%s\" has been shared with you by %s." : "Brættet \"%s\" er blevet delt med dig af %s.",
|
||||
"{user} has shared the board %s with you." : "{user} har delt brættet %s med dig.",
|
||||
@@ -14,11 +12,6 @@ OC.L10N.register(
|
||||
"To review" : "Gennemse",
|
||||
"Action needed" : "Handling påkrævet",
|
||||
"Later" : "Senere",
|
||||
"Done" : "Færdig",
|
||||
"The uploaded file exceeds the upload_max_filesize directive in php.ini" : "Den uploadede fil overstiger upload_max_filesize direktivet i php.ini",
|
||||
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Den uploadede fil overstiger MAX_FILE_SIZE indstilingen, som specificeret i HTML formularen",
|
||||
"No file was uploaded" : "Ingen fil uploadet",
|
||||
"Missing a temporary folder" : "Manglende midlertidig mappe.",
|
||||
"A kanban style project and personal management tool for Nextcloud" : "Et Kanban-inspireret projekt- og styringsværktøj til Nextcloud",
|
||||
"Add a new stack" : "Tilføj en ny stak",
|
||||
"Submit" : "Tilføj",
|
||||
@@ -26,17 +19,12 @@ OC.L10N.register(
|
||||
"Hide archived cards" : "Skjul arkiverede kort",
|
||||
"All Boards" : "Alle lister",
|
||||
"Archived boards" : "Arkiverede lister",
|
||||
"Actions" : "Handlinger",
|
||||
"Archive card" : "Arkivér kort",
|
||||
"Delete card" : "Slet kort",
|
||||
"Enter a card title" : "Angiv titel på kort",
|
||||
"Add card" : "Tilføj kort",
|
||||
"Close" : "Luk",
|
||||
"Sharing" : "Deling",
|
||||
"Tags" : "Mærkat",
|
||||
"Select users or groups to share with" : "Vælg brugere eller grupper og dele med",
|
||||
"Group" : "Gruppe",
|
||||
"Circle" : "Cirkel",
|
||||
"No matching user or group found." : "Ingen bruger eller gruppe fundet",
|
||||
"Loading" : "Loader",
|
||||
"Edit" : "Redigér",
|
||||
@@ -56,8 +44,6 @@ OC.L10N.register(
|
||||
"Undo board deletion - Otherwise the board will be deleted during the next cronjob run." : "Fortryd sletning af board - Ellers vil boardet blive slettet ved næste cronjob kørsel.",
|
||||
"Create new board" : "Opret ny liste",
|
||||
"New board title" : "Ny titel på liste",
|
||||
"Create board" : "Opret liste",
|
||||
"Cancel upload" : "Annuller upload ",
|
||||
"by" : "af",
|
||||
"Modified:" : "Ændret:",
|
||||
"Created:" : "Oprettet:",
|
||||
@@ -71,11 +57,9 @@ OC.L10N.register(
|
||||
"Click to set" : "Klik for at sætte",
|
||||
"Remove due date" : "Fjern forfaldsdato",
|
||||
"Description" : "Beskrivelse",
|
||||
"Attachments" : "Vedhæftede filer",
|
||||
"Saved" : "Gemt",
|
||||
"Unsaved changes" : "Ikke gemte ændringer",
|
||||
"Formatting help" : "Hjælp til formatering",
|
||||
"Upload attachment" : "Upload vedhæftning",
|
||||
"Add a card description…" : "Tilføj en beskrivelse...",
|
||||
"Shared boards" : "Delte lister",
|
||||
"Move board to archive" : "Flyt liste til arkiv",
|
||||
|
||||
16
l10n/da.json
16
l10n/da.json
@@ -2,9 +2,7 @@
|
||||
"Remove user from card" : "Fjern bruger fra kort",
|
||||
"Hours" : "Timer",
|
||||
"Minutes" : "Minutter",
|
||||
"File already exists" : "Fil findes allerede",
|
||||
"Deck" : "Deck",
|
||||
"Personal" : "Personlig",
|
||||
"The card \"%s\" on \"%s\" has reached its due date." : "Kortet \"%s\" på \"%s\" har nået sin udløbsdato.",
|
||||
"The board \"%s\" has been shared with you by %s." : "Brættet \"%s\" er blevet delt med dig af %s.",
|
||||
"{user} has shared the board %s with you." : "{user} har delt brættet %s med dig.",
|
||||
@@ -12,11 +10,6 @@
|
||||
"To review" : "Gennemse",
|
||||
"Action needed" : "Handling påkrævet",
|
||||
"Later" : "Senere",
|
||||
"Done" : "Færdig",
|
||||
"The uploaded file exceeds the upload_max_filesize directive in php.ini" : "Den uploadede fil overstiger upload_max_filesize direktivet i php.ini",
|
||||
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Den uploadede fil overstiger MAX_FILE_SIZE indstilingen, som specificeret i HTML formularen",
|
||||
"No file was uploaded" : "Ingen fil uploadet",
|
||||
"Missing a temporary folder" : "Manglende midlertidig mappe.",
|
||||
"A kanban style project and personal management tool for Nextcloud" : "Et Kanban-inspireret projekt- og styringsværktøj til Nextcloud",
|
||||
"Add a new stack" : "Tilføj en ny stak",
|
||||
"Submit" : "Tilføj",
|
||||
@@ -24,17 +17,12 @@
|
||||
"Hide archived cards" : "Skjul arkiverede kort",
|
||||
"All Boards" : "Alle lister",
|
||||
"Archived boards" : "Arkiverede lister",
|
||||
"Actions" : "Handlinger",
|
||||
"Archive card" : "Arkivér kort",
|
||||
"Delete card" : "Slet kort",
|
||||
"Enter a card title" : "Angiv titel på kort",
|
||||
"Add card" : "Tilføj kort",
|
||||
"Close" : "Luk",
|
||||
"Sharing" : "Deling",
|
||||
"Tags" : "Mærkat",
|
||||
"Select users or groups to share with" : "Vælg brugere eller grupper og dele med",
|
||||
"Group" : "Gruppe",
|
||||
"Circle" : "Cirkel",
|
||||
"No matching user or group found." : "Ingen bruger eller gruppe fundet",
|
||||
"Loading" : "Loader",
|
||||
"Edit" : "Redigér",
|
||||
@@ -54,8 +42,6 @@
|
||||
"Undo board deletion - Otherwise the board will be deleted during the next cronjob run." : "Fortryd sletning af board - Ellers vil boardet blive slettet ved næste cronjob kørsel.",
|
||||
"Create new board" : "Opret ny liste",
|
||||
"New board title" : "Ny titel på liste",
|
||||
"Create board" : "Opret liste",
|
||||
"Cancel upload" : "Annuller upload ",
|
||||
"by" : "af",
|
||||
"Modified:" : "Ændret:",
|
||||
"Created:" : "Oprettet:",
|
||||
@@ -69,11 +55,9 @@
|
||||
"Click to set" : "Klik for at sætte",
|
||||
"Remove due date" : "Fjern forfaldsdato",
|
||||
"Description" : "Beskrivelse",
|
||||
"Attachments" : "Vedhæftede filer",
|
||||
"Saved" : "Gemt",
|
||||
"Unsaved changes" : "Ikke gemte ændringer",
|
||||
"Formatting help" : "Hjælp til formatering",
|
||||
"Upload attachment" : "Upload vedhæftning",
|
||||
"Add a card description…" : "Tilføj en beskrivelse...",
|
||||
"Shared boards" : "Delte lister",
|
||||
"Move board to archive" : "Flyt liste til arkiv",
|
||||
|
||||
10
l10n/de.js
10
l10n/de.js
@@ -67,9 +67,9 @@ OC.L10N.register(
|
||||
"You have added the attachment {attachment} to card {card}" : "Du hast den Anhang {attachment} zur Karte {card} hinzugefügt",
|
||||
"{user} has added the attachment {attachment} to card {card}" : "{user} hat den Anhang {attachment} zur Karte {card} hinzugefügt",
|
||||
"You have updated the attachment {attachment} on card {card}" : "Du hast den Anhang {attachment} der Karte {card} aktualisiert",
|
||||
"{user} has updated the attachment {attachment} on card {card}" : "{user} hat den Anhang {attachment} der Karte {card} aktualisiert",
|
||||
"{user} has updated the attachment {attachment} to card {card}" : "{user} hat den Anhang {attachment} der Karte {card} aktualisiert",
|
||||
"You have deleted the attachment {attachment} from card {card}" : "Du hast den Anhang {attachment} von der Karte {card} entfernt",
|
||||
"{user} has deleted the attachment {attachment} from card {card}" : "{user} hat den Anhang {attachment} von Karte {card} entfernt",
|
||||
"{user} has deleted the attachment {attachment} to card {card}" : "{user} hat den Anhang {attachment} von Karte {card} entfernt",
|
||||
"You have restored the attachment {attachment} to card {card}" : "Du hast den Anhang {attachment} der Karte {card} wiederhergestellt",
|
||||
"{user} has restored the attachment {attachment} to card {card}" : "{user} hat den Anhang {attachment} der Karte {card} wiederhergestellt",
|
||||
"You have commented on card {card}" : "Du hast die Karte {card} kommentiert",
|
||||
@@ -99,14 +99,14 @@ OC.L10N.register(
|
||||
"Example Task 1" : "Beispielaufgabe 1",
|
||||
"The file was uploaded" : "Die Datei wurde hochgeladen",
|
||||
"The uploaded file exceeds the upload_max_filesize directive in php.ini" : "Die hochgeladene Datei überschreitet die upload_max_filesize-Vorgabe in php.ini",
|
||||
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Die Datei ist größer als die MAX_FILE_SIZE-Vorgabe, die im HTML-Formular angegeben ist.",
|
||||
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Die Datei ist größer, als die MAX_FILE_SIZE-Vorgabe, die im HTML-Formular angegeben ist.",
|
||||
"The file was only partially uploaded" : "Die Datei konnte nur teilweise hochgeladen werden",
|
||||
"No file was uploaded" : "Es wurde keine Datei hochgeladen",
|
||||
"Missing a temporary folder" : "Kein temporärer Ordner vorhanden",
|
||||
"Could not write file to disk" : "Die Datei konnte nicht auf die Festplatte geschrieben werden",
|
||||
"A PHP extension stopped the file upload" : "Eine PHP-Erweiterung hat das Hochladen der Datei gestoppt",
|
||||
"No file uploaded or file size exceeds maximum of %s" : "Keine Datei hochgeladen oder die Dateigröße überschreitet %s",
|
||||
"A kanban style project and personal management tool for Nextcloud" : "Ein Kanban-Werkzeug für Nextcloud",
|
||||
"A kanban style project and personal management tool for Nextcloud" : "Ein Kanban Werkzeug für Nextcloud",
|
||||
"Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deck ist ein Organisationstool im Kanban-Stil für die persönliche Planung und Projektorganisation von Teams, die in Nextcloud integriert sind.\n\n\n- 📥 Füge Deine Aufgaben zu den Karten hinzu und ordne diese\n- 📄 Zusätzliche Hinweise in der Abschrift notieren\n- 🔖 Vergabe von Labels für noch bessere Organisation\n- 👥 Teile mit Deinem Team, Freunden oder der Familie\n- 📎 Füge Dateien hinzu und verwende diese in Deinen Markdown-Beschreibungen\n- 💬 Diskutiere mit Deinem Team mit Kommentaren\n- ⚡ Behalte Überblick über Änderungen mit dem Aktivitäten-Stream\n- 🚀 Organisiere Dein Projekt",
|
||||
"Select the board to link to a project" : "Wähle ein Board aus, um dieses mit einem Projekt zu verknüpfen",
|
||||
"Select board" : "Board auswählen",
|
||||
@@ -170,7 +170,7 @@ OC.L10N.register(
|
||||
"Select an attachment" : "Anhang auswählen",
|
||||
"Cancel upload" : "Hochladen abbrechen",
|
||||
"by" : "von",
|
||||
"Undo file deletion - Otherwise the file will be deleted during the next cronjob run." : "Dateilöschung rückgängig machen — andernfalls wird die Datei beim nächsten Cron-Job-Lauf gelöscht.",
|
||||
"Undo file deletion - Otherwise the file will be deleted during the next cronjob run." : "Dateilöschung rückgängig machen - andernfalls wird die Datei beim nächsten Cron-Job-Lauf gelöscht.",
|
||||
"Undo file deletion" : "Dateilöschung rückgängig machen",
|
||||
"Insert the file into the description" : "Füge die Datei in die Beschreibung ein",
|
||||
"Delete attachment" : "Anhang löschen",
|
||||
|
||||
10
l10n/de.json
10
l10n/de.json
@@ -65,9 +65,9 @@
|
||||
"You have added the attachment {attachment} to card {card}" : "Du hast den Anhang {attachment} zur Karte {card} hinzugefügt",
|
||||
"{user} has added the attachment {attachment} to card {card}" : "{user} hat den Anhang {attachment} zur Karte {card} hinzugefügt",
|
||||
"You have updated the attachment {attachment} on card {card}" : "Du hast den Anhang {attachment} der Karte {card} aktualisiert",
|
||||
"{user} has updated the attachment {attachment} on card {card}" : "{user} hat den Anhang {attachment} der Karte {card} aktualisiert",
|
||||
"{user} has updated the attachment {attachment} to card {card}" : "{user} hat den Anhang {attachment} der Karte {card} aktualisiert",
|
||||
"You have deleted the attachment {attachment} from card {card}" : "Du hast den Anhang {attachment} von der Karte {card} entfernt",
|
||||
"{user} has deleted the attachment {attachment} from card {card}" : "{user} hat den Anhang {attachment} von Karte {card} entfernt",
|
||||
"{user} has deleted the attachment {attachment} to card {card}" : "{user} hat den Anhang {attachment} von Karte {card} entfernt",
|
||||
"You have restored the attachment {attachment} to card {card}" : "Du hast den Anhang {attachment} der Karte {card} wiederhergestellt",
|
||||
"{user} has restored the attachment {attachment} to card {card}" : "{user} hat den Anhang {attachment} der Karte {card} wiederhergestellt",
|
||||
"You have commented on card {card}" : "Du hast die Karte {card} kommentiert",
|
||||
@@ -97,14 +97,14 @@
|
||||
"Example Task 1" : "Beispielaufgabe 1",
|
||||
"The file was uploaded" : "Die Datei wurde hochgeladen",
|
||||
"The uploaded file exceeds the upload_max_filesize directive in php.ini" : "Die hochgeladene Datei überschreitet die upload_max_filesize-Vorgabe in php.ini",
|
||||
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Die Datei ist größer als die MAX_FILE_SIZE-Vorgabe, die im HTML-Formular angegeben ist.",
|
||||
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Die Datei ist größer, als die MAX_FILE_SIZE-Vorgabe, die im HTML-Formular angegeben ist.",
|
||||
"The file was only partially uploaded" : "Die Datei konnte nur teilweise hochgeladen werden",
|
||||
"No file was uploaded" : "Es wurde keine Datei hochgeladen",
|
||||
"Missing a temporary folder" : "Kein temporärer Ordner vorhanden",
|
||||
"Could not write file to disk" : "Die Datei konnte nicht auf die Festplatte geschrieben werden",
|
||||
"A PHP extension stopped the file upload" : "Eine PHP-Erweiterung hat das Hochladen der Datei gestoppt",
|
||||
"No file uploaded or file size exceeds maximum of %s" : "Keine Datei hochgeladen oder die Dateigröße überschreitet %s",
|
||||
"A kanban style project and personal management tool for Nextcloud" : "Ein Kanban-Werkzeug für Nextcloud",
|
||||
"A kanban style project and personal management tool for Nextcloud" : "Ein Kanban Werkzeug für Nextcloud",
|
||||
"Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deck ist ein Organisationstool im Kanban-Stil für die persönliche Planung und Projektorganisation von Teams, die in Nextcloud integriert sind.\n\n\n- 📥 Füge Deine Aufgaben zu den Karten hinzu und ordne diese\n- 📄 Zusätzliche Hinweise in der Abschrift notieren\n- 🔖 Vergabe von Labels für noch bessere Organisation\n- 👥 Teile mit Deinem Team, Freunden oder der Familie\n- 📎 Füge Dateien hinzu und verwende diese in Deinen Markdown-Beschreibungen\n- 💬 Diskutiere mit Deinem Team mit Kommentaren\n- ⚡ Behalte Überblick über Änderungen mit dem Aktivitäten-Stream\n- 🚀 Organisiere Dein Projekt",
|
||||
"Select the board to link to a project" : "Wähle ein Board aus, um dieses mit einem Projekt zu verknüpfen",
|
||||
"Select board" : "Board auswählen",
|
||||
@@ -168,7 +168,7 @@
|
||||
"Select an attachment" : "Anhang auswählen",
|
||||
"Cancel upload" : "Hochladen abbrechen",
|
||||
"by" : "von",
|
||||
"Undo file deletion - Otherwise the file will be deleted during the next cronjob run." : "Dateilöschung rückgängig machen — andernfalls wird die Datei beim nächsten Cron-Job-Lauf gelöscht.",
|
||||
"Undo file deletion - Otherwise the file will be deleted during the next cronjob run." : "Dateilöschung rückgängig machen - andernfalls wird die Datei beim nächsten Cron-Job-Lauf gelöscht.",
|
||||
"Undo file deletion" : "Dateilöschung rückgängig machen",
|
||||
"Insert the file into the description" : "Füge die Datei in die Beschreibung ein",
|
||||
"Delete attachment" : "Anhang löschen",
|
||||
|
||||
@@ -2,7 +2,7 @@ OC.L10N.register(
|
||||
"deck",
|
||||
{
|
||||
"Please provide a content for your comment." : "Bitte geben Sie einen Inhalt für Ihren Kommentar an.",
|
||||
"Posting the comment failed." : "Senden des Kommentars fehlgeschlagen.",
|
||||
"Posting the comment failed." : "Absenden des Kommentars ist fehlgeschlagen.",
|
||||
"The comment has been deleted" : "Der Kommentar wurde gelöscht",
|
||||
"The associated stack is deleted as well, it will be restored as well." : "Der dazugehörige Stapel wurde auch gelöscht, er wird ebenfalls wiederhergestellt.",
|
||||
"Restore associated stack" : "Dazugehörigen Stapel wiederherstellen",
|
||||
@@ -67,9 +67,9 @@ OC.L10N.register(
|
||||
"You have added the attachment {attachment} to card {card}" : "Sie haben den Anhang {attachment} zur Karte {card} hinzugefügt",
|
||||
"{user} has added the attachment {attachment} to card {card}" : "{user} hat den Anhang {attachment} zur Karte {card} hinzugefügt",
|
||||
"You have updated the attachment {attachment} on card {card}" : "Sie haben den Anhang {attachment} der Karte {card} aktualisiert",
|
||||
"{user} has updated the attachment {attachment} on card {card}" : "{user} hat den Anhang {attachment} der Karte {card} aktualisiert",
|
||||
"{user} has updated the attachment {attachment} to card {card}" : "{user} hat den Anhang {attachment} der Karte {card} aktualisiert",
|
||||
"You have deleted the attachment {attachment} from card {card}" : "Sie haben den Anhang {attachment} von der Karte {card} entfernt",
|
||||
"{user} has deleted the attachment {attachment} from card {card}" : "{user} hat den Anhang {attachment} von Karte {card} entfernt",
|
||||
"{user} has deleted the attachment {attachment} to card {card}" : "{user} hat den Anhang {attachment} von Karte {card} entfernt",
|
||||
"You have restored the attachment {attachment} to card {card}" : "Sie haben den Anhang {attachment} der Karte {card} wiederhergestellt",
|
||||
"{user} has restored the attachment {attachment} to card {card}" : "{user} hat den Anhang {attachment} der Karte {card} wiederhergestellt",
|
||||
"You have commented on card {card}" : "Sie haben die Karte {card} kommentiert",
|
||||
@@ -94,9 +94,9 @@ OC.L10N.register(
|
||||
"To do" : "Offen",
|
||||
"Doing" : "In Arbeit",
|
||||
"Done" : "Erledigt",
|
||||
"Example Task 3" : "Beispielsaufgabe 3",
|
||||
"Example Task 2" : "Beispielsaufgabe 2",
|
||||
"Example Task 1" : "Beispielsaufgabe 1",
|
||||
"Example Task 3" : "Beispielaufgabe 3",
|
||||
"Example Task 2" : "Beispielaufgabe 2",
|
||||
"Example Task 1" : "Beispielaufgabe 1",
|
||||
"The file was uploaded" : "Die Datei wurde hochgeladen",
|
||||
"The uploaded file exceeds the upload_max_filesize directive in php.ini" : "Die hochgeladene Datei überschreitet die upload_max_filesize-Vorgabe in php.ini",
|
||||
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Die Datei ist größer, als die MAX_FILE_SIZE-Vorgabe, die im HTML-Formular angegeben ist.",
|
||||
@@ -106,7 +106,7 @@ OC.L10N.register(
|
||||
"Could not write file to disk" : "Die Datei konnte nicht auf die Festplatte geschrieben werden",
|
||||
"A PHP extension stopped the file upload" : "Eine PHP-Erweiterung hat das Hochladen der Datei gestoppt",
|
||||
"No file uploaded or file size exceeds maximum of %s" : "Keine Datei hochgeladen oder die Dateigröße überschreitet %s",
|
||||
"A kanban style project and personal management tool for Nextcloud" : "Ein Kanban-Werkzeug für Nextcloud",
|
||||
"A kanban style project and personal management tool for Nextcloud" : "Ein Kanban Werkzeug für Nextcloud",
|
||||
"Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deck ist ein Organisationstool im Kanban-Stil für die persönliche Planung und Projektorganisation von Teams, die in Nextcloud integriert sind.\n\n\n- 📥 Fügen Sie Ihre Aufgaben zu den Karten hinzu und ordnen Sie diese\n- 📄 Zusätzliche Hinweise in der Abschrift notieren\n- 🔖 Zuweisung von Labels für noch bessere Organisation\n- 👥 Teilen Sie mit Ihrem Team, Ihren Freunden oder Ihrer Familie\n- 📎 Fügen Sie Dateien hinzu und verwende diese in Ihren Markdown-Beschreibungen\n- 💬 Diskutieren Sie mit Ihrem Team mit Kommentaren\n- ⚡ Behalten Sie Überblick über Änderungen mit dem Aktivitäten-Stream\n- 🚀 Organisieren Sie Ihr Projekt",
|
||||
"Select the board to link to a project" : "Wählen Sie ein Board aus, um dieses mit einem Projekt zu verknüpfen",
|
||||
"Select board" : "Board auswählen",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{ "translations": {
|
||||
"Please provide a content for your comment." : "Bitte geben Sie einen Inhalt für Ihren Kommentar an.",
|
||||
"Posting the comment failed." : "Senden des Kommentars fehlgeschlagen.",
|
||||
"Posting the comment failed." : "Absenden des Kommentars ist fehlgeschlagen.",
|
||||
"The comment has been deleted" : "Der Kommentar wurde gelöscht",
|
||||
"The associated stack is deleted as well, it will be restored as well." : "Der dazugehörige Stapel wurde auch gelöscht, er wird ebenfalls wiederhergestellt.",
|
||||
"Restore associated stack" : "Dazugehörigen Stapel wiederherstellen",
|
||||
@@ -65,9 +65,9 @@
|
||||
"You have added the attachment {attachment} to card {card}" : "Sie haben den Anhang {attachment} zur Karte {card} hinzugefügt",
|
||||
"{user} has added the attachment {attachment} to card {card}" : "{user} hat den Anhang {attachment} zur Karte {card} hinzugefügt",
|
||||
"You have updated the attachment {attachment} on card {card}" : "Sie haben den Anhang {attachment} der Karte {card} aktualisiert",
|
||||
"{user} has updated the attachment {attachment} on card {card}" : "{user} hat den Anhang {attachment} der Karte {card} aktualisiert",
|
||||
"{user} has updated the attachment {attachment} to card {card}" : "{user} hat den Anhang {attachment} der Karte {card} aktualisiert",
|
||||
"You have deleted the attachment {attachment} from card {card}" : "Sie haben den Anhang {attachment} von der Karte {card} entfernt",
|
||||
"{user} has deleted the attachment {attachment} from card {card}" : "{user} hat den Anhang {attachment} von Karte {card} entfernt",
|
||||
"{user} has deleted the attachment {attachment} to card {card}" : "{user} hat den Anhang {attachment} von Karte {card} entfernt",
|
||||
"You have restored the attachment {attachment} to card {card}" : "Sie haben den Anhang {attachment} der Karte {card} wiederhergestellt",
|
||||
"{user} has restored the attachment {attachment} to card {card}" : "{user} hat den Anhang {attachment} der Karte {card} wiederhergestellt",
|
||||
"You have commented on card {card}" : "Sie haben die Karte {card} kommentiert",
|
||||
@@ -92,9 +92,9 @@
|
||||
"To do" : "Offen",
|
||||
"Doing" : "In Arbeit",
|
||||
"Done" : "Erledigt",
|
||||
"Example Task 3" : "Beispielsaufgabe 3",
|
||||
"Example Task 2" : "Beispielsaufgabe 2",
|
||||
"Example Task 1" : "Beispielsaufgabe 1",
|
||||
"Example Task 3" : "Beispielaufgabe 3",
|
||||
"Example Task 2" : "Beispielaufgabe 2",
|
||||
"Example Task 1" : "Beispielaufgabe 1",
|
||||
"The file was uploaded" : "Die Datei wurde hochgeladen",
|
||||
"The uploaded file exceeds the upload_max_filesize directive in php.ini" : "Die hochgeladene Datei überschreitet die upload_max_filesize-Vorgabe in php.ini",
|
||||
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Die Datei ist größer, als die MAX_FILE_SIZE-Vorgabe, die im HTML-Formular angegeben ist.",
|
||||
@@ -104,7 +104,7 @@
|
||||
"Could not write file to disk" : "Die Datei konnte nicht auf die Festplatte geschrieben werden",
|
||||
"A PHP extension stopped the file upload" : "Eine PHP-Erweiterung hat das Hochladen der Datei gestoppt",
|
||||
"No file uploaded or file size exceeds maximum of %s" : "Keine Datei hochgeladen oder die Dateigröße überschreitet %s",
|
||||
"A kanban style project and personal management tool for Nextcloud" : "Ein Kanban-Werkzeug für Nextcloud",
|
||||
"A kanban style project and personal management tool for Nextcloud" : "Ein Kanban Werkzeug für Nextcloud",
|
||||
"Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deck ist ein Organisationstool im Kanban-Stil für die persönliche Planung und Projektorganisation von Teams, die in Nextcloud integriert sind.\n\n\n- 📥 Fügen Sie Ihre Aufgaben zu den Karten hinzu und ordnen Sie diese\n- 📄 Zusätzliche Hinweise in der Abschrift notieren\n- 🔖 Zuweisung von Labels für noch bessere Organisation\n- 👥 Teilen Sie mit Ihrem Team, Ihren Freunden oder Ihrer Familie\n- 📎 Fügen Sie Dateien hinzu und verwende diese in Ihren Markdown-Beschreibungen\n- 💬 Diskutieren Sie mit Ihrem Team mit Kommentaren\n- ⚡ Behalten Sie Überblick über Änderungen mit dem Aktivitäten-Stream\n- 🚀 Organisieren Sie Ihr Projekt",
|
||||
"Select the board to link to a project" : "Wählen Sie ein Board aus, um dieses mit einem Projekt zu verknüpfen",
|
||||
"Select board" : "Board auswählen",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user