implement card reference widget, fix DeckIcon.vue

bring back eslint and stylelint on compilation, fix almost all warnings, ignore some

Signed-off-by: Julien Veyssier <eneiluj@posteo.net>
This commit is contained in:
Julien Veyssier
2022-09-06 18:03:44 +02:00
parent 89068641ee
commit 3c83320c20
54 changed files with 1029 additions and 200 deletions

View File

@@ -8,6 +8,7 @@ module.exports = {
'jsdoc/require-param-type': ['off'],
'jsdoc/check-param-names': ['off'],
'jsdoc/no-undefined-types': ['off'],
'jsdoc/require-property-description' : ['off']
'jsdoc/require-property-description': ['off'],
'import/no-named-as-default-member': ['off']
},
}

View File

@@ -36,7 +36,6 @@ use OCA\Deck\Db\AclMapper;
use OCA\Deck\Db\AssignmentMapper;
use OCA\Deck\Db\BoardMapper;
use OCA\Deck\Db\CardMapper;
use OCA\Deck\Db\User;
use OCA\Deck\Event\AclCreatedEvent;
use OCA\Deck\Event\AclDeletedEvent;
use OCA\Deck\Event\AclUpdatedEvent;
@@ -48,6 +47,7 @@ use OCA\Deck\Listeners\FullTextSearchEventListener;
use OCA\Deck\Middleware\DefaultBoardMiddleware;
use OCA\Deck\Middleware\ExceptionMiddleware;
use OCA\Deck\Notification\Notifier;
use OCA\Deck\Reference\CardReferenceProvider;
use OCA\Deck\Search\CardCommentProvider;
use OCA\Deck\Search\DeckProvider;
use OCA\Deck\Service\PermissionService;
@@ -58,6 +58,7 @@ use OCP\AppFramework\Bootstrap\IBootContext;
use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\AppFramework\Bootstrap\IRegistrationContext;
use OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent;
use OCP\Collaboration\Reference\RenderReferenceEvent;
use OCP\Collaboration\Resources\IProviderManager;
use OCP\Comments\CommentsEntityEvent;
use OCP\Comments\ICommentsManager;
@@ -83,6 +84,14 @@ class Application extends App implements IBootstrap {
public function __construct(array $urlParams = []) {
parent::__construct(self::APP_ID, $urlParams);
// TODO move this back to ::register after fixing the autoload issue
// (and use a listener class)
$container = $this->getContainer();
$eventDispatcher = $container->get(IEventDispatcher::class);
$eventDispatcher->addListener(RenderReferenceEvent::class, function () {
Util::addScript(self::APP_ID, self::APP_ID . '-card-reference');
});
}
public function boot(IBootContext $context): void {
@@ -121,6 +130,10 @@ class Application extends App implements IBootstrap {
$context->registerSearchProvider(CardCommentProvider::class);
$context->registerDashboardWidget(DeckWidget::class);
// reference widget
$context->registerReferenceProvider(CardReferenceProvider::class);
// $context->registerEventListener(RenderReferenceEvent::class, CardReferenceListener::class);
$context->registerEventListener(BeforeTemplateRenderedEvent::class, BeforeTemplateRenderedListener::class);
// Event listening for full text search indexing

View File

@@ -0,0 +1,113 @@
<?php
/**
* @copyright Copyright (c) 2022 Julien Veyssier <eneiluj@posteo.net>
*
* @author Julien Veyssier <eneiluj@posteo.net>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace OCA\Deck\Reference;
use OC\Collaboration\Reference\Reference;
use OCA\Deck\AppInfo\Application;
use OCA\Deck\Service\BoardService;
use OCA\Deck\Service\CardService;
use OCA\Deck\Service\StackService;
use OCP\Collaboration\Reference\IReference;
use OCP\Collaboration\Reference\IReferenceProvider;
use OCP\IURLGenerator;
class CardReferenceProvider implements IReferenceProvider {
private CardService $cardService;
private IURLGenerator $urlGenerator;
private BoardService $boardService;
private StackService $stackService;
public function __construct(CardService $cardService,
BoardService $boardService,
StackService $stackService,
IURLGenerator $urlGenerator,
?string $userId) {
$this->cardService = $cardService;
$this->urlGenerator = $urlGenerator;
$this->boardService = $boardService;
$this->stackService = $stackService;
}
/**
* @inheritDoc
*/
public function matchReference(string $referenceText): bool {
$start = $this->urlGenerator->getAbsoluteURL('/apps/' . Application::APP_ID);
$startIndex = $this->urlGenerator->getAbsoluteURL('/index.php/apps/' . Application::APP_ID);
// link example: https://nextcloud.local/index.php/apps/deck/#/board/2/card/11
$noIndexMatch = preg_match('/^' . preg_quote($start, '/') . '\/#\/board\/[0-9]+\/card\/[0-9]+$/', $referenceText) === 1;
$indexMatch = preg_match('/^' . preg_quote($startIndex, '/') . '\/#\/board\/[0-9]+\/card\/[0-9]+$/', $referenceText) === 1;
return $noIndexMatch || $indexMatch;
}
/**
* @inheritDoc
*/
public function resolveReference(string $referenceText): ?IReference {
if ($this->matchReference($referenceText)) {
$cardIds = $this->getBoardCardId($referenceText);
if ($cardIds !== null) {
[$boardId, $cardId] = $cardIds;
$card = $this->cardService->find((int) $cardId);
$board = $this->boardService->find((int) $boardId);
$stack = $this->stackService->find((int) $card->jsonSerialize()['stackId']);
$reference = new Reference($referenceText);
$reference->setRichObject(Application::APP_ID . '-card', [
'card' => $card,
'board' => $board,
'stack' => $stack,
]);
return $reference;
}
}
return null;
}
private function getBoardCardId(string $url): ?array {
$start = $this->urlGenerator->getAbsoluteURL('/apps/' . Application::APP_ID);
$startIndex = $this->urlGenerator->getAbsoluteURL('/index.php/apps/' . Application::APP_ID);
preg_match('/^' . preg_quote($start, '/') . '\/#\/board\/([0-9]+)\/card\/([0-9]+)$/', $url, $matches);
if ($matches && count($matches) > 2) {
return [$matches[1], $matches[2]];
}
preg_match('/^' . preg_quote($startIndex, '/') . '\/#\/board\/([0-9]+)\/card\/([0-9]+)$/', $url, $matches2);
if ($matches2 && count($matches2) > 2) {
return [$matches2[1], $matches2[2]];
}
return null;
}
public function getCachePrefix(string $referenceId): string {
return $referenceId;
}
public function getCacheKey(string $referenceId): ?string {
return null;
}
}

502
package-lock.json generated
View File

@@ -23,6 +23,7 @@
"@nextcloud/router": "^2.0.0",
"@nextcloud/vue": "^6.0.0-beta.4",
"@nextcloud/vue-dashboard": "^2.0.1",
"@nextcloud/vue-richtext": "^2.0.0",
"blueimp-md5": "^2.19.0",
"dompurify": "^2.4.0",
"lodash": "^4.17.21",
@@ -53,8 +54,10 @@
"@relative-ci/agent": "^4.1.0",
"@vue/test-utils": "^1.3.0",
"cypress": "^10.7.0",
"eslint-webpack-plugin": "^3.2.0",
"jest": "^29.0.1",
"jest-serializer-vue": "^2.0.2",
"stylelint-webpack-plugin": "^3.3.0",
"vue-jest": "^3.0.7",
"vue-template-compiler": "^2.7.9"
},
@@ -3497,6 +3500,24 @@
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
},
"node_modules/@nextcloud/vue-richtext": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@nextcloud/vue-richtext/-/vue-richtext-2.0.0.tgz",
"integrity": "sha512-Z/AbweVmIB8shWZVLI0kUPrJnkCBlU5xIkkfv+RPFepLY7eZ+ttm5HRhLGqgFyXFNf4RIM7yGt/l6K35XcEX2A==",
"dependencies": {
"@nextcloud/axios": "^2.0.0",
"@nextcloud/router": "^2.0.0",
"clone": "^2.1.2",
"vue": "^2.7.8"
},
"engines": {
"node": ">=14.0.0",
"npm": ">=7.0.0"
},
"peerDependencies": {
"vue": "^2.7.8"
}
},
"node_modules/@nextcloud/vue/node_modules/ansi-regex": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
@@ -3600,7 +3621,6 @@
"version": "2.1.4",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@nodelib/fs.stat": "2.0.4",
"run-parallel": "^1.1.9"
@@ -3613,7 +3633,6 @@
"version": "2.0.4",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">= 8"
}
@@ -3622,7 +3641,6 @@
"version": "1.2.6",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@nodelib/fs.scandir": "2.1.4",
"fastq": "^1.6.0"
@@ -3798,10 +3816,9 @@
}
},
"node_modules/@types/eslint": {
"version": "7.28.2",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.28.2.tgz",
"integrity": "sha512-KubbADPkfoU75KgKeKLsFHXnU4ipH7wYg0TRT33NK3N3yiu7jlFAAoygIWBV+KbuHx/G+AvuGX6DllnK35gfJA==",
"peer": true,
"version": "8.4.6",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.6.tgz",
"integrity": "sha512-/fqTbjxyFUaYNO7VcW5g+4npmqVACz1bB7RTHYuLj+PRjw9hrCwrUXVQFpChUS0JsyEFvMZ7U/PfmvWgxJhI9g==",
"dependencies": {
"@types/estree": "*",
"@types/json-schema": "*"
@@ -4463,7 +4480,6 @@
"resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz",
"integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==",
"dev": true,
"peer": true,
"dependencies": {
"ajv": "^8.0.0"
},
@@ -4481,7 +4497,6 @@
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz",
"integrity": "sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==",
"dev": true,
"peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.1",
"json-schema-traverse": "^1.0.0",
@@ -4497,8 +4512,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
"dev": true,
"peer": true
"dev": true
},
"node_modules/ajv-keywords": {
"version": "3.5.2",
@@ -4636,7 +4650,6 @@
"version": "2.1.0",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=8"
}
@@ -7438,7 +7451,6 @@
"version": "3.0.1",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"path-type": "^4.0.0"
},
@@ -7450,7 +7462,6 @@
"version": "4.0.0",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=8"
}
@@ -8450,6 +8461,121 @@
"node": ">=10"
}
},
"node_modules/eslint-webpack-plugin": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-3.2.0.tgz",
"integrity": "sha512-avrKcGncpPbPSUHX6B3stNGzkKFto3eL+DKM4+VyMrVnhPc3vRczVlCq3uhuFOdRvDHTVXuzwk1ZKUrqDQHQ9w==",
"dev": true,
"dependencies": {
"@types/eslint": "^7.29.0 || ^8.4.1",
"jest-worker": "^28.0.2",
"micromatch": "^4.0.5",
"normalize-path": "^3.0.0",
"schema-utils": "^4.0.0"
},
"engines": {
"node": ">= 12.13.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"peerDependencies": {
"eslint": "^7.0.0 || ^8.0.0",
"webpack": "^5.0.0"
}
},
"node_modules/eslint-webpack-plugin/node_modules/ajv": {
"version": "8.11.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz",
"integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==",
"dev": true,
"dependencies": {
"fast-deep-equal": "^3.1.1",
"json-schema-traverse": "^1.0.0",
"require-from-string": "^2.0.2",
"uri-js": "^4.2.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/eslint-webpack-plugin/node_modules/ajv-keywords": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
"integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
"dev": true,
"dependencies": {
"fast-deep-equal": "^3.1.3"
},
"peerDependencies": {
"ajv": "^8.8.2"
}
},
"node_modules/eslint-webpack-plugin/node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
"engines": {
"node": ">=8"
}
},
"node_modules/eslint-webpack-plugin/node_modules/jest-worker": {
"version": "28.1.3",
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz",
"integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==",
"dev": true,
"dependencies": {
"@types/node": "*",
"merge-stream": "^2.0.0",
"supports-color": "^8.0.0"
},
"engines": {
"node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
"node_modules/eslint-webpack-plugin/node_modules/json-schema-traverse": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
"dev": true
},
"node_modules/eslint-webpack-plugin/node_modules/schema-utils": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz",
"integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==",
"dev": true,
"dependencies": {
"@types/json-schema": "^7.0.9",
"ajv": "^8.8.0",
"ajv-formats": "^2.1.1",
"ajv-keywords": "^5.0.0"
},
"engines": {
"node": ">= 12.13.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
}
},
"node_modules/eslint-webpack-plugin/node_modules/supports-color": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
"integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
"dev": true,
"dependencies": {
"has-flag": "^4.0.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/supports-color?sponsor=1"
}
},
"node_modules/eslint/node_modules/ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
@@ -9068,7 +9194,6 @@
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz",
"integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==",
"dev": true,
"peer": true,
"dependencies": {
"@nodelib/fs.stat": "^2.0.2",
"@nodelib/fs.walk": "^1.2.3",
@@ -9105,7 +9230,6 @@
"version": "1.11.0",
"dev": true,
"license": "ISC",
"peer": true,
"dependencies": {
"reusify": "^1.0.4"
}
@@ -9625,7 +9749,6 @@
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"dev": true,
"peer": true,
"dependencies": {
"is-glob": "^4.0.1"
},
@@ -9711,7 +9834,6 @@
"resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
"integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
"dev": true,
"peer": true,
"dependencies": {
"array-union": "^2.1.0",
"dir-glob": "^3.0.1",
@@ -10223,7 +10345,6 @@
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
"integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
"dev": true,
"peer": true,
"engines": {
"node": ">= 4"
}
@@ -10533,7 +10654,6 @@
"version": "2.1.1",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=0.10.0"
}
@@ -10590,7 +10710,6 @@
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
"dev": true,
"peer": true,
"dependencies": {
"is-extglob": "^2.1.1"
},
@@ -13815,7 +13934,6 @@
"version": "1.4.1",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">= 8"
}
@@ -15452,8 +15570,7 @@
"url": "https://feross.org/support"
}
],
"license": "MIT",
"peer": true
"license": "MIT"
},
"node_modules/quick-lru": {
"version": "4.0.1",
@@ -15866,7 +15983,6 @@
"version": "2.0.2",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=0.10.0"
}
@@ -15964,7 +16080,6 @@
"version": "1.0.4",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"iojs": ">=1.0.0",
"node": ">=0.10.0"
@@ -16020,7 +16135,6 @@
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"queue-microtask": "^1.2.2"
}
@@ -17112,6 +17226,121 @@
"stylelint": "^14.5.1"
}
},
"node_modules/stylelint-webpack-plugin": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/stylelint-webpack-plugin/-/stylelint-webpack-plugin-3.3.0.tgz",
"integrity": "sha512-F53bapIZ9zI16ero8IWm6TrUE6SSibZBphJE9b5rR2FxtvmGmm1YmS+a5xjQzn63+cv71GVSCu4byX66fBLpEw==",
"dev": true,
"dependencies": {
"globby": "^11.1.0",
"jest-worker": "^28.1.0",
"micromatch": "^4.0.5",
"normalize-path": "^3.0.0",
"schema-utils": "^4.0.0"
},
"engines": {
"node": ">= 12.13.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"peerDependencies": {
"stylelint": "^13.0.0 || ^14.0.0",
"webpack": "^5.0.0"
}
},
"node_modules/stylelint-webpack-plugin/node_modules/ajv": {
"version": "8.11.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz",
"integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==",
"dev": true,
"dependencies": {
"fast-deep-equal": "^3.1.1",
"json-schema-traverse": "^1.0.0",
"require-from-string": "^2.0.2",
"uri-js": "^4.2.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/stylelint-webpack-plugin/node_modules/ajv-keywords": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
"integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
"dev": true,
"dependencies": {
"fast-deep-equal": "^3.1.3"
},
"peerDependencies": {
"ajv": "^8.8.2"
}
},
"node_modules/stylelint-webpack-plugin/node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
"engines": {
"node": ">=8"
}
},
"node_modules/stylelint-webpack-plugin/node_modules/jest-worker": {
"version": "28.1.3",
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz",
"integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==",
"dev": true,
"dependencies": {
"@types/node": "*",
"merge-stream": "^2.0.0",
"supports-color": "^8.0.0"
},
"engines": {
"node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
"node_modules/stylelint-webpack-plugin/node_modules/json-schema-traverse": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
"dev": true
},
"node_modules/stylelint-webpack-plugin/node_modules/schema-utils": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz",
"integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==",
"dev": true,
"dependencies": {
"@types/json-schema": "^7.0.9",
"ajv": "^8.8.0",
"ajv-formats": "^2.1.1",
"ajv-keywords": "^5.0.0"
},
"engines": {
"node": ">= 12.13.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
}
},
"node_modules/stylelint-webpack-plugin/node_modules/supports-color": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
"integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
"dev": true,
"dependencies": {
"has-flag": "^4.0.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/supports-color?sponsor=1"
}
},
"node_modules/stylelint/node_modules/@csstools/selector-specificity": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz",
@@ -21677,6 +21906,17 @@
}
}
},
"@nextcloud/vue-richtext": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@nextcloud/vue-richtext/-/vue-richtext-2.0.0.tgz",
"integrity": "sha512-Z/AbweVmIB8shWZVLI0kUPrJnkCBlU5xIkkfv+RPFepLY7eZ+ttm5HRhLGqgFyXFNf4RIM7yGt/l6K35XcEX2A==",
"requires": {
"@nextcloud/axios": "^2.0.0",
"@nextcloud/router": "^2.0.0",
"clone": "^2.1.2",
"vue": "^2.7.8"
}
},
"@nextcloud/webpack-vue-config": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/@nextcloud/webpack-vue-config/-/webpack-vue-config-5.3.0.tgz",
@@ -21687,7 +21927,6 @@
"@nodelib/fs.scandir": {
"version": "2.1.4",
"dev": true,
"peer": true,
"requires": {
"@nodelib/fs.stat": "2.0.4",
"run-parallel": "^1.1.9"
@@ -21695,13 +21934,11 @@
},
"@nodelib/fs.stat": {
"version": "2.0.4",
"dev": true,
"peer": true
"dev": true
},
"@nodelib/fs.walk": {
"version": "1.2.6",
"dev": true,
"peer": true,
"requires": {
"@nodelib/fs.scandir": "2.1.4",
"fastq": "^1.6.0"
@@ -21857,10 +22094,9 @@
}
},
"@types/eslint": {
"version": "7.28.2",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.28.2.tgz",
"integrity": "sha512-KubbADPkfoU75KgKeKLsFHXnU4ipH7wYg0TRT33NK3N3yiu7jlFAAoygIWBV+KbuHx/G+AvuGX6DllnK35gfJA==",
"peer": true,
"version": "8.4.6",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.6.tgz",
"integrity": "sha512-/fqTbjxyFUaYNO7VcW5g+4npmqVACz1bB7RTHYuLj+PRjw9hrCwrUXVQFpChUS0JsyEFvMZ7U/PfmvWgxJhI9g==",
"requires": {
"@types/estree": "*",
"@types/json-schema": "*"
@@ -22455,7 +22691,6 @@
"resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz",
"integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==",
"dev": true,
"peer": true,
"requires": {
"ajv": "^8.0.0"
},
@@ -22465,7 +22700,6 @@
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz",
"integrity": "sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==",
"dev": true,
"peer": true,
"requires": {
"fast-deep-equal": "^3.1.1",
"json-schema-traverse": "^1.0.0",
@@ -22477,8 +22711,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
"dev": true,
"peer": true
"dev": true
}
}
},
@@ -22567,8 +22800,7 @@
},
"array-union": {
"version": "2.1.0",
"dev": true,
"peer": true
"dev": true
},
"array.prototype.flat": {
"version": "1.3.0",
@@ -24732,15 +24964,13 @@
"dir-glob": {
"version": "3.0.1",
"dev": true,
"peer": true,
"requires": {
"path-type": "^4.0.0"
},
"dependencies": {
"path-type": {
"version": "4.0.0",
"dev": true,
"peer": true
"dev": true
}
}
},
@@ -25681,6 +25911,86 @@
"dev": true,
"peer": true
},
"eslint-webpack-plugin": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-3.2.0.tgz",
"integrity": "sha512-avrKcGncpPbPSUHX6B3stNGzkKFto3eL+DKM4+VyMrVnhPc3vRczVlCq3uhuFOdRvDHTVXuzwk1ZKUrqDQHQ9w==",
"dev": true,
"requires": {
"@types/eslint": "^7.29.0 || ^8.4.1",
"jest-worker": "^28.0.2",
"micromatch": "^4.0.5",
"normalize-path": "^3.0.0",
"schema-utils": "^4.0.0"
},
"dependencies": {
"ajv": {
"version": "8.11.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz",
"integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==",
"dev": true,
"requires": {
"fast-deep-equal": "^3.1.1",
"json-schema-traverse": "^1.0.0",
"require-from-string": "^2.0.2",
"uri-js": "^4.2.2"
}
},
"ajv-keywords": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
"integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
"dev": true,
"requires": {
"fast-deep-equal": "^3.1.3"
}
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
"jest-worker": {
"version": "28.1.3",
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz",
"integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==",
"dev": true,
"requires": {
"@types/node": "*",
"merge-stream": "^2.0.0",
"supports-color": "^8.0.0"
}
},
"json-schema-traverse": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
"dev": true
},
"schema-utils": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz",
"integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.9",
"ajv": "^8.8.0",
"ajv-formats": "^2.1.1",
"ajv-keywords": "^5.0.0"
}
},
"supports-color": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
"integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
"dev": true,
"requires": {
"has-flag": "^4.0.0"
}
}
}
},
"espree": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz",
@@ -25947,7 +26257,6 @@
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz",
"integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==",
"dev": true,
"peer": true,
"requires": {
"@nodelib/fs.stat": "^2.0.2",
"@nodelib/fs.walk": "^1.2.3",
@@ -25976,7 +26285,6 @@
"fastq": {
"version": "1.11.0",
"dev": true,
"peer": true,
"requires": {
"reusify": "^1.0.4"
}
@@ -26358,7 +26666,6 @@
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"dev": true,
"peer": true,
"requires": {
"is-glob": "^4.0.1"
}
@@ -26420,7 +26727,6 @@
"resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
"integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
"dev": true,
"peer": true,
"requires": {
"array-union": "^2.1.0",
"dir-glob": "^3.0.1",
@@ -26787,8 +27093,7 @@
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
"integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
"dev": true,
"peer": true
"dev": true
},
"immutable": {
"version": "4.1.0",
@@ -26990,8 +27295,7 @@
},
"is-extglob": {
"version": "2.1.1",
"dev": true,
"peer": true
"dev": true
},
"is-finite": {
"version": "1.1.0",
@@ -27027,7 +27331,6 @@
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
"dev": true,
"peer": true,
"requires": {
"is-extglob": "^2.1.1"
}
@@ -29365,8 +29668,7 @@
},
"merge2": {
"version": "1.4.1",
"dev": true,
"peer": true
"dev": true
},
"methods": {
"version": "1.1.2",
@@ -30559,8 +30861,7 @@
},
"queue-microtask": {
"version": "1.2.3",
"dev": true,
"peer": true
"dev": true
},
"quick-lru": {
"version": "4.0.1",
@@ -30869,8 +31170,7 @@
},
"require-from-string": {
"version": "2.0.2",
"dev": true,
"peer": true
"dev": true
},
"requireindex": {
"version": "1.2.0",
@@ -30935,8 +31235,7 @@
},
"reusify": {
"version": "1.0.4",
"dev": true,
"peer": true
"dev": true
},
"rfdc": {
"version": "1.3.0",
@@ -30967,7 +31266,6 @@
"run-parallel": {
"version": "1.2.0",
"dev": true,
"peer": true,
"requires": {
"queue-microtask": "^1.2.2"
}
@@ -31870,6 +32168,86 @@
"postcss-value-parser": "^4.1.0"
}
},
"stylelint-webpack-plugin": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/stylelint-webpack-plugin/-/stylelint-webpack-plugin-3.3.0.tgz",
"integrity": "sha512-F53bapIZ9zI16ero8IWm6TrUE6SSibZBphJE9b5rR2FxtvmGmm1YmS+a5xjQzn63+cv71GVSCu4byX66fBLpEw==",
"dev": true,
"requires": {
"globby": "^11.1.0",
"jest-worker": "^28.1.0",
"micromatch": "^4.0.5",
"normalize-path": "^3.0.0",
"schema-utils": "^4.0.0"
},
"dependencies": {
"ajv": {
"version": "8.11.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz",
"integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==",
"dev": true,
"requires": {
"fast-deep-equal": "^3.1.1",
"json-schema-traverse": "^1.0.0",
"require-from-string": "^2.0.2",
"uri-js": "^4.2.2"
}
},
"ajv-keywords": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
"integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
"dev": true,
"requires": {
"fast-deep-equal": "^3.1.3"
}
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
"jest-worker": {
"version": "28.1.3",
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz",
"integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==",
"dev": true,
"requires": {
"@types/node": "*",
"merge-stream": "^2.0.0",
"supports-color": "^8.0.0"
}
},
"json-schema-traverse": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
"dev": true
},
"schema-utils": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz",
"integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.9",
"ajv": "^8.8.0",
"ajv-formats": "^2.1.1",
"ajv-keywords": "^5.0.0"
}
},
"supports-color": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
"integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
"dev": true,
"requires": {
"has-flag": "^4.0.0"
}
}
}
},
"superstruct": {
"version": "0.16.0",
"resolved": "https://registry.npmjs.org/superstruct/-/superstruct-0.16.0.tgz",

View File

@@ -42,6 +42,7 @@
"@nextcloud/router": "^2.0.0",
"@nextcloud/vue": "^6.0.0-beta.4",
"@nextcloud/vue-dashboard": "^2.0.1",
"@nextcloud/vue-richtext": "^2.0.0",
"blueimp-md5": "^2.19.0",
"dompurify": "^2.4.0",
"lodash": "^4.17.21",
@@ -79,8 +80,10 @@
"@relative-ci/agent": "^4.1.0",
"@vue/test-utils": "^1.3.0",
"cypress": "^10.7.0",
"eslint-webpack-plugin": "^3.2.0",
"jest": "^29.0.1",
"jest-serializer-vue": "^2.0.2",
"stylelint-webpack-plugin": "^3.3.0",
"vue-jest": "^3.0.7",
"vue-template-compiler": "^2.7.9"
},

