Compare commits
74 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
124cc94939 | ||
|
|
d45f2e9faa | ||
|
|
2ea019885d | ||
|
|
ccbe2eaf94 | ||
|
|
568b099c17 | ||
|
|
a5bd24f475 | ||
|
|
89bec2752b | ||
|
|
2a1fa11b0d | ||
|
|
ba5570558e | ||
|
|
df0531851e | ||
|
|
bbc218de95 | ||
|
|
9b6d62d24c | ||
|
|
d2ceda08cb | ||
|
|
af01ecd3d1 | ||
|
|
7afe28f2e9 | ||
|
|
56a79c9fcc | ||
|
|
6fa485c6ca | ||
|
|
66e386b547 | ||
|
|
48e6bae44a | ||
|
|
c75463429e | ||
|
|
3d3f2de781 | ||
|
|
2454df9a35 | ||
|
|
2a7a0e4c6d | ||
|
|
6edf265b78 | ||
|
|
8e28f8e67c | ||
|
|
3b11c5c7ea | ||
|
|
be05ec1b45 | ||
|
|
b407f102fe | ||
|
|
e82a2be836 | ||
|
|
d7f7cf584f | ||
|
|
3fae174906 | ||
|
|
b58bba25bb | ||
|
|
407acc47a4 | ||
|
|
2ba19bd6fe | ||
|
|
16e79dc616 | ||
|
|
f48187f28c | ||
|
|
ea5aac3d27 | ||
|
|
3487e06c8c | ||
|
|
fd253009f1 | ||
|
|
039d3e8238 | ||
|
|
31d759ee62 | ||
|
|
53a30585f3 | ||
|
|
a2ebf3d3f0 | ||
|
|
5b7505c60c | ||
|
|
516b15d3a1 | ||
|
|
6ac8cafd46 | ||
|
|
e5c65a67a7 | ||
|
|
7b72c93076 | ||
|
|
f5550c456e | ||
|
|
fb8b724e1b | ||
|
|
a3da157aa4 | ||
|
|
0118c1e409 | ||
|
|
9dbf45ca25 | ||
|
|
184cb01f5a | ||
|
|
b3a4cca482 | ||
|
|
1272c672ae | ||
|
|
214898c3d6 | ||
|
|
7ba20e71ee | ||
|
|
49f84c31fb | ||
|
|
69f56981f4 | ||
|
|
7acd1a054e | ||
|
|
ef90ab0b2a | ||
|
|
1a275b0884 | ||
|
|
ffb25a7553 | ||
|
|
9a0476f538 | ||
|
|
9b9413c5e1 | ||
|
|
e22c6e675b | ||
|
|
92a6cbce37 | ||
|
|
871edf1a25 | ||
|
|
05376a5d3a | ||
|
|
5cc52526cf | ||
|
|
30bb429a57 | ||
|
|
52cbd3d6d8 | ||
|
|
15ae74249b |
14
.drone.yml
14
.drone.yml
@@ -5,7 +5,7 @@ steps:
|
|||||||
image: nextcloudci/php7.3:latest
|
image: nextcloudci/php7.3:latest
|
||||||
environment:
|
environment:
|
||||||
APP_NAME: deck
|
APP_NAME: deck
|
||||||
CORE_BRANCH: master
|
CORE_BRANCH: stable20
|
||||||
DB: sqlite
|
DB: sqlite
|
||||||
commands:
|
commands:
|
||||||
# Pre-setup steps
|
# Pre-setup steps
|
||||||
@@ -20,7 +20,7 @@ steps:
|
|||||||
image: nextcloudci/php7.2:latest
|
image: nextcloudci/php7.2:latest
|
||||||
environment:
|
environment:
|
||||||
APP_NAME: deck
|
APP_NAME: deck
|
||||||
CORE_BRANCH: master
|
CORE_BRANCH: stable20
|
||||||
DB: sqlite
|
DB: sqlite
|
||||||
commands:
|
commands:
|
||||||
- composer install
|
- composer install
|
||||||
@@ -29,7 +29,7 @@ steps:
|
|||||||
image: nextcloudci/php7.3:php7.3-2
|
image: nextcloudci/php7.3:php7.3-2
|
||||||
environment:
|
environment:
|
||||||
APP_NAME: deck
|
APP_NAME: deck
|
||||||
CORE_BRANCH: master
|
CORE_BRANCH: stable20
|
||||||
DB: sqlite
|
DB: sqlite
|
||||||
commands:
|
commands:
|
||||||
- composer install
|
- composer install
|
||||||
@@ -38,7 +38,7 @@ steps:
|
|||||||
image: nextcloudci/php7.4:latest
|
image: nextcloudci/php7.4:latest
|
||||||
environment:
|
environment:
|
||||||
APP_NAME: deck
|
APP_NAME: deck
|
||||||
CORE_BRANCH: master
|
CORE_BRANCH: stable20
|
||||||
DB: sqlite
|
DB: sqlite
|
||||||
commands:
|
commands:
|
||||||
- composer install
|
- composer install
|
||||||
@@ -58,7 +58,7 @@ steps:
|
|||||||
image: nextcloudci/php7.3:latest
|
image: nextcloudci/php7.3:latest
|
||||||
environment:
|
environment:
|
||||||
APP_NAME: deck
|
APP_NAME: deck
|
||||||
CORE_BRANCH: master
|
CORE_BRANCH: stable20
|
||||||
DB: sqlite
|
DB: sqlite
|
||||||
commands:
|
commands:
|
||||||
# Pre-setup steps
|
# Pre-setup steps
|
||||||
@@ -84,7 +84,7 @@ steps:
|
|||||||
image: nextcloudci/php7.4:latest
|
image: nextcloudci/php7.4:latest
|
||||||
environment:
|
environment:
|
||||||
APP_NAME: deck
|
APP_NAME: deck
|
||||||
CORE_BRANCH: master
|
CORE_BRANCH: stable20
|
||||||
DB: sqlite
|
DB: sqlite
|
||||||
commands:
|
commands:
|
||||||
# Pre-setup steps
|
# Pre-setup steps
|
||||||
@@ -111,7 +111,7 @@ steps:
|
|||||||
image: nextcloudci/php7.3:latest
|
image: nextcloudci/php7.3:latest
|
||||||
environment:
|
environment:
|
||||||
APP_NAME: deck
|
APP_NAME: deck
|
||||||
CORE_BRANCH: master
|
CORE_BRANCH: stable20
|
||||||
DB: sqlite
|
DB: sqlite
|
||||||
commands:
|
commands:
|
||||||
# Pre-setup steps
|
# Pre-setup steps
|
||||||
|
|||||||
11
.travis.yml
11
.travis.yml
@@ -2,9 +2,13 @@ language: php
|
|||||||
services:
|
services:
|
||||||
- mysql
|
- mysql
|
||||||
php:
|
php:
|
||||||
|
- 7.2
|
||||||
- 7.3
|
- 7.3
|
||||||
|
- 7.4
|
||||||
env:
|
env:
|
||||||
- CORE_BRANCH=master DB=mysql
|
- CORE_BRANCH=stable20 DB=mysql
|
||||||
|
- CORE_BRANCH=stable19 DB=mysql
|
||||||
|
- CORE_BRANCH=stable18 DB=mysql
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
@@ -17,10 +21,13 @@ before_install:
|
|||||||
- wget https://raw.githubusercontent.com/nextcloud/travis_ci/master/before_install.sh
|
- wget https://raw.githubusercontent.com/nextcloud/travis_ci/master/before_install.sh
|
||||||
- bash ./before_install.sh deck $CORE_BRANCH $DB
|
- bash ./before_install.sh deck $CORE_BRANCH $DB
|
||||||
- cd ../server
|
- cd ../server
|
||||||
- ./occ app:enable deck
|
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- cd apps/deck
|
- cd apps/deck
|
||||||
|
- composer install --no-dev
|
||||||
|
- cd ../../
|
||||||
|
- ./occ app:enable deck
|
||||||
|
- cd apps/deck
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- composer install
|
- composer install
|
||||||
|
|||||||
21
CHANGELOG.md
21
CHANGELOG.md
@@ -1,6 +1,27 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
## 1.1.2 - 2020-10-14
|
||||||
|
|
||||||
|
### Bugfixes
|
||||||
|
|
||||||
|
* [#2436](https://github.com/nextcloud/deck/pull/2436) Move most destructive actions in drop down menus to the bottom
|
||||||
|
* [#2438](https://github.com/nextcloud/deck/pull/2438) Fix scrollable titles with Dyslexia font
|
||||||
|
* [#2439](https://github.com/nextcloud/deck/pull/2439) Only remove card padding for editable cards
|
||||||
|
* [#2442](https://github.com/nextcloud/deck/pull/2442) Move navigation toggle handling to @nextcloud/vue native one
|
||||||
|
* [#2443](https://github.com/nextcloud/deck/pull/2443) Do not open the dialog automatically upon card creation, only upon click
|
||||||
|
|
||||||
|
## 1.1.1 - 2020-10-13
|
||||||
|
|
||||||
|
### Bugfixes
|
||||||
|
|
||||||
|
* [#2364](https://github.com/nextcloud/deck/pull/2364) Use uid instead of displayname for sharee results
|
||||||
|
* [#2365](https://github.com/nextcloud/deck/pull/2365) Comments do not depend on the comments app (@jakobroehrl)
|
||||||
|
* [#2395](https://github.com/nextcloud/deck/pull/2395) Fix failure if full text search app was enabled
|
||||||
|
* [#2396](https://github.com/nextcloud/deck/pull/2396) Also exclude deleted items from calendar boards
|
||||||
|
* [#2425](https://github.com/nextcloud/deck/pull/2425) Fix filter popover styling (@Flamenco)
|
||||||
|
* [#2432](https://github.com/nextcloud/deck/pull/2432) Properly handle multiple shares in a row and refactor sharee loading
|
||||||
|
|
||||||
## 1.1.0 - 2020-10-03
|
## 1.1.0 - 2020-10-03
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
- 🚀 Get your project organized
|
- 🚀 Get your project organized
|
||||||
|
|
||||||
</description>
|
</description>
|
||||||
<version>1.1.0</version>
|
<version>1.1.2</version>
|
||||||
<licence>agpl</licence>
|
<licence>agpl</licence>
|
||||||
<author>Julius Härtl</author>
|
<author>Julius Härtl</author>
|
||||||
<namespace>Deck</namespace>
|
<namespace>Deck</namespace>
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
<database min-version="9.4">pgsql</database>
|
<database min-version="9.4">pgsql</database>
|
||||||
<database>sqlite</database>
|
<database>sqlite</database>
|
||||||
<database min-version="5.5">mysql</database>
|
<database min-version="5.5">mysql</database>
|
||||||
<nextcloud min-version="18" max-version="21" />
|
<nextcloud min-version="18" max-version="20" />
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<background-jobs>
|
<background-jobs>
|
||||||
<job>OCA\Deck\Cron\DeleteCron</job>
|
<job>OCA\Deck\Cron\DeleteCron</job>
|
||||||
|
|||||||
@@ -97,13 +97,13 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
|
|||||||
// FIXME: One moving to QBMapper we should allow filtering the boards probably by method chaining for additional where clauses
|
// FIXME: One moving to QBMapper we should allow filtering the boards probably by method chaining for additional where clauses
|
||||||
$sql = 'SELECT id, title, owner, color, archived, deleted_at, 0 as shared, last_modified FROM `*PREFIX*deck_boards` WHERE owner = ? AND last_modified > ?';
|
$sql = 'SELECT id, title, owner, color, archived, deleted_at, 0 as shared, last_modified FROM `*PREFIX*deck_boards` WHERE owner = ? AND last_modified > ?';
|
||||||
if (!$includeArchived) {
|
if (!$includeArchived) {
|
||||||
$sql .= ' AND NOT archived';
|
$sql .= ' AND NOT archived AND deleted_at = 0';
|
||||||
}
|
}
|
||||||
$sql .= ' UNION ' .
|
$sql .= ' UNION ' .
|
||||||
'SELECT boards.id, title, owner, color, archived, deleted_at, 1 as shared, last_modified FROM `*PREFIX*deck_boards` as boards ' .
|
'SELECT boards.id, title, owner, color, archived, deleted_at, 1 as shared, last_modified FROM `*PREFIX*deck_boards` as boards ' .
|
||||||
'JOIN `*PREFIX*deck_board_acl` as acl ON boards.id=acl.board_id WHERE acl.participant=? AND acl.type=? AND boards.owner != ? AND last_modified > ?';
|
'JOIN `*PREFIX*deck_board_acl` as acl ON boards.id=acl.board_id WHERE acl.participant=? AND acl.type=? AND boards.owner != ? AND last_modified > ?';
|
||||||
if (!$includeArchived) {
|
if (!$includeArchived) {
|
||||||
$sql .= ' AND NOT archived';
|
$sql .= ' AND NOT archived AND deleted_at = 0';
|
||||||
}
|
}
|
||||||
$entries = $this->findEntities($sql, [$userId, $since, $userId, Acl::PERMISSION_TYPE_USER, $userId, $since], $limit, $offset);
|
$entries = $this->findEntities($sql, [$userId, $since, $userId, Acl::PERMISSION_TYPE_USER, $userId, $since], $limit, $offset);
|
||||||
/* @var Board $entry */
|
/* @var Board $entry */
|
||||||
@@ -142,7 +142,7 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
|
|||||||
}
|
}
|
||||||
$sql .= ')';
|
$sql .= ')';
|
||||||
if (!$includeArchived) {
|
if (!$includeArchived) {
|
||||||
$sql .= ' AND NOT archived';
|
$sql .= ' AND NOT archived AND deleted_at = 0';
|
||||||
}
|
}
|
||||||
$entries = $this->findEntities($sql, array_merge([$userId, Acl::PERMISSION_TYPE_GROUP], $groups), $limit, $offset);
|
$entries = $this->findEntities($sql, array_merge([$userId, Acl::PERMISSION_TYPE_GROUP], $groups), $limit, $offset);
|
||||||
/* @var Board $entry */
|
/* @var Board $entry */
|
||||||
@@ -174,7 +174,7 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
|
|||||||
}
|
}
|
||||||
$sql .= ')';
|
$sql .= ')';
|
||||||
if (!$includeArchived) {
|
if (!$includeArchived) {
|
||||||
$sql .= ' AND NOT archived';
|
$sql .= ' AND NOT archived AND deleted_at = 0';
|
||||||
}
|
}
|
||||||
$entries = $this->findEntities($sql, array_merge([$userId, Acl::PERMISSION_TYPE_CIRCLE], $circles), $limit, $offset);
|
$entries = $this->findEntities($sql, array_merge([$userId, Acl::PERMISSION_TYPE_CIRCLE], $circles), $limit, $offset);
|
||||||
/* @var Board $entry */
|
/* @var Board $entry */
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ class FTSEvent extends Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function getArgument($key) {
|
public function getArgument($key) {
|
||||||
if ($this->hasArgument($key)) {
|
if (isset($this->arguments[$key])) {
|
||||||
return $this->arguments[$key];
|
return $this->arguments[$key];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
1555
package-lock.json
generated
1555
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
34
package.json
34
package.json
@@ -33,30 +33,30 @@
|
|||||||
"@juliushaertl/vue-richtext": "^0.3.3",
|
"@juliushaertl/vue-richtext": "^0.3.3",
|
||||||
"@nextcloud/auth": "^1.3.0",
|
"@nextcloud/auth": "^1.3.0",
|
||||||
"@nextcloud/axios": "^1.4.0",
|
"@nextcloud/axios": "^1.4.0",
|
||||||
"@nextcloud/dialogs": "^2.0.1",
|
"@nextcloud/dialogs": "^3.0.0",
|
||||||
"@nextcloud/event-bus": "^1.2.0",
|
"@nextcloud/event-bus": "^1.2.0",
|
||||||
"@nextcloud/files": "^1.1.0",
|
"@nextcloud/files": "^1.1.0",
|
||||||
"@nextcloud/initial-state": "^1.1.2",
|
"@nextcloud/initial-state": "^1.2.0",
|
||||||
"@nextcloud/l10n": "^1.4.1",
|
"@nextcloud/l10n": "^1.4.1",
|
||||||
"@nextcloud/moment": "^1.1.1",
|
"@nextcloud/moment": "^1.1.1",
|
||||||
"@nextcloud/router": "^1.2.0",
|
"@nextcloud/router": "^1.2.0",
|
||||||
"@nextcloud/vue": "^2.6.8",
|
"@nextcloud/vue": "^2.7.0",
|
||||||
"@nextcloud/vue-dashboard": "^1.0.1",
|
"@nextcloud/vue-dashboard": "^1.0.1",
|
||||||
"blueimp-md5": "^2.18.0",
|
"blueimp-md5": "^2.18.0",
|
||||||
"dompurify": "^2.1.1",
|
"dompurify": "^2.1.1",
|
||||||
"lodash": "^4.17.20",
|
"lodash": "^4.17.20",
|
||||||
"markdown-it": "^11.0.1",
|
"markdown-it": "^11.0.1",
|
||||||
"markdown-it-task-lists": "^2.1.1",
|
"markdown-it-task-lists": "^2.1.1",
|
||||||
"moment": "^2.29.0",
|
"moment": "^2.29.1",
|
||||||
"nextcloud-vue-collections": "^0.8.1",
|
"nextcloud-vue-collections": "^0.8.1",
|
||||||
"p-queue": "^6.6.1",
|
"p-queue": "^6.6.1",
|
||||||
"url-search-params-polyfill": "^8.1.0",
|
"url-search-params-polyfill": "^8.1.0",
|
||||||
"vue": "^2.6.12",
|
"vue": "^2.6.12",
|
||||||
"vue-at": "^2.5.0-beta.2",
|
"vue-at": "^2.5.0-beta.2",
|
||||||
"vue-click-outside": "^1.1.0",
|
"vue-click-outside": "^1.1.0",
|
||||||
"vue-easymde": "^1.2.2",
|
"vue-easymde": "^1.3.0",
|
||||||
"vue-infinite-loading": "^2.4.5",
|
"vue-infinite-loading": "^2.4.5",
|
||||||
"vue-router": "^3.4.4",
|
"vue-router": "^3.4.6",
|
||||||
"vue-smooth-dnd": "^0.8.1",
|
"vue-smooth-dnd": "^0.8.1",
|
||||||
"vuex": "^3.5.1",
|
"vuex": "^3.5.1",
|
||||||
"vuex-router-sync": "^5.0.0"
|
"vuex-router-sync": "^5.0.0"
|
||||||
@@ -73,44 +73,44 @@
|
|||||||
"@babel/preset-env": "^7.11.5",
|
"@babel/preset-env": "^7.11.5",
|
||||||
"@nextcloud/browserslist-config": "^1.0.0",
|
"@nextcloud/browserslist-config": "^1.0.0",
|
||||||
"@nextcloud/eslint-config": "^2.1.0",
|
"@nextcloud/eslint-config": "^2.1.0",
|
||||||
"@nextcloud/eslint-plugin": "^1.4.0",
|
"@nextcloud/eslint-plugin": "^1.5.0",
|
||||||
"@nextcloud/webpack-vue-config": "^1.4.1",
|
"@nextcloud/webpack-vue-config": "^1.4.1",
|
||||||
"@vue/test-utils": "^1.1.0",
|
"@vue/test-utils": "^1.1.0",
|
||||||
"acorn": "^8.0.1",
|
"acorn": "^8.0.4",
|
||||||
"babel-eslint": "^10.1.0",
|
"babel-eslint": "^10.1.0",
|
||||||
"babel-jest": "^26.3.0",
|
"babel-jest": "^26.5.2",
|
||||||
"babel-loader": "^8.1.0",
|
"babel-loader": "^8.1.0",
|
||||||
"css-loader": "^4.3.0",
|
"css-loader": "^4.3.0",
|
||||||
"eslint": "^6.8.0",
|
"eslint": "^6.8.0",
|
||||||
"eslint-config-standard": "^12.0.0",
|
"eslint-config-standard": "^12.0.0",
|
||||||
"eslint-friendly-formatter": "^4.0.1",
|
"eslint-friendly-formatter": "^4.0.1",
|
||||||
"eslint-loader": "^3.0.4",
|
"eslint-loader": "^3.0.4",
|
||||||
"eslint-plugin-import": "^2.22.0",
|
"eslint-plugin-import": "^2.22.1",
|
||||||
"eslint-plugin-node": "^11.1.0",
|
"eslint-plugin-node": "^11.1.0",
|
||||||
"eslint-plugin-promise": "^4.2.1",
|
"eslint-plugin-promise": "^4.2.1",
|
||||||
"eslint-plugin-standard": "^4.0.1",
|
"eslint-plugin-standard": "^4.0.1",
|
||||||
"eslint-plugin-vue": "^6.2.2",
|
"eslint-plugin-vue": "^6.2.2",
|
||||||
"file-loader": "^6.1.0",
|
"file-loader": "^6.1.1",
|
||||||
"jest": "^26.4.2",
|
"jest": "^26.5.2",
|
||||||
"jest-serializer-vue": "^2.0.2",
|
"jest-serializer-vue": "^2.0.2",
|
||||||
"minimist": "^1.2.5",
|
"minimist": "^1.2.5",
|
||||||
"node-sass": "^4.14.1",
|
"node-sass": "^4.14.1",
|
||||||
"raw-loader": "^4.0.1",
|
"raw-loader": "^4.0.2",
|
||||||
"sass-loader": "^10.0.2",
|
"sass-loader": "^10.0.3",
|
||||||
"style-loader": "^1.2.1",
|
"style-loader": "^1.3.0",
|
||||||
"stylelint": "^13.7.2",
|
"stylelint": "^13.7.2",
|
||||||
"stylelint-config-recommended": "^3.0.0",
|
"stylelint-config-recommended": "^3.0.0",
|
||||||
"stylelint-config-recommended-scss": "^4.2.0",
|
"stylelint-config-recommended-scss": "^4.2.0",
|
||||||
"stylelint-scss": "^3.18.0",
|
"stylelint-scss": "^3.18.0",
|
||||||
"stylelint-webpack-plugin": "^2.1.0",
|
"stylelint-webpack-plugin": "^2.1.0",
|
||||||
"url-loader": "^4.1.0",
|
"url-loader": "^4.1.1",
|
||||||
"vue-jest": "^3.0.7",
|
"vue-jest": "^3.0.7",
|
||||||
"vue-loader": "^15.9.3",
|
"vue-loader": "^15.9.3",
|
||||||
"vue-template-compiler": "^2.6.12",
|
"vue-template-compiler": "^2.6.12",
|
||||||
"webpack": "^4.44.2",
|
"webpack": "^4.44.2",
|
||||||
"webpack-cli": "^3.3.12",
|
"webpack-cli": "^3.3.12",
|
||||||
"webpack-dev-server": "^3.11.0",
|
"webpack-dev-server": "^3.11.0",
|
||||||
"webpack-merge": "^5.1.4"
|
"webpack-merge": "^5.2.0"
|
||||||
},
|
},
|
||||||
"jest": {
|
"jest": {
|
||||||
"moduleFileExtensions": [
|
"moduleFileExtensions": [
|
||||||
|
|||||||
39
src/App.vue
39
src/App.vue
@@ -21,11 +21,11 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div id="content" :class="{ 'nav-hidden': !navShown, 'sidebar-hidden': !sidebarRouterView }">
|
<Content id="content" app-name="deck" :class="{ 'nav-hidden': !navShown, 'sidebar-hidden': !sidebarRouterView }">
|
||||||
<AppNavigation v-show="navShown" />
|
<AppNavigation />
|
||||||
<div id="app-content">
|
<AppContent>
|
||||||
<router-view />
|
<router-view />
|
||||||
</div>
|
</AppContent>
|
||||||
|
|
||||||
<Modal v-if="cardDetailsInModal && $route.params.cardId" :title="t('deck', 'Card details')" @close="hideModal()">
|
<Modal v-if="cardDetailsInModal && $route.params.cardId" :title="t('deck', 'Card details')" @close="hideModal()">
|
||||||
<div class="modal__content modal__card">
|
<div class="modal__content modal__card">
|
||||||
@@ -34,15 +34,16 @@
|
|||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
<router-view v-show="!cardDetailsInModal || !$route.params.cardId" name="sidebar" />
|
<router-view v-show="!cardDetailsInModal || !$route.params.cardId" name="sidebar" />
|
||||||
</div>
|
</Content>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
import { mapState } from 'vuex'
|
import { mapState } from 'vuex'
|
||||||
import AppNavigation from './components/navigation/AppNavigation'
|
import AppNavigation from './components/navigation/AppNavigation'
|
||||||
import { Modal } from '@nextcloud/vue'
|
import { Modal, Content, AppContent } from '@nextcloud/vue'
|
||||||
import { BoardApi } from './services/BoardApi'
|
import { BoardApi } from './services/BoardApi'
|
||||||
|
import { emit, subscribe } from '@nextcloud/event-bus'
|
||||||
|
|
||||||
const boardApi = new BoardApi()
|
const boardApi = new BoardApi()
|
||||||
|
|
||||||
@@ -51,6 +52,8 @@ export default {
|
|||||||
components: {
|
components: {
|
||||||
AppNavigation,
|
AppNavigation,
|
||||||
Modal,
|
Modal,
|
||||||
|
Content,
|
||||||
|
AppContent,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -91,6 +94,15 @@ export default {
|
|||||||
this.$store.dispatch('loadBoards')
|
this.$store.dispatch('loadBoards')
|
||||||
this.$store.dispatch('loadSharees')
|
this.$store.dispatch('loadSharees')
|
||||||
},
|
},
|
||||||
|
mounted() {
|
||||||
|
// Set navigation to initial state and update in case it gets toggled
|
||||||
|
emit('toggle-navigation', { open: this.navShown, _initial: true })
|
||||||
|
this.$nextTick(() => {
|
||||||
|
subscribe('navigation-toggled', (navState) => {
|
||||||
|
this.$store.dispatch('toggleNav', navState.open)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
hideModal() {
|
hideModal() {
|
||||||
this.$router.push({ name: 'board' })
|
this.$router.push({ name: 'board' })
|
||||||
@@ -131,13 +143,6 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
|
|
||||||
.multiselect {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal__card {
|
.modal__card {
|
||||||
min-width: 320px;
|
min-width: 320px;
|
||||||
@@ -147,3 +152,11 @@ export default {
|
|||||||
height: 80vh;
|
height: 80vh;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
|
||||||
|
.multiselect {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -22,17 +22,17 @@
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<div id="app-navigation-toggle-custom" class="icon-menu" @click="toggleNav" />
|
<div v-if="overviewName" class="board-title">
|
||||||
<div v-if="board" class="board-title">
|
<div class="board-bullet icon-calendar-dark" />
|
||||||
|
<h2>{{ overviewName }}</h2>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="board" class="board-title">
|
||||||
<div :style="{backgroundColor: '#' + board.color}" class="board-bullet" />
|
<div :style="{backgroundColor: '#' + board.color}" class="board-bullet" />
|
||||||
<h2><a href="#">{{ board.title }}</a></h2>
|
<h2>{{ board.title }}</h2>
|
||||||
<p v-if="showArchived">
|
<p v-if="showArchived">
|
||||||
({{ t('deck', 'Archived cards') }})
|
({{ t('deck', 'Archived cards') }})
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="overviewName" class="board-title">
|
|
||||||
<h2><a href="#">{{ overviewName }}</a></h2>
|
|
||||||
</div>
|
|
||||||
<div v-if="board" class="board-actions">
|
<div v-if="board" class="board-actions">
|
||||||
<div v-if="canManage && !showArchived && !board.archived"
|
<div v-if="canManage && !showArchived && !board.archived"
|
||||||
id="stack-add"
|
id="stack-add"
|
||||||
@@ -321,6 +321,9 @@ export default {
|
|||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.controls {
|
.controls {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
padding: 3px;
|
||||||
|
height: 44px;
|
||||||
|
padding-left: 44px;
|
||||||
|
|
||||||
.board-title {
|
.board-title {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -337,7 +340,7 @@ export default {
|
|||||||
height: 20px;
|
height: 20px;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background-color: #aaa;
|
background-color: transparent;
|
||||||
margin: 12px;
|
margin: 12px;
|
||||||
margin-left: -4px;
|
margin-left: -4px;
|
||||||
}
|
}
|
||||||
@@ -395,6 +398,7 @@ export default {
|
|||||||
width: 250px;
|
width: 250px;
|
||||||
max-height: 80vh;
|
max-height: 80vh;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
padding: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.filter h3 {
|
.filter h3 {
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.board {
|
.board {
|
||||||
margin-left: $board-spacing;
|
padding-left: $board-spacing;
|
||||||
position: relative;
|
position: relative;
|
||||||
height: calc(100% - 44px);
|
height: calc(100% - 44px);
|
||||||
overflow-x: scroll;
|
overflow-x: scroll;
|
||||||
|
|||||||
@@ -7,10 +7,19 @@
|
|||||||
:options="formatedSharees"
|
:options="formatedSharees"
|
||||||
:user-select="true"
|
:user-select="true"
|
||||||
label="displayName"
|
label="displayName"
|
||||||
|
:loading="isLoading || !!isSearching"
|
||||||
|
:disabled="isLoading"
|
||||||
track-by="multiselectKey"
|
track-by="multiselectKey"
|
||||||
:internal-search="true"
|
:internal-search="true"
|
||||||
@input="clickAddAcl"
|
@input="clickAddAcl"
|
||||||
@search-change="asyncFind" />
|
@search-change="asyncFind">
|
||||||
|
<template #noOptions>
|
||||||
|
{{ isSearching ? t('deck', 'Searching for users, groups and circles ...') : t('deck', 'No participants found') }}
|
||||||
|
</template>
|
||||||
|
<template #noResult>
|
||||||
|
{{ isSearching ? t('deck', 'Searching for users, groups and circles ...') : t('deck', 'No participants found') }}
|
||||||
|
</template>
|
||||||
|
</Multiselect>
|
||||||
|
|
||||||
<ul
|
<ul
|
||||||
id="shareWithList"
|
id="shareWithList"
|
||||||
@@ -63,6 +72,7 @@ import { Avatar, Multiselect, Actions, ActionButton, ActionCheckbox } from '@nex
|
|||||||
import { CollectionList } from 'nextcloud-vue-collections'
|
import { CollectionList } from 'nextcloud-vue-collections'
|
||||||
import { mapGetters, mapState } from 'vuex'
|
import { mapGetters, mapState } from 'vuex'
|
||||||
import { getCurrentUser } from '@nextcloud/auth'
|
import { getCurrentUser } from '@nextcloud/auth'
|
||||||
|
import { showError } from '@nextcloud/dialogs'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'SharingTabSidebar',
|
name: 'SharingTabSidebar',
|
||||||
@@ -83,6 +93,7 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
|
isSearching: false,
|
||||||
addAcl: null,
|
addAcl: null,
|
||||||
addAclForAPI: null,
|
addAclForAPI: null,
|
||||||
}
|
}
|
||||||
@@ -102,7 +113,7 @@ export default {
|
|||||||
formatedSharees() {
|
formatedSharees() {
|
||||||
return this.unallocatedSharees.map(item => {
|
return this.unallocatedSharees.map(item => {
|
||||||
const sharee = {
|
const sharee = {
|
||||||
user: item.label,
|
user: item.value.shareWith,
|
||||||
displayName: item.label,
|
displayName: item.label,
|
||||||
icon: 'icon-user',
|
icon: 'icon-user',
|
||||||
multiselectKey: item.shareType + ':' + item.primaryKey,
|
multiselectKey: item.shareType + ':' + item.primaryKey,
|
||||||
@@ -137,13 +148,20 @@ export default {
|
|||||||
this.asyncFind('')
|
this.asyncFind('')
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
asyncFind(query) {
|
async asyncFind(query) {
|
||||||
this.isLoading = true
|
// manual debounce to handle async searching more easily and have more control over the loading state
|
||||||
this.$store.dispatch('loadSharees', query).then(response => {
|
const timestamp = (new Date()).getTime()
|
||||||
this.isLoading = false
|
if (!this.isSearching || timestamp > this.isSearching + 300) {
|
||||||
})
|
this.isSearching = timestamp
|
||||||
|
await this.$store.dispatch('loadSharees', query)
|
||||||
|
|
||||||
|
// only reset searching flag if the most recent search finished
|
||||||
|
if (this.isSearching === timestamp) {
|
||||||
|
this.isSearching = false
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
clickAddAcl() {
|
async clickAddAcl() {
|
||||||
this.addAclForAPI = {
|
this.addAclForAPI = {
|
||||||
type: this.addAcl.value.shareType,
|
type: this.addAcl.value.shareType,
|
||||||
participant: this.addAcl.value.shareWith,
|
participant: this.addAcl.value.shareWith,
|
||||||
@@ -151,7 +169,16 @@ export default {
|
|||||||
permissionShare: false,
|
permissionShare: false,
|
||||||
permissionManage: false,
|
permissionManage: false,
|
||||||
}
|
}
|
||||||
this.$store.dispatch('addAclToCurrentBoard', this.addAclForAPI)
|
this.isLoading = true
|
||||||
|
try {
|
||||||
|
await this.$store.dispatch('addAclToCurrentBoard', this.addAclForAPI)
|
||||||
|
} catch (e) {
|
||||||
|
const errorMessage = t('deck', 'Failed to create share with {displayName}', { displayName: this.addAcl.displayName })
|
||||||
|
console.error(errorMessage, e)
|
||||||
|
showError(errorMessage)
|
||||||
|
}
|
||||||
|
this.addAcl = null
|
||||||
|
this.isLoading = false
|
||||||
},
|
},
|
||||||
clickEditAcl(acl) {
|
clickEditAcl(acl) {
|
||||||
this.addAclForAPI = Object.assign({}, acl)
|
this.addAclForAPI = Object.assign({}, acl)
|
||||||
|
|||||||
@@ -160,6 +160,7 @@ export default {
|
|||||||
]),
|
]),
|
||||||
...mapState({
|
...mapState({
|
||||||
showArchived: state => state.showArchived,
|
showArchived: state => state.showArchived,
|
||||||
|
cardDetailsInModal: state => state.cardDetailsInModal,
|
||||||
}),
|
}),
|
||||||
cardsByStack() {
|
cardsByStack() {
|
||||||
return this.$store.getters.cardsByStack(this.stack.id).filter((card) => {
|
return this.$store.getters.cardsByStack(this.stack.id).filter((card) => {
|
||||||
@@ -245,7 +246,9 @@ export default {
|
|||||||
this.$refs.newCardInput.focus()
|
this.$refs.newCardInput.focus()
|
||||||
this.animate = false
|
this.animate = false
|
||||||
})
|
})
|
||||||
this.$router.push({ name: 'card', params: { cardId: newCard.id } })
|
if (!this.cardDetailsInModal) {
|
||||||
|
this.$router.push({ name: 'card', params: { cardId: newCard.id } })
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
showError('Could not create card: ' + e.response.data.message)
|
showError('Could not create card: ' + e.response.data.message)
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -179,7 +179,7 @@
|
|||||||
<CardSidebarTabAttachments :card="currentCard" />
|
<CardSidebarTabAttachments :card="currentCard" />
|
||||||
</AppSidebarTab>
|
</AppSidebarTab>
|
||||||
|
|
||||||
<AppSidebarTab v-if="hasComments"
|
<AppSidebarTab
|
||||||
id="comments"
|
id="comments"
|
||||||
:order="2"
|
:order="2"
|
||||||
:name="t('deck', 'Comments')"
|
:name="t('deck', 'Comments')"
|
||||||
@@ -283,7 +283,6 @@ export default {
|
|||||||
descriptionSaveTimeout: null,
|
descriptionSaveTimeout: null,
|
||||||
descriptionSaving: false,
|
descriptionSaving: false,
|
||||||
hasActivity: capabilities && capabilities.activity,
|
hasActivity: capabilities && capabilities.activity,
|
||||||
hasComments: !!OC.appswebroots['comments'],
|
|
||||||
modalShow: false,
|
modalShow: false,
|
||||||
lang: {
|
lang: {
|
||||||
days: getDayNamesMin(),
|
days: getDayNamesMin(),
|
||||||
@@ -572,14 +571,16 @@ export default {
|
|||||||
// FIXME: Obivously we should at some point not randomly reuse the sidebar component
|
// FIXME: Obivously we should at some point not randomly reuse the sidebar component
|
||||||
// since this is not oficially supported
|
// since this is not oficially supported
|
||||||
.modal__card .app-sidebar {
|
.modal__card .app-sidebar {
|
||||||
|
$modal-padding: 14px;
|
||||||
border: 0;
|
border: 0;
|
||||||
min-width: 100%;
|
min-width: calc(100% - #{$modal-padding*2});
|
||||||
position: relative;
|
position: relative;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
max-width: 100%;
|
max-width: calc(100% - #{$modal-padding*2});
|
||||||
max-height: 100%;
|
padding: 14px;
|
||||||
|
max-height: calc(100% - #{$modal-padding*2});
|
||||||
&::v-deep {
|
&::v-deep {
|
||||||
.app-sidebar-header {
|
.app-sidebar-header {
|
||||||
position: sticky;
|
position: sticky;
|
||||||
|
|||||||
@@ -144,17 +144,19 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$avatar-offset: 12px;
|
||||||
|
|
||||||
.avatar-list {
|
.avatar-list {
|
||||||
float: right;
|
float: right;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
padding-right: 8px;
|
padding-right: $avatar-offset;
|
||||||
flex-direction: row-reverse;
|
flex-direction: row-reverse;
|
||||||
.avatardiv,
|
.avatardiv,
|
||||||
/deep/ .avatardiv {
|
/deep/ .avatardiv {
|
||||||
width: 36px;
|
width: 36px;
|
||||||
height: 36px;
|
height: 36px;
|
||||||
box-sizing: content-box !important;
|
box-sizing: content-box !important;
|
||||||
margin-right: -12px;
|
margin-right: -$avatar-offset;
|
||||||
transition: margin-right 0.2s ease-in-out;
|
transition: margin-right 0.2s ease-in-out;
|
||||||
|
|
||||||
&.icon-more {
|
&.icon-more {
|
||||||
|
|||||||
@@ -121,10 +121,6 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.card:not(.card__editable) .avatars {
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fade-enter-active, .fade-leave-active {
|
.fade-enter-active, .fade-leave-active {
|
||||||
transition: opacity .125s;
|
transition: opacity .125s;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
class="card"
|
class="card"
|
||||||
@click="openCard">
|
@click="openCard">
|
||||||
<div class="card-upper">
|
<div class="card-upper">
|
||||||
<h3 v-if="isArchived || showArchived || !canEdit">
|
<h3 v-if="compactMode || isArchived || showArchived || !canEdit">
|
||||||
{{ card.title }}
|
{{ card.title }}
|
||||||
</h3>
|
</h3>
|
||||||
<h3 v-else-if="!editing">
|
<h3 v-else-if="!editing">
|
||||||
@@ -41,6 +41,7 @@
|
|||||||
<form v-if="editing"
|
<form v-if="editing"
|
||||||
v-click-outside="cancelEdit"
|
v-click-outside="cancelEdit"
|
||||||
class="dragDisabled"
|
class="dragDisabled"
|
||||||
|
@click.stop
|
||||||
@keyup.esc="cancelEdit"
|
@keyup.esc="cancelEdit"
|
||||||
@submit.prevent="finishedEdit(card)">
|
@submit.prevent="finishedEdit(card)">
|
||||||
<input v-model="copiedCard.title"
|
<input v-model="copiedCard.title"
|
||||||
@@ -59,9 +60,9 @@
|
|||||||
name="zoom"
|
name="zoom"
|
||||||
tag="ul"
|
tag="ul"
|
||||||
class="labels"
|
class="labels"
|
||||||
@click="openCard">
|
@click.stop="openCard">
|
||||||
<li v-for="label in labelsSorted" :key="label.id" :style="labelStyle(label)">
|
<li v-for="label in labelsSorted" :key="label.id" :style="labelStyle(label)">
|
||||||
<span @click="applyLabelFilter(label)">{{ label.title }}</span>
|
<span @click.stop="applyLabelFilter(label)">{{ label.title }}</span>
|
||||||
</li>
|
</li>
|
||||||
</transition-group>
|
</transition-group>
|
||||||
<div v-show="!compactMode" class="card-controls compact-item" @click="openCard">
|
<div v-show="!compactMode" class="card-controls compact-item" @click="openCard">
|
||||||
@@ -115,10 +116,10 @@ export default {
|
|||||||
]),
|
]),
|
||||||
canEdit() {
|
canEdit() {
|
||||||
if (this.currentBoard) {
|
if (this.currentBoard) {
|
||||||
return this.$store.getters.canEdit
|
return !this.currentBoard.archived && this.$store.getters.canEdit
|
||||||
}
|
}
|
||||||
const board = this.$store.getters.boards.find((item) => item.id === this.card.boardId)
|
const board = this.$store.getters.boards.find((item) => item.id === this.card.boardId)
|
||||||
return board ? board.permissions.PERMISSION_EDIT : false
|
return board ? !board.archived && board.permissions.PERMISSION_EDIT : false
|
||||||
},
|
},
|
||||||
card() {
|
card() {
|
||||||
return this.item ? this.item : this.$store.getters.cardById(this.id)
|
return this.item ? this.item : this.$store.getters.cardById(this.id)
|
||||||
@@ -171,6 +172,10 @@ export default {
|
|||||||
background-color: var(--color-main-background);
|
background-color: var(--color-main-background);
|
||||||
margin-bottom: $card-spacing;
|
margin-bottom: $card-spacing;
|
||||||
|
|
||||||
|
&::v-deep * {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
body.dark &, body.theme--dark & {
|
body.dark &, body.theme--dark & {
|
||||||
border: 2px solid var(--color-border);
|
border: 2px solid var(--color-border);
|
||||||
}
|
}
|
||||||
@@ -195,7 +200,7 @@ export default {
|
|||||||
margin: 12px $card-padding;
|
margin: 12px $card-padding;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
font-size: 100%;
|
font-size: 100%;
|
||||||
overflow-x: hidden;
|
overflow: hidden;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
padding-left: 4px;
|
padding-left: 4px;
|
||||||
span {
|
span {
|
||||||
@@ -212,11 +217,16 @@ export default {
|
|||||||
.card-controls {
|
.card-controls {
|
||||||
display: flex;
|
display: flex;
|
||||||
margin-left: $card-padding;
|
margin-left: $card-padding;
|
||||||
|
margin-right: $card-padding;
|
||||||
|
|
||||||
& > div {
|
& > div {
|
||||||
display: flex;
|
display: flex;
|
||||||
max-height: 44px;
|
max-height: 44px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&.card__editable .card-controls {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.duedate {
|
.duedate {
|
||||||
|
|||||||
@@ -30,18 +30,18 @@
|
|||||||
<ActionButton v-if="showArchived === false && isCurrentUserAssigned" icon="icon-user" @click="unassignCardFromMe()">
|
<ActionButton v-if="showArchived === false && isCurrentUserAssigned" icon="icon-user" @click="unassignCardFromMe()">
|
||||||
{{ t('deck', 'Unassign myself') }}
|
{{ t('deck', 'Unassign myself') }}
|
||||||
</ActionButton>
|
</ActionButton>
|
||||||
<ActionButton icon="icon-archive" @click="archiveUnarchiveCard()">
|
|
||||||
{{ showArchived ? t('deck', 'Unarchive card') : t('deck', 'Archive card') }}
|
|
||||||
</ActionButton>
|
|
||||||
<ActionButton v-if="showArchived === false" icon="icon-delete" @click="deleteCard()">
|
|
||||||
{{ t('deck', 'Delete card') }}
|
|
||||||
</ActionButton>
|
|
||||||
<ActionButton icon="icon-external" @click.stop="modalShow=true">
|
<ActionButton icon="icon-external" @click.stop="modalShow=true">
|
||||||
{{ t('deck', 'Move card') }}
|
{{ t('deck', 'Move card') }}
|
||||||
</ActionButton>
|
</ActionButton>
|
||||||
<ActionButton icon="icon-settings-dark" @click="openCard">
|
<ActionButton icon="icon-settings-dark" @click="openCard">
|
||||||
{{ t('deck', 'Card details') }}
|
{{ t('deck', 'Card details') }}
|
||||||
</ActionButton>
|
</ActionButton>
|
||||||
|
<ActionButton icon="icon-archive" @click="archiveUnarchiveCard()">
|
||||||
|
{{ showArchived ? t('deck', 'Unarchive card') : t('deck', 'Archive card') }}
|
||||||
|
</ActionButton>
|
||||||
|
<ActionButton v-if="showArchived === false" icon="icon-delete" @click="deleteCard()">
|
||||||
|
{{ t('deck', 'Delete card') }}
|
||||||
|
</ActionButton>
|
||||||
</Actions>
|
</Actions>
|
||||||
</div>
|
</div>
|
||||||
<Modal v-if="modalShow" :title="t('deck', 'Move card to another board')" @close="modalShow=false">
|
<Modal v-if="modalShow" :title="t('deck', 'Move card to another board')" @close="modalShow=false">
|
||||||
@@ -106,7 +106,7 @@ export default {
|
|||||||
return this.$store.getters.canEdit
|
return this.$store.getters.canEdit
|
||||||
}
|
}
|
||||||
const board = this.$store.getters.boards.find((item) => item.id === this.card.boardId)
|
const board = this.$store.getters.boards.find((item) => item.id === this.card.boardId)
|
||||||
return board.permissions.PERMISSION_EDIT
|
return !!board?.permissions?.PERMISSION_EDIT
|
||||||
},
|
},
|
||||||
isBoardAndStackChoosen() {
|
isBoardAndStackChoosen() {
|
||||||
if (this.selectedBoard === '' || this.selectedStack === '') {
|
if (this.selectedBoard === '' || this.selectedStack === '') {
|
||||||
|
|||||||
@@ -192,8 +192,4 @@ export default {
|
|||||||
color: var(--color-text-light);
|
color: var(--color-text-light);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep .app-navigation-toggle {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import comment from './comment'
|
|||||||
import trashbin from './trashbin'
|
import trashbin from './trashbin'
|
||||||
import attachment from './attachment'
|
import attachment from './attachment'
|
||||||
import overview from './overview'
|
import overview from './overview'
|
||||||
import debounce from 'lodash/debounce'
|
|
||||||
Vue.use(Vuex)
|
Vue.use(Vuex)
|
||||||
|
|
||||||
const apiClient = new BoardApi()
|
const apiClient = new BoardApi()
|
||||||
@@ -59,7 +58,7 @@ export default new Vuex.Store({
|
|||||||
state: {
|
state: {
|
||||||
config: loadState('deck', 'config', {}),
|
config: loadState('deck', 'config', {}),
|
||||||
showArchived: false,
|
showArchived: false,
|
||||||
navShown: true,
|
navShown: localStorage.getItem('deck.navShown') === 'true',
|
||||||
compactMode: localStorage.getItem('deck.compactMode') === 'true',
|
compactMode: localStorage.getItem('deck.compactMode') === 'true',
|
||||||
cardDetailsInModal: localStorage.getItem('deck.cardDetailsInModal') === 'true',
|
cardDetailsInModal: localStorage.getItem('deck.cardDetailsInModal') === 'true',
|
||||||
sidebarShown: false,
|
sidebarShown: false,
|
||||||
@@ -204,8 +203,9 @@ export default new Vuex.Store({
|
|||||||
return board.id !== b.id
|
return board.id !== b.id
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
toggleNav(state) {
|
toggleNav(state, navState) {
|
||||||
state.navShown = !state.navShown
|
state.navShown = navState
|
||||||
|
localStorage.setItem('deck.navShown', navState)
|
||||||
},
|
},
|
||||||
toggleSidebar(state) {
|
toggleSidebar(state) {
|
||||||
state.sidebarShown = !state.sidebarShown
|
state.sidebarShown = !state.sidebarShown
|
||||||
@@ -392,7 +392,7 @@ export default new Vuex.Store({
|
|||||||
const boards = await apiClient.loadBoards()
|
const boards = await apiClient.loadBoards()
|
||||||
commit('setBoards', boards)
|
commit('setBoards', boards)
|
||||||
},
|
},
|
||||||
loadSharees: debounce(function({ commit }, query) {
|
async loadSharees({ commit }, query) {
|
||||||
const params = new URLSearchParams()
|
const params = new URLSearchParams()
|
||||||
if (typeof query === 'undefined') {
|
if (typeof query === 'undefined') {
|
||||||
return
|
return
|
||||||
@@ -402,16 +402,15 @@ export default new Vuex.Store({
|
|||||||
params.append('perPage', 20)
|
params.append('perPage', 20)
|
||||||
params.append('itemType', [0, 1, 7])
|
params.append('itemType', [0, 1, 7])
|
||||||
|
|
||||||
axios.get(generateOcsUrl('apps/files_sharing/api/v1') + 'sharees', { params }).then((response) => {
|
const response = await axios.get(generateOcsUrl('apps/files_sharing/api/v1') + 'sharees', { params })
|
||||||
commit('setSharees', response.data.ocs.data)
|
commit('setSharees', response.data.ocs.data)
|
||||||
})
|
},
|
||||||
}, 250),
|
|
||||||
|
|
||||||
setBoardFilter({ commmit }, filter) {
|
setBoardFilter({ commmit }, filter) {
|
||||||
commmit('setBoardFilter', filter)
|
commmit('setBoardFilter', filter)
|
||||||
},
|
},
|
||||||
toggleNav({ commit }) {
|
toggleNav({ commit }, navState) {
|
||||||
commit('toggleNav')
|
commit('toggleNav', navState)
|
||||||
},
|
},
|
||||||
toggleSidebar({ commit }) {
|
toggleSidebar({ commit }) {
|
||||||
commit('toggleSidebar')
|
commit('toggleSidebar')
|
||||||
@@ -454,13 +453,11 @@ export default new Vuex.Store({
|
|||||||
},
|
},
|
||||||
|
|
||||||
// acl actions
|
// acl actions
|
||||||
addAclToCurrentBoard({ dispatch, commit }, newAcl) {
|
async addAclToCurrentBoard({ dispatch, commit }, newAcl) {
|
||||||
newAcl.boardId = this.state.currentBoard.id
|
newAcl.boardId = this.state.currentBoard.id
|
||||||
apiClient.addAcl(newAcl)
|
const result = await apiClient.addAcl(newAcl)
|
||||||
.then((returnAcl) => {
|
commit('addAclToCurrentBoard', result)
|
||||||
commit('addAclToCurrentBoard', returnAcl)
|
dispatch('refreshBoard', newAcl.boardId)
|
||||||
dispatch('refreshBoard', newAcl.boardId)
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
updateAclFromCurrentBoard({ commit }, acl) {
|
updateAclFromCurrentBoard({ commit }, acl) {
|
||||||
acl.boardId = this.state.currentBoard.id
|
acl.boardId = this.state.currentBoard.id
|
||||||
|
|||||||
Reference in New Issue
Block a user