View File

@@ -43,9 +43,9 @@
<script>
import { mapState } from 'vuex'
import AppNavigation from './components/navigation/AppNavigation'
import AppNavigation from './components/navigation/AppNavigation.vue'
import { NcModal, NcContent, NcAppContent } from '@nextcloud/vue'
import { BoardApi } from './services/BoardApi'
import { BoardApi } from './services/BoardApi.js'
import { emit, subscribe } from '@nextcloud/event-bus'
const boardApi = new BoardApi()

View File

@@ -92,11 +92,11 @@
<script>
import { generateUrl } from '@nextcloud/router'
import NcModal from '@nextcloud/vue/dist/Components/NcModal'
import NcMultiselect from '@nextcloud/vue/dist/Components/NcMultiselect'
import NcEmptyContent from '@nextcloud/vue/dist/Components/NcEmptyContent'
import NcModal from '@nextcloud/vue/dist/Components/NcModal.js'
import NcMultiselect from '@nextcloud/vue/dist/Components/NcMultiselect.js'
import NcEmptyContent from '@nextcloud/vue/dist/Components/NcEmptyContent.js'
import axios from '@nextcloud/axios'
import { CardApi } from './services/CardApi'
import { CardApi } from './services/CardApi.js'
const cardApi = new CardApi()

View File

@@ -39,7 +39,7 @@ import RichText from '@juliushaertl/vue-richtext'
import { NcUserBubble } from '@nextcloud/vue'
import moment from '@nextcloud/moment'
import DOMPurify from 'dompurify'
import relativeDate from '../mixins/relativeDate'
import relativeDate from '../mixins/relativeDate.js'
const InternalLink = {
name: 'InternalLink',

View File

@@ -37,7 +37,7 @@
<script>
import axios from '@nextcloud/axios'
import { generateOcsUrl } from '@nextcloud/router'
import ActivityEntry from './ActivityEntry'
import ActivityEntry from './ActivityEntry.vue'
import InfiniteLoading from 'vue-infinite-loading'
const ACTIVITY_FETCH_LIMIT = 50

View File

@@ -63,7 +63,7 @@
<script>
import { NcModal } from '@nextcloud/vue'
import attachmentUpload from '../mixins/attachmentUpload'
import attachmentUpload from '../mixins/attachmentUpload.js'
import { loadState } from '@nextcloud/initial-state'
let maxUploadSizeState

View File

@@ -217,13 +217,13 @@
<script>
import { mapState, mapGetters } from 'vuex'
import { NcActions, NcActionButton, NcAvatar, NcButton, NcPopover } from '@nextcloud/vue'
import labelStyle from '../mixins/labelStyle'
import CardCreateDialog from '../CardCreateDialog'
import ArchiveIcon from 'vue-material-design-icons/Archive'
import FilterIcon from 'vue-material-design-icons/Filter'
import FilterOffIcon from 'vue-material-design-icons/FilterOff'
import ArrowCollapseVerticalIcon from 'vue-material-design-icons/ArrowCollapseVertical'
import ArrowExpandVerticalIcon from 'vue-material-design-icons/ArrowExpandVertical'
import labelStyle from '../mixins/labelStyle.js'
import CardCreateDialog from '../CardCreateDialog.vue'
import ArchiveIcon from 'vue-material-design-icons/Archive.vue'
import FilterIcon from 'vue-material-design-icons/Filter.vue'
import FilterOffIcon from 'vue-material-design-icons/FilterOff.vue'
import ArrowCollapseVerticalIcon from 'vue-material-design-icons/ArrowCollapseVertical.vue'
import ArrowExpandVerticalIcon from 'vue-material-design-icons/ArrowExpandVertical.vue'
export default {
name: 'Controls',

View File

@@ -73,11 +73,11 @@
import { Container, Draggable } from 'vue-smooth-dnd'
import { mapState, mapGetters } from 'vuex'
import Controls from '../Controls'
import Stack from './Stack'
import Controls from '../Controls.vue'
import Stack from './Stack.vue'
import { NcEmptyContent } from '@nextcloud/vue'
import GlobalSearchResults from '../search/GlobalSearchResults'
import { showError } from '../../helpers/errors'
import GlobalSearchResults from '../search/GlobalSearchResults.vue'
import { showError } from '../../helpers/errors.js'
export default {
name: 'Board',

View File

@@ -59,10 +59,10 @@
<script>
import { mapState, mapGetters } from 'vuex'
import SharingTabSidebar from './SharingTabSidebar'
import TagsTabSidebar from './TagsTabSidebar'
import DeletedTabSidebar from './DeletedTabSidebar'
import TimelineTabSidebar from './TimelineTabSidebar'
import SharingTabSidebar from './SharingTabSidebar.vue'
import TagsTabSidebar from './TagsTabSidebar.vue'
import DeletedTabSidebar from './DeletedTabSidebar.vue'
import TimelineTabSidebar from './TimelineTabSidebar.vue'
import { NcAppSidebar, NcAppSidebarTab } from '@nextcloud/vue'
const capabilities = window.OC.getCapabilities()

View File

@@ -32,7 +32,7 @@
<script>
import { mapState } from 'vuex'
import relativeDate from '../../mixins/relativeDate'
import relativeDate from '../../mixins/relativeDate.js'
export default {
name: 'DeletedTabSidebar',

View File

@@ -133,10 +133,10 @@ import { Container, Draggable } from 'vue-smooth-dnd'
import { NcActions, NcActionButton, NcModal } from '@nextcloud/vue'
import { showError, showUndo } from '@nextcloud/dialogs'
import CardItem from '../cards/CardItem'
import CardItem from '../cards/CardItem.vue'
import '@nextcloud/dialogs/styles/toast.scss'
import ArchiveIcon from 'vue-material-design-icons/Archive'
import ArchiveIcon from 'vue-material-design-icons/Archive.vue'
export default {
name: 'Stack',

View File

@@ -70,7 +70,7 @@
<script>
import { mapGetters } from 'vuex'
import Color from '../../mixins/color'
import Color from '../../mixins/color.js'
import { NcColorPicker, NcActions, NcActionButton } from '@nextcloud/vue'
export default {

View File

@@ -7,7 +7,7 @@
</template>
<script>
import ActivityList from '../ActivityList'
import ActivityList from '../ActivityList.vue'
export default {
name: 'TimelineTabSidebar',

View File

@@ -43,8 +43,8 @@
<script>
import BoardItem from './BoardItem'
import Controls from '../Controls'
import BoardItem from './BoardItem.vue'
import Controls from '../Controls.vue'
export default {
name: 'Boards',

View File

@@ -104,14 +104,14 @@
<script>
import axios from '@nextcloud/axios'
import { NcActions, NcActionButton, ActionLink } from '@nextcloud/vue'
import AttachmentDragAndDrop from '../AttachmentDragAndDrop'
import relativeDate from '../../mixins/relativeDate'
import AttachmentDragAndDrop from '../AttachmentDragAndDrop.vue'
import relativeDate from '../../mixins/relativeDate.js'
import { formatFileSize } from '@nextcloud/files'
import { getCurrentUser } from '@nextcloud/auth'
import { generateUrl, generateOcsUrl, generateRemoteUrl } from '@nextcloud/router'
import { mapState, mapActions } from 'vuex'
import { loadState } from '@nextcloud/initial-state'
import attachmentUpload from '../../mixins/attachmentUpload'
import attachmentUpload from '../../mixins/attachmentUpload.js'
import { getFilePickerBuilder } from '@nextcloud/dialogs'
const maxUploadSizeState = loadState('deck', 'maxUploadSize')

View File

@@ -85,11 +85,11 @@
import { NcActionButton, NcAppSidebar, NcAppSidebarTab } from '@nextcloud/vue'
import { generateUrl } from '@nextcloud/router'
import { mapState, mapGetters } from 'vuex'
import CardSidebarTabDetails from './CardSidebarTabDetails'
import CardSidebarTabAttachments from './CardSidebarTabAttachments'
import CardSidebarTabComments from './CardSidebarTabComments'
import CardSidebarTabActivity from './CardSidebarTabActivity'
import relativeDate from '../../mixins/relativeDate'
import CardSidebarTabDetails from './CardSidebarTabDetails.vue'
import CardSidebarTabAttachments from './CardSidebarTabAttachments.vue'
import CardSidebarTabComments from './CardSidebarTabComments.vue'
import CardSidebarTabActivity from './CardSidebarTabActivity.vue'
import relativeDate from '../../mixins/relativeDate.js'
import moment from '@nextcloud/moment'
import AttachmentIcon from 'vue-material-design-icons/Paperclip.vue'

View File

@@ -30,7 +30,7 @@
</template>
<script>
import ActivityList from '../ActivityList'
import ActivityList from '../ActivityList.vue'
export default {
name: 'CardSidebarTabActivity',

View File

@@ -28,7 +28,7 @@
</template>
<script>
import AttachmentList from './AttachmentList'
import AttachmentList from './AttachmentList.vue'
export default {
name: 'CardSidebarTabAttachments',
components: {

View File

@@ -36,8 +36,8 @@
<script>
import { mapState, mapGetters } from 'vuex'
import { NcAvatar } from '@nextcloud/vue'
import CommentItem from './CommentItem'
import CommentForm from './CommentForm'
import CommentItem from './CommentItem.vue'
import CommentForm from './CommentForm.vue'
import InfiniteLoading from 'vue-infinite-loading'
import { getCurrentUser } from '@nextcloud/auth'

View File

@@ -129,14 +129,14 @@ import { NcAvatar, NcActions, NcActionButton, NcMultiselect, NcDatetimePicker }
import { loadState } from '@nextcloud/initial-state'
import { CollectionList } from 'nextcloud-vue-collections'
import Color from '../../mixins/color'
import Color from '../../mixins/color.js'
import {
getLocale,
getDayNamesMin,
getFirstDay,
getMonthNamesShort,
} from '@nextcloud/l10n'
import Description from './Description'
import Description from './Description.vue'
export default {
name: 'CardSidebarTabDetails',

View File

@@ -65,7 +65,7 @@
import { mapState } from 'vuex'
import { NcUserBubble, NcAvatar } from '@nextcloud/vue'
import At from 'vue-at'
import { rawToParsed } from '../../helpers/mentions'
import { rawToParsed } from '../../helpers/mentions.js'
export default {
name: 'CommentForm',

View File

@@ -66,10 +66,10 @@
<script>
import { NcAvatar, NcActions, NcActionButton, NcUserBubble } from '@nextcloud/vue'
import RichText from '@juliushaertl/vue-richtext'
import CommentForm from './CommentForm'
import CommentForm from './CommentForm.vue'
import { getCurrentUser } from '@nextcloud/auth'
import md5 from 'blueimp-md5'
import relativeDate from '../../mixins/relativeDate'
import relativeDate from '../../mixins/relativeDate.js'
import ReplyIcon from 'vue-material-design-icons/Reply'
const AtMention = {

View File

@@ -78,7 +78,7 @@
import MarkdownIt from 'markdown-it'
import MarkdownItTaskCheckbox from 'markdown-it-task-checkbox'
import MarkdownItLinkAttributes from 'markdown-it-link-attributes'
import AttachmentList from './AttachmentList'
import AttachmentList from './AttachmentList.vue'
import { NcActions, NcActionButton, NcModal } from '@nextcloud/vue'
import { formatFileSize } from '@nextcloud/files'
import { generateUrl } from '@nextcloud/router'

View File

@@ -49,8 +49,8 @@
</div>
</template>
<script>
import NcAvatarList from './AvatarList'
import CardMenu from './CardMenu'
import NcAvatarList from './AvatarList.vue'
import CardMenu from './CardMenu.vue'
import TextIcon from 'vue-material-design-icons/Text.vue'
import AttachmentIcon from 'vue-material-design-icons/Paperclip.vue'
import CheckmarkIcon from 'vue-material-design-icons/CheckboxMarked.vue'

View File

@@ -83,12 +83,12 @@
<script>
import ClickOutside from 'vue-click-outside'
import { mapState, mapGetters } from 'vuex'
import CardBadges from './CardBadges'
import Color from '../../mixins/color'
import labelStyle from '../../mixins/labelStyle'
import AttachmentDragAndDrop from '../AttachmentDragAndDrop'
import CardMenu from './CardMenu'
import DueDate from './badges/DueDate'
import CardBadges from './CardBadges.vue'
import Color from '../../mixins/color.js'
import labelStyle from '../../mixins/labelStyle.js'
import AttachmentDragAndDrop from '../AttachmentDragAndDrop.vue'
import CardMenu from './CardMenu.vue'
import DueDate from './badges/DueDate.vue'
export default {
name: 'CardItem',

View File

@@ -1,38 +1,55 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg"
:height="size"
:width="size"
version="1.1"
viewBox="0 0 16 16">
<rect ry="1"
height="8"
width="14"
y="7"
x="1" />
<rect ry=".5"
height="1"
width="12"
y="5"
x="2" />
<rect ry=".5"
height="1"
width="10"
y="3"
x="3" />
<rect ry=".5"
height="1"
width="8"
y="1"
x="4" />
</svg>
<span :aria-hidden="!title"
:aria-label="title"
class="material-design-icon deck-icon"
role="img"
v-bind="$attrs"
@click="$emit('click', $event)">
<svg xmlns="http://www.w3.org/2000/svg"
:fill="fillColor"
:height="size"
:width="size"
version="1.1"
viewBox="0 0 16 16">
<rect ry="1"
height="8"
width="14"
y="7"
x="1" />
<rect ry=".5"
height="1"
width="12"
y="5"
x="2" />
<rect ry=".5"
height="1"
width="10"
y="3"
x="3" />
<rect ry=".5"
height="1"
width="8"
y="1"
x="4" />
</svg>
</span>
</template>
<script>
export default {
name: 'DeckIcon',
props: {
title: {
type: String,
default: '',
},
fillColor: {
type: String,
default: 'currentColor',
},
size: {
type: Number,
default: 16,
default: 24,
},
},
}

View File

@@ -107,8 +107,8 @@ import axios from '@nextcloud/axios'
import { mapGetters } from 'vuex'
import ClickOutside from 'vue-click-outside'
import { NcAppNavigation, NcAppNavigationItem, NcAppNavigationSettings, NcMultiselect } from '@nextcloud/vue'
import AppNavigationAddBoard from './AppNavigationAddBoard'
import AppNavigationBoardCategory from './AppNavigationBoardCategory'
import AppNavigationAddBoard from './AppNavigationAddBoard.vue'
import AppNavigationBoardCategory from './AppNavigationBoardCategory.vue'
import { loadState } from '@nextcloud/initial-state'
import { generateOcsUrl } from '@nextcloud/router'
import { getCurrentUser } from '@nextcloud/auth'

View File

@@ -34,7 +34,7 @@
</template>
<script>
import AppNavigationBoard from './AppNavigationBoard'
import AppNavigationBoard from './AppNavigationBoard.vue'
import { NcAppNavigationItem } from '@nextcloud/vue'
export default {

View File

@@ -80,11 +80,11 @@
<script>
import Controls from '../Controls'
import CardItem from '../cards/CardItem'
import Controls from '../Controls.vue'
import CardItem from '../cards/CardItem.vue'
import { mapGetters } from 'vuex'
import moment from '@nextcloud/moment'
import GlobalSearchResults from '../search/GlobalSearchResults'
import GlobalSearchResults from '../search/GlobalSearchResults.vue'
const FILTER_UPCOMING = 'upcoming'

View File

@@ -52,13 +52,13 @@
</template>
<script>
import CardItem from '../cards/CardItem'
import CardItem from '../cards/CardItem.vue'
import { mapState } from 'vuex'
import axios from '@nextcloud/axios'
import { generateOcsUrl } from '@nextcloud/router'
import InfiniteLoading from 'vue-infinite-loading'
import RichText from '@juliushaertl/vue-richtext'
import Placeholder from './Placeholder'
import Placeholder from './Placeholder.vue'
import { NcActions, NcActionButton } from '@nextcloud/vue'
const createCancelToken = () => axios.CancelToken.source()

View File

@@ -0,0 +1,49 @@
/**
* @copyright Copyright (c) 2022 Julien Veyssier <eneiluj@posteo.net>
*
* @author Julien Veyssier <eneiluj@posteo.net>
*
* @license AGPL-3.0-or-later
*
* 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 { registerWidget } from '@nextcloud/vue-richtext'
import Tooltip from '@nextcloud/vue/dist/Directives/Tooltip.js'
import Vue from 'vue'
import CardReferenceWidget from './views/CardReferenceWidget.vue'
import { translate, translatePlural } from '@nextcloud/l10n'
Vue.prototype.t = translate
Vue.prototype.n = translatePlural
Vue.prototype.OC = window.OC
Vue.prototype.OCA = window.OCA
Vue.directive('tooltip', Tooltip)
registerWidget('deck-card', (el, { richObjectType, richObject, accessible }) => {
// trick to change the wrapper element size, otherwise it always is 100%
// which is not very nice with a simple card
el.parentNode.style['max-width'] = '400px'
el.parentNode.style['min-width'] = '200px'
const Widget = Vue.extend(CardReferenceWidget)
new Widget({
propsData: {
richObjectType,
richObject,
accessible,
},
}).$mount(el)
})

View File

@@ -23,8 +23,8 @@
import Vue from 'vue'
import './../css/collections.css'
import FileSharingPicker from './views/FileSharingPicker'
import { buildSelector } from './helpers/selector'
import FileSharingPicker from './views/FileSharingPicker.js'
import { buildSelector } from './helpers/selector.js'
// eslint-disable-next-line
__webpack_nonce__ = btoa(OC.requestToken);
@@ -44,7 +44,7 @@ window.addEventListener('DOMContentLoaded', () => {
window.OCP.Collaboration.registerType('deck', {
action: () => {
const BoardSelector = () => import('./BoardSelector')
const BoardSelector = () => import('./BoardSelector.vue')
return buildSelector(BoardSelector)
},
typeString: t('deck', 'Link to a board'),
@@ -53,7 +53,7 @@ window.addEventListener('DOMContentLoaded', () => {
window.OCP.Collaboration.registerType('deck-card', {
action: () => {
const CardSelector = () => import('./CardSelector')
const CardSelector = () => import('./CardSelector.vue')
return buildSelector(CardSelector)
},
typeString: t('deck', 'Link to a card'),

View File

@@ -23,7 +23,7 @@
import Vue from 'vue'
import Vuex from 'vuex'
import overview from './store/overview'
import overview from './store/overview.js'
import './css/dashboard.scss'

View File

@@ -23,9 +23,9 @@
import Vue from 'vue'
import { generateUrl } from '@nextcloud/router'
import CardCreateDialog from './CardCreateDialog'
import { buildSelector } from './helpers/selector'
import './init-collections'
import CardCreateDialog from './CardCreateDialog.vue'
import { buildSelector } from './helpers/selector.js'
import './init-collections.js'
// eslint-disable-next-line
__webpack_nonce__ = btoa(OC.requestToken);

View File

@@ -20,9 +20,9 @@
*
*/
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store/main'
import App from './App.vue'
import router from './router.js'
import store from './store/main.js'
import { sync } from 'vuex-router-sync'
import { translate, translatePlural } from '@nextcloud/l10n'
import { generateFilePath } from '@nextcloud/router'
@@ -30,7 +30,7 @@ import { showError } from '@nextcloud/dialogs'
import { subscribe } from '@nextcloud/event-bus'
import { Tooltip } from '@nextcloud/vue'
import ClickOutside from 'vue-click-outside'
import './models'
import './models/index.js'
// the server snap.js conflicts with vertical scrolling so we disable it
document.body.setAttribute('data-snap-ignore', 'true')

View File

@@ -20,7 +20,7 @@
*
*/
import Color from './color'
import Color from './color.js'
export default {
mixins: [Color],

View File

@@ -23,13 +23,13 @@
import Vue from 'vue'
import Router from 'vue-router'
import { generateUrl } from '@nextcloud/router'
import { BOARD_FILTERS } from './store/main'
import Boards from './components/boards/Boards'
import Board from './components/board/Board'
import Sidebar from './components/Sidebar'
import BoardSidebar from './components/board/BoardSidebar'
import CardSidebar from './components/card/CardSidebar'
import Overview from './components/overview/Overview'
import { BOARD_FILTERS } from './store/main.js'
import Boards from './components/boards/Boards.vue'
import Board from './components/board/Board.vue'
import Sidebar from './components/Sidebar.vue'
import BoardSidebar from './components/board/BoardSidebar.vue'
import CardSidebar from './components/card/CardSidebar.vue'
import Overview from './components/overview/Overview.vue'
Vue.use(Router)

View File

@@ -22,7 +22,7 @@
import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router'
import './../models'
import '../models/index.js'
/**
* This class handles all the api communication with the Deck backend.

View File

@@ -22,7 +22,7 @@
import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router'
import './../models'
import '../models/index.js'
export class StackApi {

View File

@@ -20,7 +20,7 @@
*
*/
import { AttachmentApi } from './../services/AttachmentApi'
import { AttachmentApi } from './../services/AttachmentApi.js'
import Vue from 'vue'
const apiClient = new AttachmentApi()

View File

@@ -20,7 +20,7 @@
*
*/
import { CardApi } from './../services/CardApi'
import { CardApi } from './../services/CardApi.js'
import moment from 'moment'
import Vue from 'vue'

View File

@@ -20,7 +20,7 @@
*
*/
import { CommentApi } from '../services/CommentApi'
import { CommentApi } from '../services/CommentApi.js'
import Vue from 'vue'
const apiClient = new CommentApi()

View File

@@ -27,14 +27,14 @@ import Vue from 'vue'
import Vuex from 'vuex'
import axios from '@nextcloud/axios'
import { generateOcsUrl, generateUrl } from '@nextcloud/router'
import { BoardApi } from '../services/BoardApi'
import actions from './actions'
import stack from './stack'
import card from './card'
import comment from './comment'
import trashbin from './trashbin'
import attachment from './attachment'
import overview from './overview'
import { BoardApi } from '../services/BoardApi.js'
import actions from './actions.js'
import stack from './stack.js'
import card from './card.js'
import comment from './comment.js'
import trashbin from './trashbin.js'
import attachment from './attachment.js'
import overview from './overview.js'
Vue.use(Vuex)
const apiClient = new BoardApi()

View File

@@ -22,7 +22,7 @@
import Vue from 'vue'
import Vuex from 'vuex'
import { OverviewApi } from '../services/OverviewApi'
import { OverviewApi } from '../services/OverviewApi.js'
Vue.use(Vuex)
const apiClient = new OverviewApi()

View File

@@ -21,8 +21,8 @@
*/
import Vue from 'vue'
import { StackApi } from './../services/StackApi'
import applyOrderToArray from './../helpers/applyOrderToArray'
import { StackApi } from './../services/StackApi.js'
import applyOrderToArray from './../helpers/applyOrderToArray.js'
const apiClient = new StackApi()

View File

@@ -20,8 +20,8 @@
*
*/
import { StackApi } from '../services/StackApi'
import { CardApi } from '../services/CardApi'
import { StackApi } from '../services/StackApi.js'
import { CardApi } from '../services/CardApi.js'
const stackApi = new StackApi()
const cardApi = new CardApi()

View File

@@ -0,0 +1,235 @@
<!--
- @copyright Copyright (c) 2022 2022 Julien Veyssier <eneiluj@posteo.net>
-
- @author 2022 Julien Veyssier <eneiluj@posteo.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/>.
-->
<template>
<div class="deck-card-reference">
<h3>
<DeckIcon :size="20" class="icon" />
<a v-tooltip.top="{ content: boardTooltip }"
:href="boardLink"
target="_blank"
class="link">
{{ board.title }}
</a>
<a v-tooltip.top="{ content: stackTooltip }"
:href="boardLink"
target="_blank"
class="link">
/ {{ stack.title }}
</a>
</h3>
<div class="line">
<a :href="cardLink"
:title="cardTooltip"
target="_blank"
class="link">
{{ card.title }}
</a>
<div class="spacer" />
<span v-show="dueDate"
v-tooltip.top="{ content: formattedDueDate }"
class="due-date">
<CalendarBlankIcon :size="20"
class="icon" />
{{ dueDate }}
</span>
</div>
<div>
<transition-group v-if="card.labels && card.labels.length"
name="zoom"
tag="ul"
class="labels"
@click.stop="openCard">
<li v-for="label in labelsSorted" :key="label.id" :style="labelStyle(label)">
<span>{{ label.title }}</span>
</li>
</transition-group>
</div>
<div class="line description-assignees">
<TextIcon v-if="card.description" :size="20" class="icon" />
<div class="description"
:title="card.description">
{{ card.description }}
</div>
<div class="spacer" />
<AvatarList :users="card.assignedUsers" class="card-assignees" />
</div>
</div>
</template>
<script>
import CalendarBlankIcon from 'vue-material-design-icons/CalendarBlank.vue'
import TextIcon from 'vue-material-design-icons/Text.vue'
import DeckIcon from '../components/icons/DeckIcon.vue'
import AvatarList from '../components/cards/AvatarList.vue'
import labelStyle from '../mixins/labelStyle.js'
import moment from '@nextcloud/moment'
import { generateUrl } from '@nextcloud/router'
export default {
name: 'CardReferenceWidget',
components: {
AvatarList,
DeckIcon,
CalendarBlankIcon,
TextIcon,
},
mixins: [labelStyle],
props: {
richObjectType: {
type: String,
default: '',
},
richObject: {
type: Object,
default: null,
},
accessible: {
type: Boolean,
default: true,
},
},
data() {
return {
}
},
computed: {
card() {
return this.richObject.card
},
board() {
return this.richObject.board
},
stack() {
return this.richObject.stack
},
cardLink() {
return generateUrl('/apps/deck/#/board/{boardId}/card/{cardId}', { boardId: this.board.id, cardId: this.card.id })
},
boardLink() {
return generateUrl('/apps/deck/#/board/{boardId}', { boardId: this.board.id })
},
cardTooltip() {
return t('deck', '* Created on {created}\n* Last modified on {lastMod}\n* {nbAttachments} attachments\n* {nbComments} comments', {
created: moment.unix(this.card.createdAt).format('LLL'),
lastMod: moment.unix(this.card.lastModified).format('LLL'),
nbAttachments: this.card.attachments.length,
nbComments: this.card.commentsCount,
})
},
boardTooltip() {
return t('deck', 'Owned by {dn}', { dn: this.board.owner.displayname })
},
stackTooltip() {
return t('deck', '{nbCards} cards', { nbCards: this.stack.cards.length })
},
dueDate() {
return this.card.duedate
? moment(this.card.duedate).fromNow()
: null
},
formattedDueDate() {
return this.card.duedate
? t('deck', 'Due on {date}', { date: moment(this.card.duedate).format('LLL') })
: null
},
labelsSorted() {
return [...this.card.labels].sort((a, b) => (a.title < b.title) ? -1 : 1)
},
},
methods: {
},
}
</script>
<style scoped lang="scss">
/* stylelint-disable-next-line no-invalid-position-at-import-rule */
@import '../css/labels';
.deck-card-reference {
width: 100%;
white-space: normal;
padding: 12px;
h3 {
display: flex;
align-items: center;
justify-content: center;
margin: 0 0 8px 0;
font-weight: bold;
.icon {
margin-right: 8px;
}
}
.link:hover {
text-decoration: underline;
}
.line {
display: flex;
align-items: center;
.icon {
margin-right: 4px;
}
}
.due-date {
display: flex;
align-items: center;
}
.labels {
margin: 8px 0;
}
.description-assignees {
width: 100%;
display: flex;
align-items: center;
.description {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
margin-right: 8px;
}
.card-assignees {
margin-top: 0;
height: 36px;
flex-grow: unset;
}
}
.spacer {
flex-grow: 1;
}
}
</style>

View File

@@ -59,10 +59,10 @@
<script>
import { NcDashboardWidget } from '@nextcloud/vue'
import { mapGetters } from 'vuex'
import labelStyle from './../mixins/labelStyle'
import DueDate from '../components/cards/badges/DueDate'
import labelStyle from './../mixins/labelStyle.js'
import DueDate from '../components/cards/badges/DueDate.vue'
import { generateUrl } from '@nextcloud/router'
import CardCreateDialog from '../CardCreateDialog'
import CardCreateDialog from '../CardCreateDialog.vue'
export default {
name: 'Dashboard',

View File

@@ -21,7 +21,7 @@
*/
import Vue from 'vue'
import { createShare } from '../services/SharingApi'
import { createShare } from '../services/SharingApi.js'
export default {
icon: 'icon-deck',
@@ -33,7 +33,7 @@ export default {
container.id = 'deck-board-select'
const body = document.getElementById('body-user')
body.append(container)
const CardSelector = () => import('./../CardSelector')
const CardSelector = () => import('./../CardSelector.vue')
const ComponentVM = new Vue({
render: (h) => h(CardSelector, {
title: t('deck', 'Share {file} with a Deck card', { file: decodeURIComponent(self.fileInfo.name) }),

View File

@@ -1,5 +1,10 @@
const webpackConfig = require('@nextcloud/webpack-vue-config')
const path = require('path')
const ESLintPlugin = require('eslint-webpack-plugin')
const StyleLintPlugin = require('stylelint-webpack-plugin')
const buildMode = process.env.NODE_ENV
const isDev = buildMode === 'development'
webpackConfig.entry = {
...webpackConfig.entry,
@@ -7,6 +12,7 @@ webpackConfig.entry = {
dashboard: path.join(__dirname, 'src', 'init-dashboard.js'),
calendar: path.join(__dirname, 'src', 'init-calendar.js'),
talk: path.join(__dirname, 'src', 'init-talk.js'),
'card-reference': path.join(__dirname, 'src', 'init-card-reference.js'),
}
webpackConfig.stats = {
@@ -17,4 +23,18 @@ webpackConfig.stats = {
modules: true,
}
webpackConfig.plugins.push(
new ESLintPlugin({
extensions: ['js', 'vue'],
files: 'src',
failOnError: !isDev,
})
)
webpackConfig.plugins.push(
new StyleLintPlugin({
files: 'src/**/*.{css,scss,vue}',
failOnError: !isDev,
}),
)
module.exports = webpackConfig