Compare commits
44 Commits
fix/some-b
...
backport/6
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c846880a1e | ||
|
|
acaaccda05 | ||
|
|
67b378fda5 | ||
|
|
827b7da7c2 | ||
|
|
e01149cd81 | ||
|
|
4b594be8f0 | ||
|
|
b570dd8880 | ||
|
|
afc92908fd | ||
|
|
58bc1a87b1 | ||
|
|
dbbd57e443 | ||
|
|
0d42750d19 | ||
|
|
c56170f76f | ||
|
|
c56aeba3d3 | ||
|
|
ca4e0c122b | ||
|
|
05939792a1 | ||
|
|
5cbd91649b | ||
|
|
61d58fb4eb | ||
|
|
5aa2428e2d | ||
|
|
d35d8e5a50 | ||
|
|
71fe340fad | ||
|
|
6f3f391a04 | ||
|
|
50dea78147 | ||
|
|
3f3b1a11d7 | ||
|
|
c29686feec | ||
|
|
086617563d | ||
|
|
c7d7f2e5fe | ||
|
|
ac19f517c5 | ||
|
|
9a738ee7ac | ||
|
|
b81c249164 | ||
|
|
20f74812ea | ||
|
|
63709be9ad | ||
|
|
a94efb4905 | ||
|
|
412a5d183e | ||
|
|
e144303e26 | ||
|
|
fdb3a29256 | ||
|
|
de760ac6fa | ||
|
|
1e20832cd6 | ||
|
|
8e77849027 | ||
|
|
147dadd1ab | ||
|
|
bd39df04f6 | ||
|
|
12f30e946e | ||
|
|
01a6f93730 | ||
|
|
c72bec7220 | ||
|
|
c9a5f9e79b |
34
.github/dependabot.yml
vendored
34
.github/dependabot.yml
vendored
@@ -13,23 +13,6 @@ updates:
|
||||
- juliushaertl
|
||||
- luka-nextcloud
|
||||
|
||||
- package-ecosystem: npm
|
||||
target-branch: stable30
|
||||
versioning-strategy: lockfile-only
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: saturday
|
||||
time: "03:00"
|
||||
timezone: Europe/Paris
|
||||
ignore:
|
||||
- dependency-name: "*"
|
||||
update-types: ["version-update:semver-major"]
|
||||
open-pull-requests-limit: 30
|
||||
labels:
|
||||
- 3. to review
|
||||
- dependencies
|
||||
|
||||
- package-ecosystem: npm
|
||||
target-branch: stable29
|
||||
versioning-strategy: lockfile-only
|
||||
@@ -64,6 +47,23 @@ updates:
|
||||
- 3. to review
|
||||
- dependencies
|
||||
|
||||
- package-ecosystem: npm
|
||||
target-branch: stable27
|
||||
versioning-strategy: lockfile-only
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: saturday
|
||||
time: "03:00"
|
||||
timezone: Europe/Paris
|
||||
ignore:
|
||||
- dependency-name: "*"
|
||||
update-types: ["version-update:semver-major"]
|
||||
open-pull-requests-limit: 30
|
||||
labels:
|
||||
- 3. to review
|
||||
- dependencies
|
||||
|
||||
- package-ecosystem: composer
|
||||
directory: "/"
|
||||
schedule:
|
||||
|
||||
2
.github/workflows/cypress-e2e.yml
vendored
2
.github/workflows/cypress-e2e.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
||||
node-version: [20.x]
|
||||
# containers: [1, 2, 3]
|
||||
php-versions: [ '8.2' ]
|
||||
server-versions: [ 'master' ]
|
||||
server-versions: [ 'stable30' ]
|
||||
|
||||
env:
|
||||
extensions: mbstring, iconv, fileinfo, intl, sqlite, pdo_sqlite, zip, gd, apcu
|
||||
|
||||
2
.github/workflows/integration.yml
vendored
2
.github/workflows/integration.yml
vendored
@@ -28,7 +28,7 @@ jobs:
|
||||
matrix:
|
||||
php-versions: ['8.1']
|
||||
databases: ['sqlite', 'mysql', 'pgsql']
|
||||
server-versions: ['master']
|
||||
server-versions: ['stable30']
|
||||
|
||||
name: php${{ matrix.php-versions }}-${{ matrix.databases }}-${{ matrix.server-versions }}
|
||||
|
||||
|
||||
2
.github/workflows/npm-audit-fix.yml
vendored
2
.github/workflows/npm-audit-fix.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
branches: ['main', 'master', 'stable30', 'stable29', 'stable28']
|
||||
branches: ['main', 'master', 'stable29', 'stable28', 'stable27']
|
||||
|
||||
name: npm-audit-fix-${{ matrix.branches }}
|
||||
|
||||
|
||||
2
.github/workflows/update-nextcloud-ocp.yml
vendored
2
.github/workflows/update-nextcloud-ocp.yml
vendored
@@ -20,7 +20,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
branches: ['main', 'master', 'stable30', 'stable29', 'stable28']
|
||||
branches: ['main', 'master', 'stable29', 'stable28', 'stable27']
|
||||
|
||||
name: update-nextcloud-ocp-${{ matrix.branches }}
|
||||
|
||||
|
||||
@@ -20,17 +20,17 @@
|
||||
- 🚀 Get your project organized
|
||||
|
||||
</description>
|
||||
<version>2.0.0-dev.0</version>
|
||||
<version>1.14.0-beta.2</version>
|
||||
<licence>agpl</licence>
|
||||
<author>Julius Härtl</author>
|
||||
<namespace>Deck</namespace>
|
||||
<types>
|
||||
<dav/>
|
||||
</types>
|
||||
<documentation>
|
||||
<user>https://deck.readthedocs.io/en/latest/User_documentation_en/</user>
|
||||
<developer>https://deck.readthedocs.io/en/latest/API/</developer>
|
||||
</documentation>
|
||||
<namespace>Deck</namespace>
|
||||
<types>
|
||||
<dav/>
|
||||
</types>
|
||||
<category>organization</category>
|
||||
<category>office</category>
|
||||
<website>https://github.com/nextcloud/deck</website>
|
||||
@@ -42,7 +42,7 @@
|
||||
<database min-version="9.4">pgsql</database>
|
||||
<database>sqlite</database>
|
||||
<database min-version="8.0">mysql</database>
|
||||
<nextcloud min-version="31" max-version="31"/>
|
||||
<nextcloud min-version="30" max-version="30"/>
|
||||
</dependencies>
|
||||
<background-jobs>
|
||||
<job>OCA\Deck\Cron\DeleteCron</job>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
"roave/security-advisories": "dev-master",
|
||||
"phpunit/phpunit": "^9",
|
||||
"nextcloud/coding-standard": "^1.1",
|
||||
"nextcloud/ocp": "dev-master",
|
||||
"nextcloud/ocp": "dev-stable30",
|
||||
"psalm/phar": "^5.13"
|
||||
},
|
||||
"config": {
|
||||
|
||||
41
composer.lock
generated
41
composer.lock
generated
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "ee1c5b69795943e43d6277064d284ae0",
|
||||
"content-hash": "7242ec950e99240a95e6b6d877fdd8d2",
|
||||
"packages": [
|
||||
{
|
||||
"name": "icecave/parity",
|
||||
@@ -399,16 +399,16 @@
|
||||
},
|
||||
{
|
||||
"name": "nextcloud/coding-standard",
|
||||
"version": "v1.2.3",
|
||||
"version": "v1.2.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nextcloud/coding-standard.git",
|
||||
"reference": "bc9c53a5306114b60c4363057aff9c2ed10a54da"
|
||||
"reference": "cf5f18d989ec62fb4cdc7fc92a36baf34b3d829e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nextcloud/coding-standard/zipball/bc9c53a5306114b60c4363057aff9c2ed10a54da",
|
||||
"reference": "bc9c53a5306114b60c4363057aff9c2ed10a54da",
|
||||
"url": "https://api.github.com/repos/nextcloud/coding-standard/zipball/cf5f18d989ec62fb4cdc7fc92a36baf34b3d829e",
|
||||
"reference": "cf5f18d989ec62fb4cdc7fc92a36baf34b3d829e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -434,22 +434,22 @@
|
||||
"description": "Nextcloud coding standards for the php cs fixer",
|
||||
"support": {
|
||||
"issues": "https://github.com/nextcloud/coding-standard/issues",
|
||||
"source": "https://github.com/nextcloud/coding-standard/tree/v1.2.3"
|
||||
"source": "https://github.com/nextcloud/coding-standard/tree/v1.2.1"
|
||||
},
|
||||
"time": "2024-08-23T14:32:32+00:00"
|
||||
"time": "2024-02-01T14:54:37+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nextcloud/ocp",
|
||||
"version": "dev-master",
|
||||
"version": "dev-stable30",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nextcloud-deps/ocp.git",
|
||||
"reference": "b6538d7f14472c2ef6182c51df6be34cae033099"
|
||||
"reference": "65bc71ed71b10f60394e3a3165f27e78e6b087cb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nextcloud-deps/ocp/zipball/b6538d7f14472c2ef6182c51df6be34cae033099",
|
||||
"reference": "b6538d7f14472c2ef6182c51df6be34cae033099",
|
||||
"url": "https://api.github.com/repos/nextcloud-deps/ocp/zipball/65bc71ed71b10f60394e3a3165f27e78e6b087cb",
|
||||
"reference": "65bc71ed71b10f60394e3a3165f27e78e6b087cb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -459,11 +459,10 @@
|
||||
"psr/event-dispatcher": "^1.0",
|
||||
"psr/log": "^1.1.4"
|
||||
},
|
||||
"default-branch": true,
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "31.0.0-dev"
|
||||
"dev-stable30": "30.0.0-dev"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
@@ -479,9 +478,9 @@
|
||||
"description": "Composer package containing Nextcloud's public API (classes, interfaces)",
|
||||
"support": {
|
||||
"issues": "https://github.com/nextcloud-deps/ocp/issues",
|
||||
"source": "https://github.com/nextcloud-deps/ocp/tree/master"
|
||||
"source": "https://github.com/nextcloud-deps/ocp/tree/stable30"
|
||||
},
|
||||
"time": "2024-08-31T00:39:40+00:00"
|
||||
"time": "2024-08-31T00:39:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nikic/php-parser",
|
||||
@@ -661,16 +660,16 @@
|
||||
},
|
||||
{
|
||||
"name": "php-cs-fixer/shim",
|
||||
"version": "v3.62.0",
|
||||
"version": "v3.49.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHP-CS-Fixer/shim.git",
|
||||
"reference": "7a91d5ce45c486f5b445d95901228507a02f60ae"
|
||||
"reference": "f7d3219cac46632f12362c9aa7c2ac0d2fe92c52"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/shim/zipball/7a91d5ce45c486f5b445d95901228507a02f60ae",
|
||||
"reference": "7a91d5ce45c486f5b445d95901228507a02f60ae",
|
||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/shim/zipball/f7d3219cac46632f12362c9aa7c2ac0d2fe92c52",
|
||||
"reference": "f7d3219cac46632f12362c9aa7c2ac0d2fe92c52",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -707,9 +706,9 @@
|
||||
"description": "A tool to automatically fix PHP code style",
|
||||
"support": {
|
||||
"issues": "https://github.com/PHP-CS-Fixer/shim/issues",
|
||||
"source": "https://github.com/PHP-CS-Fixer/shim/tree/v3.62.0"
|
||||
"source": "https://github.com/PHP-CS-Fixer/shim/tree/v3.49.0"
|
||||
},
|
||||
"time": "2024-08-07T17:03:46+00:00"
|
||||
"time": "2024-02-02T00:42:09+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
|
||||
@@ -35,7 +35,7 @@ describe('Board', function() {
|
||||
.type(board, { force: true })
|
||||
|
||||
// Submit
|
||||
cy.get('.board-create form button[type=submit]')
|
||||
cy.get('.board-create form input[type=submit]')
|
||||
.first().click({ force: true })
|
||||
|
||||
cy.wait('@createBoardRequest').its('response.statusCode').should('equal', 200)
|
||||
|
||||
@@ -13,7 +13,7 @@ The Deck application plugin uses the [markdown-it](https://github.com/markdown-i
|
||||
|
||||
## Supported Markdown
|
||||
|
||||
Markdown comes in many flavors. The best way to learn markdown and understand how to use it, is simply to [try it](https://markdown-it.github.io) on the original script official playground.
|
||||
Markdown comes in may flavors. The best way to learn markdown and understand how to use it, is simply to [try it](https://markdown-it.github.io) on the original script official playground.
|
||||
That same link offers also a comprehensive list of what is supported, and what is not - rendering it unnecessary to duplicate that content in here.
|
||||
|
||||
[CommonMark Markdown Reference](http://commonmark.org/help/)
|
||||
|
||||
@@ -39,8 +39,8 @@ class Filter implements \OCP\Activity\IFilter {
|
||||
|
||||
/**
|
||||
* @return int whether the filter should be rather on the top or bottom of
|
||||
* the admin section. The filters are arranged in ascending order of the
|
||||
* priority values. It is required to return a value between 0 and 100.
|
||||
* the admin section. The filters are arranged in ascending order of the
|
||||
* priority values. It is required to return a value between 0 and 100.
|
||||
* @since 11.0.0
|
||||
*/
|
||||
public function getPriority(): int {
|
||||
|
||||
@@ -47,8 +47,8 @@ abstract class SettingBase extends ActivitySettings {
|
||||
|
||||
/**
|
||||
* @return int whether the filter should be rather on the top or bottom of
|
||||
* the admin section. The filters are arranged in ascending order of the
|
||||
* priority values. It is required to return a value between 0 and 100.
|
||||
* the admin section. The filters are arranged in ascending order of the
|
||||
* priority values. It is required to return a value between 0 and 100.
|
||||
* @since 11.0.0
|
||||
*/
|
||||
public function getPriority(): int {
|
||||
|
||||
@@ -25,8 +25,8 @@ class SettingChanges extends SettingBase {
|
||||
|
||||
/**
|
||||
* @return int whether the filter should be rather on the top or bottom of
|
||||
* the admin section. The filters are arranged in ascending order of the
|
||||
* priority values. It is required to return a value between 0 and 100.
|
||||
* the admin section. The filters are arranged in ascending order of the
|
||||
* priority values. It is required to return a value between 0 and 100.
|
||||
* @since 11.0.0
|
||||
*/
|
||||
public function getPriority(): int {
|
||||
|
||||
@@ -176,7 +176,7 @@ class Application extends App implements IBootstrap {
|
||||
$permissionService = $this->getContainer()->get(PermissionService::class);
|
||||
|
||||
try {
|
||||
return $permissionService->checkPermission($cardMapper, (int)$name, Acl::PERMISSION_READ);
|
||||
return $permissionService->checkPermission($cardMapper, (int) $name, Acl::PERMISSION_READ);
|
||||
} catch (\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ class Capabilities implements ICapability {
|
||||
|
||||
/** @var IAppManager */
|
||||
private $appManager;
|
||||
/** @var PermissionService */
|
||||
/** @var PermissionService */
|
||||
private $permissionService;
|
||||
|
||||
|
||||
|
||||
@@ -72,17 +72,17 @@ final class TransferOwnership extends Command {
|
||||
try {
|
||||
$board = $boardId ? $this->boardMapper->find($boardId) : null;
|
||||
} catch (\Exception $e) {
|
||||
$output->writeln('Could not find a board for the provided id.');
|
||||
$output->writeln("Could not find a board for the provided id.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ($boardId !== null && $board->getOwner() !== $owner) {
|
||||
$output->writeln("$owner is not the owner of the board $boardId (" . $board->getTitle() . ')');
|
||||
$output->writeln("$owner is not the owner of the board $boardId (" . $board->getTitle() . ")");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ($boardId) {
|
||||
$output->writeln('Transfer board ' . $board->getTitle() . ' from '. $board->getOwner() ." to $newOwner");
|
||||
$output->writeln("Transfer board " . $board->getTitle() . " from ". $board->getOwner() ." to $newOwner");
|
||||
} else {
|
||||
$output->writeln("Transfer all boards from $owner to $newOwner");
|
||||
}
|
||||
@@ -94,12 +94,12 @@ final class TransferOwnership extends Command {
|
||||
|
||||
if ($boardId) {
|
||||
$this->boardService->transferBoardOwnership($boardId, $newOwner, $remapAssignment);
|
||||
$output->writeln('<info>Board ' . $board->getTitle() . ' from '. $board->getOwner() ." transferred to $newOwner completed</info>");
|
||||
$output->writeln("<info>Board " . $board->getTitle() . " from ". $board->getOwner() ." transferred to $newOwner completed</info>");
|
||||
return 0;
|
||||
}
|
||||
|
||||
foreach ($this->boardService->transferOwnership($owner, $newOwner, $remapAssignment) as $board) {
|
||||
$output->writeln(' - ' . $board->getTitle() . ' transferred');
|
||||
$output->writeln(" - " . $board->getTitle() . " transferred");
|
||||
}
|
||||
$output->writeln("<info>All boards from $owner to $newOwner transferred</info>");
|
||||
|
||||
|
||||
@@ -12,17 +12,27 @@ use OCA\Deck\Notification\NotificationHelper;
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\BackgroundJob\Job;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use OCP\ILogger;
|
||||
|
||||
class ScheduledNotifications extends Job {
|
||||
|
||||
/** @var CardMapper */
|
||||
protected $cardMapper;
|
||||
/** @var NotificationHelper */
|
||||
protected $notificationHelper;
|
||||
/** @var ILogger */
|
||||
protected $logger;
|
||||
|
||||
public function __construct(
|
||||
ITimeFactory $time,
|
||||
protected CardMapper $cardMapper,
|
||||
protected NotificationHelper $notificationHelper,
|
||||
protected LoggerInterface $logger
|
||||
CardMapper $cardMapper,
|
||||
NotificationHelper $notificationHelper,
|
||||
ILogger $logger
|
||||
) {
|
||||
parent::__construct($time);
|
||||
$this->cardMapper = $cardMapper;
|
||||
$this->notificationHelper = $notificationHelper;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -14,19 +14,21 @@ namespace OCA\Deck\Cron;
|
||||
use OCA\Deck\Service\SessionService;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\BackgroundJob\TimedJob;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use OCP\ILogger;
|
||||
|
||||
class SessionsCleanup extends TimedJob {
|
||||
private $sessionService;
|
||||
private $documentService;
|
||||
private $logger;
|
||||
private $imageService;
|
||||
|
||||
|
||||
public function __construct(
|
||||
ITimeFactory $time,
|
||||
private SessionService $sessionService,
|
||||
private LoggerInterface $logger,
|
||||
) {
|
||||
public function __construct(ITimeFactory $time,
|
||||
SessionService $sessionService,
|
||||
ILogger $logger) {
|
||||
parent::__construct($time);
|
||||
$this->sessionService = $sessionService;
|
||||
$this->logger = $logger;
|
||||
$this->setInterval(SessionService::SESSION_VALID_TIME);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ class Calendar extends ExternalCalendar {
|
||||
private $children;
|
||||
/** @var DeckCalendarBackend */
|
||||
private $backend;
|
||||
/** @var Board */
|
||||
/** @var Board */
|
||||
private $board;
|
||||
|
||||
public function __construct(string $principalUri, string $calendarUri, Board $board, DeckCalendarBackend $backend) {
|
||||
|
||||
@@ -75,7 +75,7 @@ class AclMapper extends DeckMapper implements IPermissionMapper {
|
||||
try {
|
||||
$entity = $this->find($id);
|
||||
return $entity->getBoardId();
|
||||
} catch (DoesNotExistException|MultipleObjectsReturnedException $e) {
|
||||
} catch (DoesNotExistException | MultipleObjectsReturnedException $e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -61,9 +61,9 @@ class AttachmentMapper extends DeckMapper implements IPermissionMapper {
|
||||
public function findByData($cardId, $data) {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->select('*')
|
||||
->from($this->getTableName())
|
||||
->where($qb->expr()->eq('card_id', $qb->createNamedParameter($cardId, IQueryBuilder::PARAM_INT)))
|
||||
->andWhere($qb->expr()->eq('data', $qb->createNamedParameter($data, IQueryBuilder::PARAM_STR)));
|
||||
->from($this->getTableName())
|
||||
->where($qb->expr()->eq('card_id', $qb->createNamedParameter($cardId, IQueryBuilder::PARAM_INT)))
|
||||
->andWhere($qb->expr()->eq('data', $qb->createNamedParameter($data, IQueryBuilder::PARAM_STR)));
|
||||
|
||||
return $this->findEntity($qb);
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ class Card extends RelationalEntity {
|
||||
$matchDate->setTime(0, 0);
|
||||
|
||||
$diff = $today->diff($matchDate);
|
||||
return (int)$diff->format('%R%a'); // Extract days count in interval
|
||||
return (int) $diff->format('%R%a'); // Extract days count in interval
|
||||
}
|
||||
|
||||
public function getCalendarPrefix(): string {
|
||||
|
||||
@@ -410,7 +410,7 @@ class CardMapper extends QBMapper implements IPermissionMapper {
|
||||
foreach ($query->getDuedate() as $duedate) {
|
||||
$dueDateColumn = $this->databaseType === 'sqlite3' ? $qb->createFunction('DATETIME(`c`.`duedate`)') : 'c.duedate';
|
||||
$date = $duedate->getValue();
|
||||
if ($date === '') {
|
||||
if ($date === "") {
|
||||
$qb->andWhere($qb->expr()->isNotNull('c.duedate'));
|
||||
continue;
|
||||
}
|
||||
@@ -461,7 +461,7 @@ class CardMapper extends QBMapper implements IPermissionMapper {
|
||||
foreach ($query->getAssigned() as $index => $assignment) {
|
||||
$qb->innerJoin('c', 'deck_assigned_users', 'au' . $index, $qb->expr()->eq('c.id', 'au' . $index . '.card_id'));
|
||||
$assignedQueryValue = $assignment->getValue();
|
||||
if ($assignedQueryValue === '') {
|
||||
if ($assignedQueryValue === "") {
|
||||
$qb->andWhere($qb->expr()->isNotNull('au' . $index . '.participant'));
|
||||
continue;
|
||||
}
|
||||
@@ -589,7 +589,7 @@ class CardMapper extends QBMapper implements IPermissionMapper {
|
||||
}
|
||||
$this->cache->set('findBoardId:' . $id, $result);
|
||||
}
|
||||
return $result !== false ? (int)$result : null;
|
||||
return $result !== false ? (int) $result : null;
|
||||
}
|
||||
|
||||
public function mapOwner(Card &$card) {
|
||||
|
||||
@@ -10,17 +10,27 @@ use OCA\Deck\Service\DefaultBoardService;
|
||||
use OCA\Deck\Service\PermissionService;
|
||||
use OCP\AppFramework\Middleware;
|
||||
use OCP\IL10N;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use OCP\ILogger;
|
||||
|
||||
class DefaultBoardMiddleware extends Middleware {
|
||||
|
||||
public function __construct(
|
||||
private LoggerInterface $logger,
|
||||
private IL10N $l10n,
|
||||
private DefaultBoardService $defaultBoardService,
|
||||
private PermissionService $permissionService,
|
||||
private ?string $userId,
|
||||
) {
|
||||
/** @var ILogger */
|
||||
private $logger;
|
||||
/** @var IL10N */
|
||||
private $l10n;
|
||||
/** @var DefaultBoardService */
|
||||
private $defaultBoardService;
|
||||
/** @var PermissionService */
|
||||
private $permissionService;
|
||||
/** @var string|null */
|
||||
private $userId;
|
||||
|
||||
public function __construct(ILogger $logger, IL10N $l10n, DefaultBoardService $defaultBoardService, PermissionService $permissionService, $userId) {
|
||||
$this->logger = $logger;
|
||||
$this->l10n = $l10n;
|
||||
$this->defaultBoardService = $defaultBoardService;
|
||||
$this->permissionService = $permissionService;
|
||||
$this->userId = $userId;
|
||||
}
|
||||
|
||||
public function beforeController($controller, $methodName) {
|
||||
@@ -29,7 +39,7 @@ class DefaultBoardMiddleware extends Middleware {
|
||||
$this->defaultBoardService->createDefaultBoard($this->l10n->t('Personal'), $this->userId, '0087C5');
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
$this->logger->error('Could not create default board', ['exception' => $e]);
|
||||
$this->logger->logException($e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,19 +15,28 @@ use OCP\AppFramework\Middleware;
|
||||
use OCP\AppFramework\OCS\OCSException;
|
||||
use OCP\AppFramework\OCSController;
|
||||
use OCP\IConfig;
|
||||
use OCP\ILogger;
|
||||
use OCP\IRequest;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class ExceptionMiddleware extends Middleware {
|
||||
|
||||
/** @var ILogger */
|
||||
private $logger;
|
||||
/** @var IConfig */
|
||||
private $config;
|
||||
/** @var IRequest */
|
||||
private $request;
|
||||
|
||||
/**
|
||||
* SharingMiddleware constructor.
|
||||
*
|
||||
* @param ILogger $logger
|
||||
* @param IConfig $config
|
||||
*/
|
||||
public function __construct(
|
||||
private LoggerInterface $logger,
|
||||
private IConfig $config,
|
||||
private IRequest $request,
|
||||
) {
|
||||
public function __construct(ILogger $logger, IConfig $config, IRequest $request) {
|
||||
$this->logger = $logger;
|
||||
$this->config = $config;
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,7 +69,9 @@ class ExceptionMiddleware extends Middleware {
|
||||
}
|
||||
|
||||
if ($exception instanceof StatusException) {
|
||||
$this->logger->debug($exception->getMessage(), ['exception' => $exception]);
|
||||
if ($this->config->getSystemValue('loglevel', ILogger::WARN) === ILogger::DEBUG) {
|
||||
$this->logger->logException($exception);
|
||||
}
|
||||
|
||||
if ($exception instanceof ConflictException) {
|
||||
return new JSONResponse([
|
||||
@@ -87,9 +98,9 @@ class ExceptionMiddleware extends Middleware {
|
||||
'message' => $exceptionMessage,
|
||||
'requestId' => $this->request->getId(),
|
||||
];
|
||||
$this->logger->error($exception->getMessage(), ['exception' => $exception]);
|
||||
$this->logger->logException($exception);
|
||||
if ($debugMode === true) {
|
||||
$response['exception'] = (array)$exception;
|
||||
$response['exception'] = (array) $exception;
|
||||
}
|
||||
return new JSONResponse($response, 500);
|
||||
}
|
||||
|
||||
@@ -142,11 +142,11 @@ class NotificationHelper {
|
||||
->setUser($userId)
|
||||
->setDateTime(new DateTime())
|
||||
->setObject('card', (string)$card->getId())
|
||||
->setSubject('card-assigned', [
|
||||
$card->getTitle(),
|
||||
$board->getTitle(),
|
||||
$this->currentUser
|
||||
]);
|
||||
->setSubject('card-assigned', [
|
||||
$card->getTitle(),
|
||||
$board->getTitle(),
|
||||
$this->currentUser
|
||||
]);
|
||||
$this->notificationManager->notify($notification);
|
||||
}
|
||||
|
||||
@@ -206,9 +206,9 @@ class NotificationHelper {
|
||||
$notification = $this->notificationManager->createNotification();
|
||||
$notification
|
||||
->setApp('deck')
|
||||
->setUser((string)$mention['id'])
|
||||
->setUser((string) $mention['id'])
|
||||
->setDateTime(new DateTime())
|
||||
->setObject('card', (string)$card->getId())
|
||||
->setObject('card', (string) $card->getId())
|
||||
->setSubject('card-comment-mentioned', [$card->getTitle(), $boardId, $this->currentUser])
|
||||
->setMessage('{message}', ['message' => $comment->getMessage()]);
|
||||
$this->notificationManager->notify($notification);
|
||||
|
||||
@@ -97,7 +97,7 @@ class BoardReferenceProvider implements IReferenceProvider {
|
||||
preg_match('/^' . preg_quote($startIndex, '/') . '(?:\/#!?)?\/board\/([0-9]+)$/', $url, $matches);
|
||||
}
|
||||
if ($matches && count($matches) > 1) {
|
||||
return (int)$matches[1];
|
||||
return (int) $matches[1];
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -106,7 +106,7 @@ class BoardReferenceProvider implements IReferenceProvider {
|
||||
public function getCachePrefix(string $referenceId): string {
|
||||
$boardId = $this->getBoardId($referenceId);
|
||||
if ($boardId !== null) {
|
||||
return (string)$boardId;
|
||||
return (string) $boardId;
|
||||
}
|
||||
|
||||
return $referenceId;
|
||||
|
||||
@@ -111,9 +111,9 @@ class CardReferenceProvider extends ADiscoverableReferenceProvider implements IS
|
||||
if ($ids !== null) {
|
||||
[, $cardId] = $ids;
|
||||
try {
|
||||
$card = $this->cardService->find((int)$cardId)->jsonSerialize();
|
||||
$stack = $this->stackService->find((int)$card['stackId'])->jsonSerialize();
|
||||
$board = $this->boardService->find((int)$stack['boardId'])->jsonSerialize();
|
||||
$card = $this->cardService->find((int) $cardId)->jsonSerialize();
|
||||
$stack = $this->stackService->find((int) $card['stackId'])->jsonSerialize();
|
||||
$board = $this->boardService->find((int) $stack['boardId'])->jsonSerialize();
|
||||
} catch (NoPermissionException $e) {
|
||||
// Skip throwing if user has no permissions
|
||||
return null;
|
||||
|
||||
@@ -73,7 +73,7 @@ class CommentReferenceProvider implements IReferenceProvider {
|
||||
try {
|
||||
$card = $this->cardService->find($cardId)->jsonSerialize();
|
||||
$board = $this->boardService->find($boardId)->jsonSerialize();
|
||||
$stack = $this->stackService->find((int)$card['stackId'])->jsonSerialize();
|
||||
$stack = $this->stackService->find((int) $card['stackId'])->jsonSerialize();
|
||||
} catch (NoPermissionException $e) {
|
||||
// Skip throwing if user has no permissions
|
||||
return null;
|
||||
@@ -162,9 +162,9 @@ class CommentReferenceProvider implements IReferenceProvider {
|
||||
}
|
||||
if ($matches && count($matches) > 3) {
|
||||
return [
|
||||
(int)$matches[1],
|
||||
(int)$matches[2],
|
||||
(int)$matches[3],
|
||||
(int) $matches[1],
|
||||
(int) $matches[2],
|
||||
(int) $matches[3],
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -17,22 +17,26 @@ use OCP\Comments\IComment;
|
||||
use OCP\Comments\ICommentsManager;
|
||||
use OCP\Comments\MessageTooLongException;
|
||||
use OCP\Comments\NotFoundException as CommentNotFoundException;
|
||||
use OCP\ILogger;
|
||||
use OCP\IUserManager;
|
||||
use OutOfBoundsException;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
use function is_numeric;
|
||||
|
||||
class CommentService {
|
||||
private ICommentsManager $commentsManager;
|
||||
private IUserManager $userManager;
|
||||
private CardMapper $cardMapper;
|
||||
private PermissionService $permissionService;
|
||||
private ILogger $logger;
|
||||
private ?string $userId;
|
||||
|
||||
public function __construct(
|
||||
private ICommentsManager $commentsManager,
|
||||
private PermissionService $permissionService,
|
||||
private CardMapper $cardMapper,
|
||||
private IUserManager $userManager,
|
||||
private LoggerInterface $logger,
|
||||
private ?string $userId,
|
||||
) {
|
||||
public function __construct(ICommentsManager $commentsManager, PermissionService $permissionService, CardMapper $cardMapper, IUserManager $userManager, ILogger $logger, ?string $userId) {
|
||||
$this->commentsManager = $commentsManager;
|
||||
$this->permissionService = $permissionService;
|
||||
$this->cardMapper = $cardMapper;
|
||||
$this->userManager = $userManager;
|
||||
$this->logger = $logger;
|
||||
$this->userId = $userId;
|
||||
}
|
||||
|
||||
public function list(string $cardId, int $limit = 20, int $offset = 0): DataResponse {
|
||||
@@ -65,8 +69,8 @@ class CommentService {
|
||||
private function get(int $cardId, int $commentId): IComment {
|
||||
$this->permissionService->checkPermission($this->cardMapper, $cardId, Acl::PERMISSION_READ);
|
||||
try {
|
||||
$comment = $this->commentsManager->get((string)$commentId);
|
||||
if ($comment->getObjectType() !== Application::COMMENT_ENTITY_TYPE || (int)$comment->getObjectId() !== $cardId) {
|
||||
$comment = $this->commentsManager->get((string) $commentId);
|
||||
if ($comment->getObjectType() !== Application::COMMENT_ENTITY_TYPE || (int) $comment->getObjectId() !== $cardId) {
|
||||
throw new CommentNotFoundException();
|
||||
}
|
||||
} catch (CommentNotFoundException $e) {
|
||||
@@ -134,7 +138,7 @@ class CommentService {
|
||||
if (!is_numeric($commentId)) {
|
||||
throw new BadRequestException('A valid comment id must be provided');
|
||||
}
|
||||
$comment = $this->get((int)$cardId, (int)$commentId);
|
||||
$comment = $this->get((int) $cardId, (int) $commentId);
|
||||
if ($comment->getActorType() !== 'users' || $comment->getActorId() !== $this->userId) {
|
||||
throw new NoPermissionException('Only authors are allowed to edit their comment.');
|
||||
}
|
||||
@@ -183,8 +187,8 @@ class CommentService {
|
||||
try {
|
||||
$displayName = $this->commentsManager->resolveDisplayName($mention['type'], $mention['id']);
|
||||
} catch (OutOfBoundsException $e) {
|
||||
$this->logger->warning('Mention type not registered, can not resolve display name.', ['exception' => $e, 'mention_type' => $mention['type']]);
|
||||
// No display name, upon client's discretion what to display.
|
||||
$this->logger->logException($e);
|
||||
// No displayname, upon client's discretion what to display.
|
||||
$displayName = '';
|
||||
}
|
||||
|
||||
|
||||
@@ -20,21 +20,37 @@ use OCP\Files\SimpleFS\ISimpleFile;
|
||||
use OCP\Files\SimpleFS\ISimpleFolder;
|
||||
use OCP\IConfig;
|
||||
use OCP\IL10N;
|
||||
use OCP\ILogger;
|
||||
use OCP\IRequest;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class FileService implements IAttachmentService {
|
||||
private $l10n;
|
||||
private $appData;
|
||||
private $request;
|
||||
private $logger;
|
||||
private $rootFolder;
|
||||
private $config;
|
||||
private $attachmentMapper;
|
||||
private $mimeTypeDetector;
|
||||
|
||||
public function __construct(
|
||||
private IL10N $l10n,
|
||||
private IAppData $appData,
|
||||
private IRequest $request,
|
||||
private LoggerInterface $logger,
|
||||
private IRootFolder $rootFolder,
|
||||
private IConfig $config,
|
||||
private AttachmentMapper $attachmentMapper,
|
||||
private IMimeTypeDetector $mimeTypeDetector
|
||||
IL10N $l10n,
|
||||
IAppData $appData,
|
||||
IRequest $request,
|
||||
ILogger $logger,
|
||||
IRootFolder $rootFolder,
|
||||
IConfig $config,
|
||||
AttachmentMapper $attachmentMapper,
|
||||
IMimeTypeDetector $mimeTypeDetector
|
||||
) {
|
||||
$this->l10n = $l10n;
|
||||
$this->appData = $appData;
|
||||
$this->request = $request;
|
||||
$this->logger = $logger;
|
||||
$this->rootFolder = $rootFolder;
|
||||
$this->config = $config;
|
||||
$this->attachmentMapper = $attachmentMapper;
|
||||
$this->mimeTypeDetector = $mimeTypeDetector;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -177,7 +193,6 @@ class FileService implements IAttachmentService {
|
||||
/**
|
||||
* Workaround until ISimpleFile can be fetched as a resource
|
||||
*
|
||||
* @return \OCP\Files\File
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function getFileFromRootFolder(Attachment $attachment) {
|
||||
|
||||
@@ -404,7 +404,7 @@ class BoardImportService {
|
||||
* @return void
|
||||
*/
|
||||
public function setConfig(string $configName, $value): void {
|
||||
if (empty((array)$this->config)) {
|
||||
if (empty((array) $this->config)) {
|
||||
$this->setConfigInstance(new \stdClass);
|
||||
}
|
||||
$this->config->$configName = $value;
|
||||
|
||||
@@ -51,7 +51,7 @@ class DeckJsonService extends ABoardImportService {
|
||||
if (!is_string($nextcloudUid) && !is_numeric($nextcloudUid)) {
|
||||
throw new \LogicException('User on setting uidRelation is invalid');
|
||||
}
|
||||
$nextcloudUid = (string)$nextcloudUid;
|
||||
$nextcloudUid = (string) $nextcloudUid;
|
||||
$this->getImportService()->getConfig('uidRelation')->$exportUid = $this->userManager->get($nextcloudUid);
|
||||
if (!$this->getImportService()->getConfig('uidRelation')->$exportUid) {
|
||||
throw new \LogicException('User on setting uidRelation not found: ' . $nextcloudUid);
|
||||
@@ -106,7 +106,7 @@ class DeckJsonService extends ABoardImportService {
|
||||
public function getComments(): array {
|
||||
$comments = [];
|
||||
foreach ($this->tmpCards as $sourceCard) {
|
||||
if (!property_exists($sourceCard, 'comments')) {
|
||||
if (!property_exists($sourceCard, "comments")) {
|
||||
continue;
|
||||
}
|
||||
$commentsOriginal = $sourceCard->comments;
|
||||
|
||||
@@ -71,7 +71,7 @@ class TrelloJsonService extends ABoardImportService {
|
||||
if (!is_string($nextcloudUid) && !is_numeric($nextcloudUid)) {
|
||||
throw new \LogicException('User on setting uidRelation is invalid');
|
||||
}
|
||||
$nextcloudUid = (string)$nextcloudUid;
|
||||
$nextcloudUid = (string) $nextcloudUid;
|
||||
$this->getImportService()->getConfig('uidRelation')->$trelloUid = $this->userManager->get($nextcloudUid);
|
||||
if (!$this->getImportService()->getConfig('uidRelation')->$trelloUid) {
|
||||
throw new \LogicException('User on setting uidRelation not found: ' . $nextcloudUid);
|
||||
@@ -141,7 +141,7 @@ class TrelloJsonService extends ABoardImportService {
|
||||
$message = $this->l10n->t(
|
||||
"This comment has more than %s characters.\n" .
|
||||
"Added as an attachment to the card with name %s.\n" .
|
||||
'Accessible on URL: %s.',
|
||||
"Accessible on URL: %s.",
|
||||
[
|
||||
IComment::MAX_MESSAGE_LENGTH,
|
||||
'comment_' . $commentId . '.md',
|
||||
|
||||
@@ -143,7 +143,7 @@ class PermissionService {
|
||||
try {
|
||||
$board = $this->getBoard($boardId);
|
||||
return $userId === $board->getOwner();
|
||||
} catch (DoesNotExistException|MultipleObjectsReturnedException $e) {
|
||||
} catch (DoesNotExistException | MultipleObjectsReturnedException $e) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -205,8 +205,8 @@ class PermissionService {
|
||||
*/
|
||||
public function findUsers($boardId, $refresh = false) {
|
||||
// cache users of a board so we don't query them for every cards
|
||||
if (array_key_exists((string)$boardId, $this->users) && !$refresh) {
|
||||
return $this->users[(string)$boardId];
|
||||
if (array_key_exists((string) $boardId, $this->users) && !$refresh) {
|
||||
return $this->users[(string) $boardId];
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -269,8 +269,8 @@ class PermissionService {
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->users[(string)$boardId] = $users;
|
||||
return $this->users[(string)$boardId];
|
||||
$this->users[(string) $boardId] = $users;
|
||||
return $this->users[(string) $boardId];
|
||||
}
|
||||
|
||||
public function canCreate() {
|
||||
|
||||
@@ -110,7 +110,7 @@ class DeckShareProvider implements \OCP\Share\IShareProvider {
|
||||
try {
|
||||
$board = $this->boardMapper->find($boardId);
|
||||
$valid = $valid && !$board->getArchived();
|
||||
} catch (DoesNotExistException|MultipleObjectsReturnedException $e) {
|
||||
} catch (DoesNotExistException | MultipleObjectsReturnedException $e) {
|
||||
$valid = false;
|
||||
}
|
||||
|
||||
@@ -966,8 +966,8 @@ class DeckShareProvider implements \OCP\Share\IShareProvider {
|
||||
protected function filterSharesOfUser(array $shares): array {
|
||||
// Deck shares when the user has a share exception
|
||||
foreach ($shares as $id => $share) {
|
||||
$type = (int)$share['share_type'];
|
||||
$permissions = (int)$share['permissions'];
|
||||
$type = (int) $share['share_type'];
|
||||
$permissions = (int) $share['permissions'];
|
||||
|
||||
if ($type === self::SHARE_TYPE_DECK_USER) {
|
||||
unset($shares[$share['parent']]);
|
||||
|
||||
@@ -45,7 +45,7 @@ abstract class BaseValidator {
|
||||
} else {
|
||||
if (!$this->{$rule}($value)) {
|
||||
throw new BadRequestException(
|
||||
$field . ' must be provided and must be '. str_replace('_', ' ', $rule));
|
||||
$field . ' must be provided and must be '. str_replace("_", " ", $rule));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -111,7 +111,7 @@ abstract class BaseValidator {
|
||||
*/
|
||||
private function max($value, $limit): bool {
|
||||
if (!$limit || !is_numeric($limit)) {
|
||||
throw new Exception('Validation rule max requires at least 1 parameter. ' . json_encode($limit));
|
||||
throw new Exception("Validation rule max requires at least 1 parameter. " . json_encode($limit));
|
||||
}
|
||||
return $this->getSize($value) <= $limit;
|
||||
}
|
||||
@@ -121,7 +121,7 @@ abstract class BaseValidator {
|
||||
*/
|
||||
private function min($value, $limit): bool {
|
||||
if (!$limit || !is_numeric($limit)) {
|
||||
throw new Exception('Validation rule max requires at least 1 parameter.');
|
||||
throw new Exception("Validation rule max requires at least 1 parameter.");
|
||||
}
|
||||
return $this->getSize($value) >= $limit;
|
||||
}
|
||||
@@ -129,7 +129,7 @@ abstract class BaseValidator {
|
||||
/**
|
||||
* Get the size of an attribute.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param mixed $value
|
||||
* @return int
|
||||
*/
|
||||
protected function getSize($value): int {
|
||||
@@ -158,6 +158,6 @@ abstract class BaseValidator {
|
||||
: $field . ' must be at least '. $parameter . ' characters long ';
|
||||
}
|
||||
|
||||
return $field . ' must be provided and must be '. str_replace('_', ' ', $rule);
|
||||
return $field . ' must be provided and must be '. str_replace("_", " ", $rule);
|
||||
}
|
||||
}
|
||||
|
||||
232
package-lock.json
generated
232
package-lock.json
generated
@@ -1,20 +1,20 @@
|
||||
{
|
||||
"name": "deck",
|
||||
"version": "2.0.0-dev.0",
|
||||
"version": "1.14.0-beta.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "deck",
|
||||
"version": "2.0.0-dev.0",
|
||||
"version": "1.14.0-beta.1",
|
||||
"license": "agpl",
|
||||
"dependencies": {
|
||||
"@babel/polyfill": "^7.12.1",
|
||||
"@babel/runtime": "^7.25.6",
|
||||
"@nextcloud/auth": "^2.4.0",
|
||||
"@babel/runtime": "^7.24.8",
|
||||
"@nextcloud/auth": "^2.3.0",
|
||||
"@nextcloud/axios": "^2.5.0",
|
||||
"@nextcloud/capabilities": "^1.2.0",
|
||||
"@nextcloud/dialogs": "^6.0.0",
|
||||
"@nextcloud/dialogs": "^5.3.5",
|
||||
"@nextcloud/event-bus": "^3.3.1",
|
||||
"@nextcloud/files": "^3.8.0",
|
||||
"@nextcloud/initial-state": "^2.2.0",
|
||||
@@ -22,9 +22,9 @@
|
||||
"@nextcloud/moment": "^1.3.1",
|
||||
"@nextcloud/notify_push": "^1.3.0",
|
||||
"@nextcloud/router": "^3.0.1",
|
||||
"@nextcloud/vue": "^8.17.1",
|
||||
"@nextcloud/vue": "^8.16.0",
|
||||
"blueimp-md5": "^2.19.0",
|
||||
"chroma-js": "^3.0.0",
|
||||
"chroma-js": "^2.6.0",
|
||||
"dompurify": "^3.1.6",
|
||||
"lodash": "^4.17.21",
|
||||
"markdown-it": "^14.1.0",
|
||||
@@ -52,11 +52,11 @@
|
||||
"@nextcloud/eslint-config": "^8.4.1",
|
||||
"@nextcloud/stylelint-config": "^3.0.1",
|
||||
"@nextcloud/webpack-vue-config": "^6.0.0",
|
||||
"@relative-ci/agent": "^4.2.11",
|
||||
"@relative-ci/agent": "^4.2.10",
|
||||
"@vue/test-utils": "^2.4.6",
|
||||
"@vue/vue2-jest": "^29.2.6",
|
||||
"cypress": "^13.14.1",
|
||||
"eslint-plugin-cypress": "^3.5.0",
|
||||
"cypress": "^13.13.2",
|
||||
"eslint-plugin-cypress": "^3.3.0",
|
||||
"eslint-webpack-plugin": "^4.2.0",
|
||||
"jest": "^29.7.0",
|
||||
"jest-serializer-vue": "^3.1.0",
|
||||
@@ -1917,9 +1917,9 @@
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@babel/runtime": {
|
||||
"version": "7.25.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz",
|
||||
"integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==",
|
||||
"version": "7.25.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.4.tgz",
|
||||
"integrity": "sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w==",
|
||||
"dependencies": {
|
||||
"regenerator-runtime": "^0.14.0"
|
||||
},
|
||||
@@ -3340,14 +3340,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/source-map": {
|
||||
"version": "0.3.6",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz",
|
||||
"integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==",
|
||||
"version": "0.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz",
|
||||
"integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/gen-mapping": "^0.3.5",
|
||||
"@jridgewell/trace-mapping": "^0.3.25"
|
||||
"@jridgewell/gen-mapping": "^0.3.0",
|
||||
"@jridgewell/trace-mapping": "^0.3.9"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/sourcemap-codec": {
|
||||
@@ -3526,9 +3526,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@nextcloud/dialogs": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@nextcloud/dialogs/-/dialogs-6.0.0.tgz",
|
||||
"integrity": "sha512-Yoye/BezFN/hQCic+OHNPSESNI3k7D85YQJU1fW4s/yMi+P6VVNLixp4lbQ7xHF+po5lXZbJhultrOyoNhqaGw==",
|
||||
"version": "5.3.7",
|
||||
"resolved": "https://registry.npmjs.org/@nextcloud/dialogs/-/dialogs-5.3.7.tgz",
|
||||
"integrity": "sha512-//pRF2GJNhW3VbVzSoE97J+DR9nZ/+IkzOzgKKDdMr65JYYMAdOs9Iew4nMf+OruDgZanGyXrfubSMVNI+1svQ==",
|
||||
"dependencies": {
|
||||
"@mdi/js": "^7.4.47",
|
||||
"@nextcloud/auth": "^2.3.0",
|
||||
@@ -3552,7 +3552,7 @@
|
||||
"npm": "^10.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@nextcloud/vue": "^8.16.0",
|
||||
"@nextcloud/vue": "^8.9.1",
|
||||
"vue": "^2.7.16"
|
||||
}
|
||||
},
|
||||
@@ -4420,10 +4420,21 @@
|
||||
"@types/json-schema": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/eslint-scope": {
|
||||
"version": "3.7.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz",
|
||||
"integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/eslint": "*",
|
||||
"@types/estree": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/estree": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
|
||||
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw=="
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz",
|
||||
"integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA=="
|
||||
},
|
||||
"node_modules/@types/express": {
|
||||
"version": "4.17.17",
|
||||
@@ -5235,9 +5246,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@webassemblyjs/ast": {
|
||||
"version": "1.12.1",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz",
|
||||
"integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==",
|
||||
"version": "1.11.6",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz",
|
||||
"integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
@@ -5260,9 +5271,9 @@
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@webassemblyjs/helper-buffer": {
|
||||
"version": "1.12.1",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz",
|
||||
"integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==",
|
||||
"version": "1.11.6",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz",
|
||||
"integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==",
|
||||
"dev": true,
|
||||
"peer": true
|
||||
},
|
||||
@@ -5286,16 +5297,16 @@
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@webassemblyjs/helper-wasm-section": {
|
||||
"version": "1.12.1",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz",
|
||||
"integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==",
|
||||
"version": "1.11.6",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz",
|
||||
"integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@webassemblyjs/ast": "1.12.1",
|
||||
"@webassemblyjs/helper-buffer": "1.12.1",
|
||||
"@webassemblyjs/ast": "1.11.6",
|
||||
"@webassemblyjs/helper-buffer": "1.11.6",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.11.6",
|
||||
"@webassemblyjs/wasm-gen": "1.12.1"
|
||||
"@webassemblyjs/wasm-gen": "1.11.6"
|
||||
}
|
||||
},
|
||||
"node_modules/@webassemblyjs/ieee754": {
|
||||
@@ -5326,30 +5337,30 @@
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@webassemblyjs/wasm-edit": {
|
||||
"version": "1.12.1",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz",
|
||||
"integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==",
|
||||
"version": "1.11.6",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz",
|
||||
"integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@webassemblyjs/ast": "1.12.1",
|
||||
"@webassemblyjs/helper-buffer": "1.12.1",
|
||||
"@webassemblyjs/ast": "1.11.6",
|
||||
"@webassemblyjs/helper-buffer": "1.11.6",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.11.6",
|
||||
"@webassemblyjs/helper-wasm-section": "1.12.1",
|
||||
"@webassemblyjs/wasm-gen": "1.12.1",
|
||||
"@webassemblyjs/wasm-opt": "1.12.1",
|
||||
"@webassemblyjs/wasm-parser": "1.12.1",
|
||||
"@webassemblyjs/wast-printer": "1.12.1"
|
||||
"@webassemblyjs/helper-wasm-section": "1.11.6",
|
||||
"@webassemblyjs/wasm-gen": "1.11.6",
|
||||
"@webassemblyjs/wasm-opt": "1.11.6",
|
||||
"@webassemblyjs/wasm-parser": "1.11.6",
|
||||
"@webassemblyjs/wast-printer": "1.11.6"
|
||||
}
|
||||
},
|
||||
"node_modules/@webassemblyjs/wasm-gen": {
|
||||
"version": "1.12.1",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz",
|
||||
"integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==",
|
||||
"version": "1.11.6",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz",
|
||||
"integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@webassemblyjs/ast": "1.12.1",
|
||||
"@webassemblyjs/ast": "1.11.6",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.11.6",
|
||||
"@webassemblyjs/ieee754": "1.11.6",
|
||||
"@webassemblyjs/leb128": "1.11.6",
|
||||
@@ -5357,26 +5368,26 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@webassemblyjs/wasm-opt": {
|
||||
"version": "1.12.1",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz",
|
||||
"integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==",
|
||||
"version": "1.11.6",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz",
|
||||
"integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@webassemblyjs/ast": "1.12.1",
|
||||
"@webassemblyjs/helper-buffer": "1.12.1",
|
||||
"@webassemblyjs/wasm-gen": "1.12.1",
|
||||
"@webassemblyjs/wasm-parser": "1.12.1"
|
||||
"@webassemblyjs/ast": "1.11.6",
|
||||
"@webassemblyjs/helper-buffer": "1.11.6",
|
||||
"@webassemblyjs/wasm-gen": "1.11.6",
|
||||
"@webassemblyjs/wasm-parser": "1.11.6"
|
||||
}
|
||||
},
|
||||
"node_modules/@webassemblyjs/wasm-parser": {
|
||||
"version": "1.12.1",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz",
|
||||
"integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==",
|
||||
"version": "1.11.6",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz",
|
||||
"integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@webassemblyjs/ast": "1.12.1",
|
||||
"@webassemblyjs/ast": "1.11.6",
|
||||
"@webassemblyjs/helper-api-error": "1.11.6",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.11.6",
|
||||
"@webassemblyjs/ieee754": "1.11.6",
|
||||
@@ -5385,13 +5396,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@webassemblyjs/wast-printer": {
|
||||
"version": "1.12.1",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz",
|
||||
"integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==",
|
||||
"version": "1.11.6",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz",
|
||||
"integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@webassemblyjs/ast": "1.12.1",
|
||||
"@webassemblyjs/ast": "1.11.6",
|
||||
"@xtuc/long": "4.2.2"
|
||||
}
|
||||
},
|
||||
@@ -5505,10 +5516,10 @@
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/acorn-import-attributes": {
|
||||
"version": "1.9.5",
|
||||
"resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz",
|
||||
"integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==",
|
||||
"node_modules/acorn-import-assertions": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz",
|
||||
"integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"peerDependencies": {
|
||||
@@ -5952,9 +5963,10 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.7.4",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz",
|
||||
"integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==",
|
||||
"version": "1.7.5",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.5.tgz",
|
||||
"integrity": "sha512-fZu86yCo+svH3uqJ/yTdQ0QHpQu5oL+/QE+QPSv6BZSkDAoky9vytxp7u5qk83OJFS3kEBcesWni9WTZAv3tSw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.6",
|
||||
"form-data": "^4.0.0",
|
||||
@@ -6888,9 +6900,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/chroma-js": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-3.0.0.tgz",
|
||||
"integrity": "sha512-ZFn4qxtZTvRJ7XatOLgaHGJYN10LoS6T0EMsu7IVayFG5+b6Yw8wCGQL5qLgo4B+wrRZ9niCrozOQ4a584bvaA=="
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.6.0.tgz",
|
||||
"integrity": "sha512-BLHvCB9s8Z1EV4ethr6xnkl/P2YRFOGqfgvuMG/MyCbZPrTA+NeiByY6XvgF0zP4/2deU2CXnWyMa3zu1LqQ3A=="
|
||||
},
|
||||
"node_modules/chrome-trace-event": {
|
||||
"version": "1.0.3",
|
||||
@@ -8483,6 +8495,7 @@
|
||||
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.7.tgz",
|
||||
"integrity": "sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"bn.js": "^4.11.9",
|
||||
@@ -8571,9 +8584,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/enhanced-resolve": {
|
||||
"version": "5.17.1",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz",
|
||||
"integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==",
|
||||
"version": "5.15.0",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz",
|
||||
"integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
@@ -10814,9 +10827,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/graceful-fs": {
|
||||
"version": "4.2.11",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
|
||||
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
|
||||
"version": "4.2.9",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz",
|
||||
"integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/graphemer": {
|
||||
@@ -17942,9 +17955,9 @@
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/serialize-javascript": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
|
||||
"integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz",
|
||||
"integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
@@ -19192,9 +19205,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/terser": {
|
||||
"version": "5.31.6",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.31.6.tgz",
|
||||
"integrity": "sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==",
|
||||
"version": "5.19.2",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.19.2.tgz",
|
||||
"integrity": "sha512-qC5+dmecKJA4cpYxRa5aVkKehYsQKc+AHeKl0Oe62aYjBL8ZA33tTljktDHJSaxxMnbI5ZYw+o/S2DxxLu8OfA==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
@@ -19211,17 +19224,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/terser-webpack-plugin": {
|
||||
"version": "5.3.10",
|
||||
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz",
|
||||
"integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==",
|
||||
"version": "5.3.9",
|
||||
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz",
|
||||
"integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/trace-mapping": "^0.3.20",
|
||||
"@jridgewell/trace-mapping": "^0.3.17",
|
||||
"jest-worker": "^27.4.5",
|
||||
"schema-utils": "^3.1.1",
|
||||
"serialize-javascript": "^6.0.1",
|
||||
"terser": "^5.26.0"
|
||||
"terser": "^5.16.8"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.13.0"
|
||||
@@ -20513,9 +20526,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/watchpack": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz",
|
||||
"integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==",
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
|
||||
"integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
@@ -20628,34 +20641,35 @@
|
||||
}
|
||||
},
|
||||
"node_modules/webpack": {
|
||||
"version": "5.94.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz",
|
||||
"integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==",
|
||||
"version": "5.88.2",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz",
|
||||
"integrity": "sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/estree": "^1.0.5",
|
||||
"@webassemblyjs/ast": "^1.12.1",
|
||||
"@webassemblyjs/wasm-edit": "^1.12.1",
|
||||
"@webassemblyjs/wasm-parser": "^1.12.1",
|
||||
"@types/eslint-scope": "^3.7.3",
|
||||
"@types/estree": "^1.0.0",
|
||||
"@webassemblyjs/ast": "^1.11.5",
|
||||
"@webassemblyjs/wasm-edit": "^1.11.5",
|
||||
"@webassemblyjs/wasm-parser": "^1.11.5",
|
||||
"acorn": "^8.7.1",
|
||||
"acorn-import-attributes": "^1.9.5",
|
||||
"browserslist": "^4.21.10",
|
||||
"acorn-import-assertions": "^1.9.0",
|
||||
"browserslist": "^4.14.5",
|
||||
"chrome-trace-event": "^1.0.2",
|
||||
"enhanced-resolve": "^5.17.1",
|
||||
"enhanced-resolve": "^5.15.0",
|
||||
"es-module-lexer": "^1.2.1",
|
||||
"eslint-scope": "5.1.1",
|
||||
"events": "^3.2.0",
|
||||
"glob-to-regexp": "^0.4.1",
|
||||
"graceful-fs": "^4.2.11",
|
||||
"graceful-fs": "^4.2.9",
|
||||
"json-parse-even-better-errors": "^2.3.1",
|
||||
"loader-runner": "^4.2.0",
|
||||
"mime-types": "^2.1.27",
|
||||
"neo-async": "^2.6.2",
|
||||
"schema-utils": "^3.2.0",
|
||||
"tapable": "^2.1.1",
|
||||
"terser-webpack-plugin": "^5.3.10",
|
||||
"watchpack": "^2.4.1",
|
||||
"terser-webpack-plugin": "^5.3.7",
|
||||
"watchpack": "^2.4.0",
|
||||
"webpack-sources": "^3.2.3"
|
||||
},
|
||||
"bin": {
|
||||
|
||||
20
package.json
20
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "deck",
|
||||
"description": "",
|
||||
"version": "2.0.0-dev.0",
|
||||
"version": "1.14.0-beta.2",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Julius Härtl",
|
||||
@@ -31,11 +31,11 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/polyfill": "^7.12.1",
|
||||
"@babel/runtime": "^7.25.6",
|
||||
"@nextcloud/auth": "^2.4.0",
|
||||
"@babel/runtime": "^7.24.8",
|
||||
"@nextcloud/auth": "^2.3.0",
|
||||
"@nextcloud/axios": "^2.5.0",
|
||||
"@nextcloud/capabilities": "^1.2.0",
|
||||
"@nextcloud/dialogs": "^6.0.0",
|
||||
"@nextcloud/dialogs": "^5.3.5",
|
||||
"@nextcloud/event-bus": "^3.3.1",
|
||||
"@nextcloud/files": "^3.8.0",
|
||||
"@nextcloud/initial-state": "^2.2.0",
|
||||
@@ -43,9 +43,9 @@
|
||||
"@nextcloud/moment": "^1.3.1",
|
||||
"@nextcloud/notify_push": "^1.3.0",
|
||||
"@nextcloud/router": "^3.0.1",
|
||||
"@nextcloud/vue": "^8.17.1",
|
||||
"@nextcloud/vue": "^8.16.0",
|
||||
"blueimp-md5": "^2.19.0",
|
||||
"chroma-js": "^3.0.0",
|
||||
"chroma-js": "^2.6.0",
|
||||
"dompurify": "^3.1.6",
|
||||
"lodash": "^4.17.21",
|
||||
"markdown-it": "^14.1.0",
|
||||
@@ -80,11 +80,11 @@
|
||||
"@nextcloud/eslint-config": "^8.4.1",
|
||||
"@nextcloud/stylelint-config": "^3.0.1",
|
||||
"@nextcloud/webpack-vue-config": "^6.0.0",
|
||||
"@relative-ci/agent": "^4.2.11",
|
||||
"@relative-ci/agent": "^4.2.10",
|
||||
"@vue/test-utils": "^2.4.6",
|
||||
"@vue/vue2-jest": "^29.2.6",
|
||||
"cypress": "^13.14.1",
|
||||
"eslint-plugin-cypress": "^3.5.0",
|
||||
"cypress": "^13.13.2",
|
||||
"eslint-plugin-cypress": "^3.3.0",
|
||||
"eslint-webpack-plugin": "^4.2.0",
|
||||
"jest": "^29.7.0",
|
||||
"jest-serializer-vue": "^3.1.0",
|
||||
@@ -107,4 +107,4 @@
|
||||
"<rootDir>/node_modules/jest-serializer-vue"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,13 +6,12 @@
|
||||
<template>
|
||||
<NcContent app-name="deck" :class="{ 'nav-hidden': !navShown, 'sidebar-hidden': !sidebarRouterView }">
|
||||
<AppNavigation />
|
||||
<NcAppContent :allow-swipe-navigation="false">
|
||||
<NcAppContent>
|
||||
<router-view />
|
||||
</NcAppContent>
|
||||
|
||||
<div v-if="$route.params.id || $route.params.cardId">
|
||||
<NcModal v-if="cardDetailsInModal && $route.params.cardId"
|
||||
:name="t('deck', 'Card details')"
|
||||
:clear-view-delay="0"
|
||||
:close-button-contained="true"
|
||||
size="large"
|
||||
@@ -33,7 +32,7 @@
|
||||
import { mapState } from 'vuex'
|
||||
import AppNavigation from './components/navigation/AppNavigation.vue'
|
||||
import KeyboardShortcuts from './components/KeyboardShortcuts.vue'
|
||||
import { NcModal, NcContent, NcAppContent, isMobile } from '@nextcloud/vue'
|
||||
import { NcModal, NcContent, NcAppContent } from '@nextcloud/vue'
|
||||
import { BoardApi } from './services/BoardApi.js'
|
||||
import { emit, subscribe } from '@nextcloud/event-bus'
|
||||
import { loadState } from '@nextcloud/initial-state'
|
||||
@@ -51,7 +50,6 @@ export default {
|
||||
NcAppContent,
|
||||
KeyboardShortcuts,
|
||||
},
|
||||
mixins: [isMobile],
|
||||
provide() {
|
||||
return {
|
||||
boardApi,
|
||||
@@ -108,7 +106,7 @@ export default {
|
||||
},
|
||||
mounted() {
|
||||
// Set navigation to initial state and update in case it gets toggled
|
||||
emit('toggle-navigation', { open: !this.isMobile && this.navShown, _initial: true })
|
||||
emit('toggle-navigation', { open: this.navShown, _initial: true })
|
||||
this.$nextTick(() => {
|
||||
subscribe('navigation-toggled', (navState) => {
|
||||
this.$store.dispatch('toggleNav', navState.open)
|
||||
|
||||
@@ -13,16 +13,16 @@
|
||||
:disabled="loading"
|
||||
label="title"
|
||||
@option:selected="fetchCardsFromBoard">
|
||||
<template #selected-option="props">
|
||||
<template slot="singleLabel" slot-scope="props">
|
||||
<span>
|
||||
<span :style="{ 'backgroundColor': '#' + props.color }" class="board-bullet" />
|
||||
<span>{{ props.title }}</span>
|
||||
<span :style="{ 'backgroundColor': '#' + props.option.color }" class="board-bullet" />
|
||||
<span>{{ props.option.title }}</span>
|
||||
</span>
|
||||
</template>
|
||||
<template #option="props">
|
||||
<template slot="option" slot-scope="props">
|
||||
<span>
|
||||
<span :style="{ 'backgroundColor': '#' + props.color }" class="board-bullet" />
|
||||
<span>{{ props.title }}</span>
|
||||
<span :style="{ 'backgroundColor': '#' + props.option.color }" class="board-bullet" />
|
||||
<span>{{ props.option.title }}</span>
|
||||
</span>
|
||||
</template>
|
||||
</NcSelect>
|
||||
|
||||
@@ -544,7 +544,7 @@ export default {
|
||||
.filter--item {
|
||||
input + label {
|
||||
display: block;
|
||||
padding: var(--default-grid-baseline) 0;
|
||||
padding: 6px 0;
|
||||
.avatardiv {
|
||||
vertical-align: middle;
|
||||
margin-bottom: 2px;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div class="board-wrapper" :tabindex="-1" @touchend="fixActionRestriction">
|
||||
<div class="board-wrapper" :tabindex="-1">
|
||||
<Controls :board="board" />
|
||||
|
||||
<transition name="fade" mode="out-in">
|
||||
@@ -22,27 +22,23 @@
|
||||
<template #icon>
|
||||
<DeckIcon />
|
||||
</template>
|
||||
<template #name>
|
||||
<template #title>
|
||||
{{ t('deck', 'No lists available') }}
|
||||
</template>
|
||||
<template v-if="canManage" #action>
|
||||
{{ t('deck', 'Create a new list to add cards to this board') }}
|
||||
<form @submit.prevent="addNewStack()">
|
||||
<NcTextField ref="newStackInput"
|
||||
:disable="loading"
|
||||
:value.sync="newStackTitle"
|
||||
<input id="new-stack-input-main"
|
||||
v-model="newStackTitle"
|
||||
v-focus
|
||||
type="text"
|
||||
class="no-close"
|
||||
:placeholder="t('deck', 'List name')"
|
||||
type="text" />
|
||||
<NcButton type="secondary"
|
||||
native-type="submit"
|
||||
:disabled="loading"
|
||||
:title="t('deck', 'Add list')">
|
||||
<template #icon>
|
||||
<CheckIcon v-if="!loading" :size="20" />
|
||||
<NcLoadingIcon v-else :size="20" />
|
||||
</template>
|
||||
{{ t('deck', 'Add list') }}
|
||||
</NcButton>
|
||||
required>
|
||||
<input title="t('deck', 'Add list')"
|
||||
class="icon-confirm"
|
||||
type="submit"
|
||||
value="">
|
||||
</form>
|
||||
</template>
|
||||
</NcEmptyContent>
|
||||
@@ -86,9 +82,8 @@ import { Container, Draggable } from 'vue-smooth-dnd'
|
||||
import { mapState, mapGetters } from 'vuex'
|
||||
import Controls from '../Controls.vue'
|
||||
import DeckIcon from '../icons/DeckIcon.vue'
|
||||
import CheckIcon from 'vue-material-design-icons/Check.vue'
|
||||
import Stack from './Stack.vue'
|
||||
import { NcEmptyContent, NcModal, NcButton, NcTextField, NcLoadingIcon } from '@nextcloud/vue'
|
||||
import { NcEmptyContent, NcModal } from '@nextcloud/vue'
|
||||
import GlobalSearchResults from '../search/GlobalSearchResults.vue'
|
||||
import { showError } from '../../helpers/errors.js'
|
||||
import { createSession } from '../../sessions.js'
|
||||
@@ -104,10 +99,6 @@ export default {
|
||||
Stack,
|
||||
NcEmptyContent,
|
||||
NcModal,
|
||||
NcTextField,
|
||||
NcButton,
|
||||
NcLoadingIcon,
|
||||
CheckIcon,
|
||||
CardSidebar,
|
||||
},
|
||||
inject: [
|
||||
@@ -140,7 +131,7 @@ export default {
|
||||
'canManage',
|
||||
]),
|
||||
stacksByBoard() {
|
||||
return this.board?.id ? this.$store.getters.stacksByBoard(this.board.id) : []
|
||||
return this.$store.getters.stacksByBoard(this.board.id)
|
||||
},
|
||||
dragHandleSelector() {
|
||||
return this.canEdit ? '.stack__title' : '.no-drag'
|
||||
@@ -156,11 +147,6 @@ export default {
|
||||
showArchived() {
|
||||
this.fetchData()
|
||||
},
|
||||
isEmpty(newValue) {
|
||||
newValue && this.$nextTick(() => {
|
||||
this.$refs?.newStackInput?.focus()
|
||||
})
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.session = createSession(this.id)
|
||||
@@ -231,13 +217,6 @@ export default {
|
||||
window.removeEventListener('mouseup', this.stopMouseDrag)
|
||||
window.removeEventListener('mouseleave', this.stopMouseDrag)
|
||||
},
|
||||
|
||||
fixActionRestriction() {
|
||||
document.body.classList.remove(
|
||||
'smooth-dnd-no-user-select',
|
||||
'smooth-dnd-disable-touch-action',
|
||||
)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -250,16 +229,13 @@ export default {
|
||||
text-align: center;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
max-width: 200px;
|
||||
margin: auto;
|
||||
margin-top: calc(var(--default-grid-baseline) * 4);
|
||||
gap: var(--default-grid-baseline);
|
||||
margin-top: 20px;
|
||||
|
||||
input[type="text"] {
|
||||
input[type=text] {
|
||||
flex-grow: 1;
|
||||
}
|
||||
button[type="submit"] {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.board-wrapper {
|
||||
@@ -302,9 +278,7 @@ export default {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
// Margin left instead of padidng to avoid jumps on dropping a card
|
||||
margin-left: $stack-spacing;
|
||||
padding-right: $stack-spacing;
|
||||
padding: $stack-spacing;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
padding-top: 15px;
|
||||
|
||||
@@ -88,33 +88,15 @@
|
||||
</div>
|
||||
</NcModal>
|
||||
|
||||
<Container :get-child-payload="payloadForCard(stack.id)"
|
||||
group-name="stack"
|
||||
data-click-closes-sidebar="true"
|
||||
non-drag-area-selector=".dragDisabled"
|
||||
:drag-handle-selector="dragHandleSelector"
|
||||
data-dragscroll-enabled
|
||||
@should-accept-drop="canEdit"
|
||||
@drag-start="draggingCard = true"
|
||||
@drag-end="draggingCard = false"
|
||||
@drop="($event) => onDropCard(stack.id, $event)">
|
||||
<Draggable v-for="card in cardsByStack" :key="card.id">
|
||||
<transition :appear="animate && !card.animated && (card.animated=true)"
|
||||
:appear-class="'zoom-appear-class'"
|
||||
:appear-active-class="'zoom-appear-active-class'">
|
||||
<CardItem :id="card.id" ref="card" :dragging="draggingCard" />
|
||||
</transition>
|
||||
</Draggable>
|
||||
</Container>
|
||||
|
||||
<transition name="slide-bottom" appear>
|
||||
<div v-show="showAddCard" class="stack__card-add">
|
||||
<transition name="slide-top" appear>
|
||||
<div v-if="showAddCard" class="stack__card-add">
|
||||
<form :class="{ 'icon-loading-small': stateCardCreating }"
|
||||
@submit.prevent.stop="clickAddCard()">
|
||||
<label for="new-stack-input-main" class="hidden-visually">{{ t('deck', 'Add a new card') }}</label>
|
||||
<input id="new-stack-input-main"
|
||||
ref="newCardInput"
|
||||
v-model="newCardTitle"
|
||||
v-focus
|
||||
type="text"
|
||||
class="no-close"
|
||||
:disabled="stateCardCreating"
|
||||
@@ -130,6 +112,25 @@
|
||||
</form>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<Container :get-child-payload="payloadForCard(stack.id)"
|
||||
group-name="stack"
|
||||
data-click-closes-sidebar="true"
|
||||
non-drag-area-selector=".dragDisabled"
|
||||
:drag-handle-selector="dragHandleSelector"
|
||||
data-dragscroll-enabled
|
||||
@should-accept-drop="canEdit"
|
||||
@drag-start="draggingCard = true"
|
||||
@drag-end="draggingCard = false"
|
||||
@drop="($event) => onDropCard(stack.id, $event)">
|
||||
<Draggable v-for="card in cardsByStack" :key="card.id">
|
||||
<transition :appear="animate && !card.animated && (card.animated=true)"
|
||||
:appear-class="'zoom-appear-class'"
|
||||
:appear-active-class="'zoom-appear-active-class'">
|
||||
<CardItem :id="card.id" :dragging="draggingCard" />
|
||||
</transition>
|
||||
</Draggable>
|
||||
</Container>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -220,18 +221,10 @@ export default {
|
||||
showAddCard(newValue) {
|
||||
if (!newValue) {
|
||||
this.$store.dispatch('toggleShortcutLock', false)
|
||||
} else {
|
||||
this.$nextTick(() => {
|
||||
this.$refs.newCardInput.focus()
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.setupAutoscrollOnDrag()
|
||||
},
|
||||
|
||||
methods: {
|
||||
stopCardCreation(e) {
|
||||
// For some reason the submit event triggers a MouseEvent that is bubbling to the outside
|
||||
@@ -310,7 +303,6 @@ export default {
|
||||
this.$nextTick(() => {
|
||||
this.$refs.newCardInput.focus()
|
||||
this.animate = false
|
||||
this.$refs.card[(this.$refs.card.length - 1)].scrollIntoView()
|
||||
})
|
||||
if (!this.cardDetailsInModal) {
|
||||
this.$router.push({ name: 'card', params: { cardId: newCard.id } })
|
||||
@@ -324,36 +316,6 @@ export default {
|
||||
onCreateCardFocus() {
|
||||
this.$store.dispatch('toggleShortcutLock', true)
|
||||
},
|
||||
setupAutoscrollOnDrag() {
|
||||
let timer
|
||||
const autoscroll = (event) => {
|
||||
const viewportX = event.clientX
|
||||
const boardElement = document.querySelector('.board')
|
||||
const viewportWidth = boardElement.clientWidth
|
||||
const offset = viewportWidth - viewportX
|
||||
const scrollMultiplier = 10
|
||||
const scrollBoundary = window.innerWidth * 0.15
|
||||
|
||||
if (offset < 100) {
|
||||
const scrollToX = boardElement.scrollLeft + scrollMultiplier * (1 - offset / scrollBoundary)
|
||||
boardElement.scrollTo(scrollToX, boardElement.scrollTop)
|
||||
}
|
||||
|
||||
if (boardElement.scrollLeft > 0 && viewportX < scrollBoundary) {
|
||||
const scrollToX = boardElement.scrollLeft - scrollMultiplier * (1 - viewportX / scrollBoundary)
|
||||
boardElement.scrollTo(scrollToX, boardElement.scrollTop)
|
||||
}
|
||||
}
|
||||
window.addEventListener('mousemove', (e) => {
|
||||
if (!this.draggingCard) {
|
||||
timer && clearInterval(timer)
|
||||
return
|
||||
}
|
||||
|
||||
clearInterval(timer)
|
||||
timer = window.setInterval(() => autoscroll(e), 25)
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -376,7 +338,6 @@ export default {
|
||||
padding-left: $card-spacing;
|
||||
padding-right: $card-spacing;
|
||||
margin: 6px;
|
||||
margin-top: 0;
|
||||
cursor: grab;
|
||||
background-color: var(--color-main-background);
|
||||
|
||||
@@ -398,6 +359,14 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
&--add:before {
|
||||
height: 78px;
|
||||
background-image: linear-gradient(180deg, var(--color-main-background) 68px, rgba(255, 255, 255, 0) 100%);
|
||||
body.theme--dark & {
|
||||
background-image: linear-gradient(180deg, var(--color-main-background) 68px, rgba(0, 0, 0, 0) 100%);
|
||||
}
|
||||
}
|
||||
|
||||
& > * {
|
||||
position: relative;
|
||||
z-index: 100;
|
||||
@@ -453,14 +422,13 @@ export default {
|
||||
flex-shrink: 0;
|
||||
z-index: 100;
|
||||
display: flex;
|
||||
margin-bottom: 5px;
|
||||
padding-top: var(--default-grid-baseline);
|
||||
margin-top: 5px;
|
||||
background-color: var(--color-main-background);
|
||||
|
||||
form {
|
||||
display: flex;
|
||||
margin-left: $stack-spacing;
|
||||
margin-right: $stack-spacing;
|
||||
margin-right: $card-spacing + $stack-spacing + 4px;
|
||||
width: 100%;
|
||||
border: 2px solid var(--color-border-maxcontrast);
|
||||
border-radius: var(--border-radius-large);
|
||||
@@ -496,16 +464,7 @@ export default {
|
||||
.slide-top-enter, .slide-top-leave-to {
|
||||
transform: translateY(-10px);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.slide-bottom-enter-active,
|
||||
.slide-bottom-leave-active {
|
||||
transition: all 100ms ease;
|
||||
}
|
||||
|
||||
.slide-bottom-enter, .slide-bottom-leave-to {
|
||||
transform: translateY(20px);
|
||||
opacity: 0;
|
||||
height: 0px;
|
||||
}
|
||||
|
||||
.modal__content {
|
||||
|
||||
@@ -248,10 +248,6 @@ export default {
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
.drop-upload--sidebar {
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
.button-group {
|
||||
display: flex;
|
||||
gap: calc(var(--default-grid-baseline) * 3);
|
||||
|
||||
@@ -162,9 +162,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
focusHeader() {
|
||||
this.$nextTick(() => {
|
||||
this.$refs?.cardSidebar.$el.querySelector('.app-sidebar-header__mainname')?.focus()
|
||||
})
|
||||
this.$refs.cardSidebar.$el.querySelector('.app-sidebar-header__mainname').focus()
|
||||
},
|
||||
handleUpdateTitleEditable(value) {
|
||||
this.titleEditable = value
|
||||
@@ -226,7 +224,6 @@ section.app-sidebar__tab--active {
|
||||
left: 0;
|
||||
right: 0;
|
||||
max-width: calc(100% - #{$modal-padding * 2});
|
||||
min-height: calc(100vh - var(--header-height) * 4);
|
||||
padding: 0 14px;
|
||||
height: 97%;
|
||||
overflow: hidden !important;
|
||||
|
||||
@@ -66,11 +66,11 @@ export default {
|
||||
@import '../../css/variables';
|
||||
|
||||
.card-cover {
|
||||
height: 90px;
|
||||
height: 100px;
|
||||
display: flex;
|
||||
margin-top: -4px;
|
||||
margin-left: -4px;
|
||||
margin-right: -4px;
|
||||
margin-top: -8px;
|
||||
margin-left: -8px;
|
||||
margin-right: -8px;
|
||||
|
||||
.image-wrapper {
|
||||
flex: 1;
|
||||
@@ -79,10 +79,10 @@ export default {
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
&.rounded-left {
|
||||
border-top-left-radius: calc(var(--border-radius-large) - 1px);
|
||||
border-top-left-radius: 10px;
|
||||
}
|
||||
&.rounded-right {
|
||||
border-top-right-radius: calc(var(--border-radius-large) - 1px);
|
||||
border-top-right-radius: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<template>
|
||||
<AttachmentDragAndDrop v-if="card" :card-id="card.id" class="drop-upload--card">
|
||||
<div :ref="`card${card.id}`"
|
||||
:class="{'compact': compactMode, 'current-card': currentCard, 'has-labels': card.labels && card.labels.length > 0, 'card__editable': canEdit, 'card__archived': card.archived, 'card__highlight': highlight}"
|
||||
:class="{'compact': compactMode, 'current-card': currentCard, 'has-labels': card.labels && card.labels.length > 0, 'card__editable': canEdit, 'card__archived': card.archived }"
|
||||
tag="div"
|
||||
:tabindex="0"
|
||||
class="card"
|
||||
@@ -103,11 +103,6 @@ export default {
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
highlight: false,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
compactMode: state => state.compactMode,
|
||||
@@ -275,14 +270,6 @@ export default {
|
||||
},
|
||||
})
|
||||
},
|
||||
scrollIntoView() {
|
||||
this.$el.scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'center' })
|
||||
this.focus()
|
||||
this.highlight = true
|
||||
setTimeout(() => {
|
||||
this.highlight = false
|
||||
}, 2000)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -303,10 +290,11 @@ export default {
|
||||
background-color: var(--color-main-background);
|
||||
margin-bottom: $card-spacing;
|
||||
padding: var(--default-grid-baseline) $card-padding;
|
||||
border: 2px solid var(--color-border-dark);
|
||||
border: 2px solid var(--color-border);
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--default-grid-baseline);
|
||||
|
||||
&:deep(*) {
|
||||
cursor: pointer;
|
||||
@@ -329,7 +317,7 @@ export default {
|
||||
h4 {
|
||||
font-weight: normal;
|
||||
margin: 0;
|
||||
padding: var(--default-grid-baseline);
|
||||
padding: 6px;
|
||||
flex-grow: 1;
|
||||
font-size: 100%;
|
||||
overflow: hidden;
|
||||
@@ -372,28 +360,10 @@ export default {
|
||||
&.card__archived {
|
||||
background-color: var(--color-background-dark);
|
||||
}
|
||||
@keyframes highlight {
|
||||
0% {
|
||||
border-color: var(--color-border-dark);
|
||||
}
|
||||
20% {
|
||||
border-color: var(--color-primary-element);
|
||||
}
|
||||
70% {
|
||||
border-color: var(--color-primary-element);
|
||||
}
|
||||
100% {
|
||||
border-color: var(--color-border-dark);
|
||||
}
|
||||
}
|
||||
&.card__highlight {
|
||||
animation: highlight 2s;
|
||||
}
|
||||
.card-labels {
|
||||
display: flex;
|
||||
align-items: end;
|
||||
padding-left: var(--default-grid-baseline);
|
||||
padding-top: var(--default-grid-baseline);
|
||||
margin-bottom: var(--default-grid-baseline);
|
||||
|
||||
.labels {
|
||||
flex-wrap: wrap;
|
||||
@@ -433,6 +403,7 @@ export default {
|
||||
display: flex;
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
&.has-labels {
|
||||
padding-bottom: $card-padding;
|
||||
|
||||
@@ -8,41 +8,19 @@
|
||||
icon="icon-add"
|
||||
@click.prevent.stop="startCreateBoard" />
|
||||
<div v-else class="board-create">
|
||||
<NcColorPicker v-model="color" class="app-navigation-entry-bullet-wrapper" :disabled="loading">
|
||||
<NcColorPicker v-model="color" class="app-navigation-entry-bullet-wrapper">
|
||||
<div :style="{ backgroundColor: color }" class="color0 icon-colorpicker app-navigation-entry-bullet" />
|
||||
</NcColorPicker>
|
||||
<form @submit.prevent.stop="createBoard">
|
||||
<NcTextField ref="inputField"
|
||||
:disable="loading"
|
||||
:value.sync="value"
|
||||
:placeholder="t('deck', 'Board name')"
|
||||
type="text"
|
||||
required />
|
||||
<NcButton type="tertiary"
|
||||
:disabled="loading"
|
||||
:title="t('deck', 'Cancel edit')"
|
||||
@click.stop.prevent="cancelEdit">
|
||||
<template #icon>
|
||||
<CloseIcon :size="20" />
|
||||
</template>
|
||||
</NcButton>
|
||||
<NcButton type="tertiary"
|
||||
native-type="submit"
|
||||
:disabled="loading"
|
||||
:title="t('deck', 'Save board')">
|
||||
<template #icon>
|
||||
<CheckIcon v-if="!loading" :size="20" />
|
||||
<NcLoadingIcon v-else :size="20" />
|
||||
</template>
|
||||
</NcButton>
|
||||
<input :placeholder="t('deck', 'Board name')" type="text" required>
|
||||
<input type="submit" value="" class="icon-confirm">
|
||||
<NcActions><NcActionButton icon="icon-close" @click.stop.prevent="cancelEdit" /></NcActions>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { NcButton, NcColorPicker, NcAppNavigationItem, NcLoadingIcon, NcTextField } from '@nextcloud/vue'
|
||||
import CheckIcon from 'vue-material-design-icons/Check.vue'
|
||||
import CloseIcon from 'vue-material-design-icons/Close.vue'
|
||||
import { NcColorPicker, NcActionButton, NcActions, NcAppNavigationItem } from '@nextcloud/vue'
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -57,33 +35,30 @@ function randomColor() {
|
||||
|
||||
export default {
|
||||
name: 'AppNavigationAddBoard',
|
||||
components: { NcButton, NcColorPicker, NcAppNavigationItem, NcLoadingIcon, NcTextField, CheckIcon, CloseIcon },
|
||||
components: { NcColorPicker, NcAppNavigationItem, NcActionButton, NcActions },
|
||||
directives: {},
|
||||
props: {},
|
||||
data() {
|
||||
return {
|
||||
value: '',
|
||||
classes: [],
|
||||
editing: false,
|
||||
loading: false,
|
||||
color: randomColor(),
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
watch: {},
|
||||
mounted() {},
|
||||
methods: {
|
||||
startCreateBoard(e) {
|
||||
this.editing = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs?.inputField.focus()
|
||||
})
|
||||
},
|
||||
async createBoard(e) {
|
||||
this.loading = true
|
||||
const title = this.value.trim()
|
||||
const title = e.currentTarget.childNodes[0].value
|
||||
await this.$store.dispatch('createBoard', {
|
||||
title,
|
||||
color: this.color.substring(1),
|
||||
})
|
||||
this.loading = false
|
||||
this.editing = false
|
||||
this.color = randomColor()
|
||||
},
|
||||
@@ -114,9 +89,10 @@ export default {
|
||||
width: var(--default-clickable-area);
|
||||
height: var(--default-clickable-area);
|
||||
.color0 {
|
||||
width: 24px !important;
|
||||
margin: var(--default-grid-baseline);
|
||||
height: 24px;
|
||||
width: 30px !important;
|
||||
margin: 5px;
|
||||
margin-left: 7px;
|
||||
height: 30px;
|
||||
border-radius: 50%;
|
||||
background-size: 14px;
|
||||
}
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
:to="routeTo"
|
||||
:undo="deleted"
|
||||
:menu-placement="'auto'"
|
||||
:force-display-actions="isTouchDevice"
|
||||
@click="onNavigate"
|
||||
@undo="unDelete">
|
||||
<NcAppNavigationIconBullet slot="icon" :color="board.color" />
|
||||
|
||||
@@ -116,47 +114,24 @@
|
||||
<div :style="{ backgroundColor: getColor }" class="color0 icon-colorpicker app-navigation-entry-bullet" />
|
||||
</NcColorPicker>
|
||||
<form @submit.prevent.stop="applyEdit">
|
||||
<NcTextField ref="inputField"
|
||||
:disable="loading"
|
||||
:value.sync="editTitle"
|
||||
:placeholder="t('deck', 'Board name')"
|
||||
<input v-model="editTitle"
|
||||
v-focus
|
||||
dir="auto"
|
||||
type="text"
|
||||
required />
|
||||
<NcButton type="tertiary"
|
||||
:disabled="loading"
|
||||
native-type="submit"
|
||||
:title="t('deck', 'Cancel edit')"
|
||||
@click.stop.prevent="cancelEdit">
|
||||
<template #icon>
|
||||
<CloseIcon :size="20" />
|
||||
</template>
|
||||
</NcButton>
|
||||
<NcButton type="tertiary"
|
||||
native-type="submit"
|
||||
:disabled="loading"
|
||||
:title="t('deck', 'Save board')">
|
||||
<template #icon>
|
||||
<CheckIcon v-if="!loading" :size="20" />
|
||||
<NcLoadingIcon v-else :size="20" />
|
||||
</template>
|
||||
</NcButton>
|
||||
required>
|
||||
<input type="submit" value="" class="icon-confirm">
|
||||
<NcActions><NcActionButton icon="icon-close" @click.stop.prevent="cancelEdit" /></NcActions>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { NcAppNavigationIconBullet, NcAppNavigationItem, NcColorPicker, NcButton, NcTextField, NcActionButton } from '@nextcloud/vue'
|
||||
import { NcAppNavigationIconBullet, NcAppNavigationItem, NcColorPicker, NcActions, NcActionButton } from '@nextcloud/vue'
|
||||
import ClickOutside from 'vue-click-outside'
|
||||
import ArchiveIcon from 'vue-material-design-icons/Archive.vue'
|
||||
import CloneIcon from 'vue-material-design-icons/ContentDuplicate.vue'
|
||||
import AccountIcon from 'vue-material-design-icons/Account.vue'
|
||||
import CloseIcon from 'vue-material-design-icons/Close.vue'
|
||||
import CheckIcon from 'vue-material-design-icons/Check.vue'
|
||||
|
||||
import { loadState } from '@nextcloud/initial-state'
|
||||
import { emit } from '@nextcloud/event-bus'
|
||||
|
||||
import isTouchDevice from '../../mixins/isTouchDevice.js'
|
||||
|
||||
const canCreateState = loadState('deck', 'canCreate')
|
||||
|
||||
@@ -166,19 +141,15 @@ export default {
|
||||
NcAppNavigationIconBullet,
|
||||
NcAppNavigationItem,
|
||||
NcColorPicker,
|
||||
NcButton,
|
||||
NcTextField,
|
||||
NcActions,
|
||||
NcActionButton,
|
||||
AccountIcon,
|
||||
ArchiveIcon,
|
||||
CloneIcon,
|
||||
CloseIcon,
|
||||
CheckIcon,
|
||||
},
|
||||
directives: {
|
||||
ClickOutside,
|
||||
},
|
||||
mixins: [isTouchDevice],
|
||||
inject: [
|
||||
'boardApi',
|
||||
],
|
||||
@@ -342,20 +313,13 @@ export default {
|
||||
actionExport() {
|
||||
this.boardApi.exportBoard(this.board)
|
||||
},
|
||||
onNavigate() {
|
||||
if (this.isTouchDevice) {
|
||||
emit('toggle-navigation', {
|
||||
open: false,
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.board-edit {
|
||||
margin-left: calc(var(--default-clickable-area) / 2);
|
||||
margin-left: var(--default-clickable-area);
|
||||
order: 1;
|
||||
display: flex;
|
||||
height: var(--default-clickable-area);
|
||||
@@ -374,9 +338,10 @@ export default {
|
||||
width: var(--default-clickable-area);
|
||||
height: var(--default-clickable-area);
|
||||
.color0 {
|
||||
width: 24px !important;
|
||||
margin: var(--default-grid-baseline);
|
||||
height: 24px;
|
||||
width: 30px !important;
|
||||
margin: 5px;
|
||||
margin-left: 7px;
|
||||
height: 30px;
|
||||
border-radius: 50%;
|
||||
background-size: 14px;
|
||||
}
|
||||
|
||||
@@ -168,13 +168,11 @@ export default {
|
||||
.dashboard-column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: $stack-width;
|
||||
width: $stack-width;
|
||||
margin-left: $stack-spacing;
|
||||
margin-right: $stack-spacing;
|
||||
|
||||
h3 {
|
||||
font-size: var(--default-font-size);
|
||||
margin: -6px;
|
||||
margin-bottom: 12px;
|
||||
padding: 6px 13px;
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
isTouchDevice() {
|
||||
return ('ontouchstart' in window) || (navigator.maxTouchPoints > 0)
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -93,7 +93,7 @@
|
||||
<template #icon>
|
||||
<NcLoadingIcon />
|
||||
</template>
|
||||
<template #name>
|
||||
<template #title>
|
||||
{{ t('deck', 'Creating the new card …') }}
|
||||
</template>
|
||||
</NcEmptyContent>
|
||||
@@ -101,7 +101,7 @@
|
||||
<template #icon>
|
||||
<CardPlusOutline />
|
||||
</template>
|
||||
<template #name>
|
||||
<template #title>
|
||||
{{ t('deck', 'Card "{card}" was added to "{board}"', { card: card.title, board: selectedBoard.title }) }}
|
||||
</template>
|
||||
<template #action>
|
||||
|
||||
@@ -31,11 +31,11 @@ use OCP\Server;
|
||||
* @group DB
|
||||
*/
|
||||
class BoardDatabaseTest extends \Test\TestCase {
|
||||
public const TEST_USER1 = 'test-share-user1';
|
||||
public const TEST_USER2 = 'test-share-user2';
|
||||
public const TEST_USER3 = 'test-share-user3';
|
||||
public const TEST_USER4 = 'test-share-user4';
|
||||
public const TEST_GROUP1 = 'test-share-group1';
|
||||
public const TEST_USER1 = "test-share-user1";
|
||||
public const TEST_USER2 = "test-share-user2";
|
||||
public const TEST_USER3 = "test-share-user3";
|
||||
public const TEST_USER4 = "test-share-user4";
|
||||
public const TEST_GROUP1 = "test-share-group1";
|
||||
|
||||
/** @var BoardService */
|
||||
private $boardService;
|
||||
|
||||
@@ -71,7 +71,7 @@ class BoardContext implements Context {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Assert::assertNotNull($id, 'Could not find board named '.$boardName);
|
||||
Assert::assertNotNull($id, "Could not find board named ".$boardName);
|
||||
} else {
|
||||
$id = $this->board['id'];
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ class SearchContext implements Context {
|
||||
/**
|
||||
* @When /^searching for "([^"]*)" in comments in unified search$/
|
||||
* @param string $term
|
||||
* https://cloud.nextcloud.com/ocs/v2.php/search/providers/talk-conversations/search?term=an&from=%2Fapps%2Fdashboard%2F
|
||||
* https://cloud.nextcloud.com/ocs/v2.php/search/providers/talk-conversations/search?term=an&from=%2Fapps%2Fdashboard%2F
|
||||
*/
|
||||
public function searchingForComments(string $term) {
|
||||
$this->requestContext->sendOCSRequest('GET', '/search/providers/search-deck-comment/search?term=' . urlencode($term), []);
|
||||
|
||||
@@ -32,7 +32,7 @@ class SessionContext implements Context {
|
||||
'boardId' => $board['id'],
|
||||
]);
|
||||
$res = json_decode((string)$this->getResponse()->getBody(), true);
|
||||
Assert::assertArrayHasKey('token', $res['ocs']['data'], 'session creation did not respond with a token');
|
||||
Assert::assertArrayHasKey('token', $res['ocs']['data'], "session creation did not respond with a token");
|
||||
|
||||
// store token
|
||||
$user = $this->serverContext->getCurrentUser();
|
||||
@@ -44,7 +44,7 @@ class SessionContext implements Context {
|
||||
*/
|
||||
public function theResponseShouldHaveActiveSessions($length) {
|
||||
$board = $this->boardContext->getLastUsedBoard();
|
||||
Assert::assertEquals($length, count($board['activeSessions']), 'unexpected count of active sessions');
|
||||
Assert::assertEquals($length, count($board['activeSessions']), "unexpected count of active sessions");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,7 +52,7 @@ class SessionContext implements Context {
|
||||
*/
|
||||
public function theUserShouldBeInTheListOfActiveSessions($user) {
|
||||
$board = $this->boardContext->getLastUsedBoard();
|
||||
Assert::assertContains($user, $board['activeSessions'], 'user is not found in the list of active sessions');
|
||||
Assert::assertContains($user, $board['activeSessions'], "user is not found in the list of active sessions");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -67,7 +67,7 @@ class SessionContext implements Context {
|
||||
|
||||
$user = $this->serverContext->getCurrentUser();
|
||||
$token = $this->tokens[$user];
|
||||
Assert::assertNotEmpty($token, 'no token for the user found');
|
||||
Assert::assertNotEmpty($token, "no token for the user found");
|
||||
$this->requestContext->sendOCSRequest('POST', '/apps/deck/api/v1.0/session/close', [
|
||||
'boardId' => $board['id'],
|
||||
'token' => $token
|
||||
|
||||
@@ -88,8 +88,8 @@ class UserExportTest extends \Test\TestCase {
|
||||
|
||||
public function getComment($id) {
|
||||
$comment = new Comment();
|
||||
$comment->setActor('users', 'admin');
|
||||
$comment->setMessage('fake comment' . $id);
|
||||
$comment->setActor("users", "admin");
|
||||
$comment->setMessage("fake comment" . $id);
|
||||
return $comment;
|
||||
}
|
||||
public function testExecute() {
|
||||
|
||||
@@ -27,24 +27,29 @@ use OCA\Deck\Db\Card;
|
||||
use OCA\Deck\Db\CardMapper;
|
||||
use OCA\Deck\Notification\NotificationHelper;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\ILogger;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Test\TestCase;
|
||||
|
||||
class ScheduledNoificationsTest extends TestCase {
|
||||
|
||||
protected ITimeFactory&MockObject $timeFactory;
|
||||
protected CardMapper&MockObject $cardMapper;
|
||||
protected NotificationHelper&MockObject $notificationHelper;
|
||||
protected LoggerInterface&MockObject $logger;
|
||||
protected ScheduledNotifications $scheduledNotifications;
|
||||
/** @var ITimeFactory|MockObject */
|
||||
protected $timeFactory;
|
||||
/** @var CardMapper|MockObject */
|
||||
protected $cardMapper;
|
||||
/** @var NotificationHelper|MockObject */
|
||||
protected $notificationHelper;
|
||||
/** @var ILogger|MockObject */
|
||||
protected $logger;
|
||||
/** @var ScheduledNotifications */
|
||||
protected $scheduledNotifications;
|
||||
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
$this->timeFactory = $this->createMock(ITimeFactory::class);
|
||||
$this->cardMapper = $this->createMock(CardMapper::class);
|
||||
$this->notificationHelper = $this->createMock(NotificationHelper::class);
|
||||
$this->logger = $this->createMock(LoggerInterface::class);
|
||||
$this->logger = $this->createMock(ILogger::class);
|
||||
$this->scheduledNotifications = new ScheduledNotifications($this->timeFactory, $this->cardMapper, $this->notificationHelper, $this->logger);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ class AclTest extends \Test\TestCase {
|
||||
private function createAclUser() {
|
||||
$acl = new Acl();
|
||||
$acl->setId(1);
|
||||
$acl->setParticipant('admin');
|
||||
$acl->setParticipant("admin");
|
||||
$acl->setType(Acl::PERMISSION_TYPE_USER);
|
||||
$acl->setBoardId(1);
|
||||
$acl->setPermissionEdit(true);
|
||||
@@ -39,7 +39,7 @@ class AclTest extends \Test\TestCase {
|
||||
private function createAclGroup() {
|
||||
$acl = new Acl();
|
||||
$acl->setId(1);
|
||||
$acl->setParticipant('administrators');
|
||||
$acl->setParticipant("administrators");
|
||||
$acl->setType(Acl::PERMISSION_TYPE_GROUP);
|
||||
$acl->setBoardId(1);
|
||||
$acl->setPermissionEdit(true);
|
||||
|
||||
@@ -28,7 +28,7 @@ class AttachmentTest extends \Test\TestCase {
|
||||
$attachment = new Attachment();
|
||||
$attachment->setId(1);
|
||||
$attachment->setCardId(123);
|
||||
$attachment->setData('blob');
|
||||
$attachment->setData("blob");
|
||||
$attachment->setCreatedBy('admin');
|
||||
$attachment->setType('deck_file');
|
||||
return $attachment;
|
||||
|
||||
@@ -8,9 +8,9 @@ class BoardTest extends TestCase {
|
||||
private function createBoard() {
|
||||
$board = new Board();
|
||||
$board->setId(1);
|
||||
$board->setTitle('My Board');
|
||||
$board->setOwner('admin');
|
||||
$board->setColor('000000');
|
||||
$board->setTitle("My Board");
|
||||
$board->setOwner("admin");
|
||||
$board->setColor("000000");
|
||||
$board->setArchived(false);
|
||||
// TODO: relation shared labels acl
|
||||
return $board;
|
||||
@@ -20,9 +20,9 @@ class BoardTest extends TestCase {
|
||||
$board->setUsers(['user1', 'user2']);
|
||||
$this->assertEquals([
|
||||
'id' => 1,
|
||||
'title' => 'My Board',
|
||||
'owner' => 'admin',
|
||||
'color' => '000000',
|
||||
'title' => "My Board",
|
||||
'owner' => "admin",
|
||||
'color' => "000000",
|
||||
'labels' => [],
|
||||
'permissions' => [],
|
||||
'stacks' => [],
|
||||
@@ -44,9 +44,9 @@ class BoardTest extends TestCase {
|
||||
self::assertNull($board->getLabels());
|
||||
$this->assertEquals([
|
||||
'id' => 1,
|
||||
'title' => 'My Board',
|
||||
'owner' => 'admin',
|
||||
'color' => '000000',
|
||||
'title' => "My Board",
|
||||
'owner' => "admin",
|
||||
'color' => "000000",
|
||||
'labels' => [],
|
||||
'permissions' => [],
|
||||
'stacks' => [],
|
||||
@@ -63,13 +63,13 @@ class BoardTest extends TestCase {
|
||||
|
||||
public function testSetLabels() {
|
||||
$board = $this->createBoard();
|
||||
$board->setLabels(['foo', 'bar']);
|
||||
$board->setLabels(["foo", "bar"]);
|
||||
$this->assertEquals([
|
||||
'id' => 1,
|
||||
'title' => 'My Board',
|
||||
'owner' => 'admin',
|
||||
'color' => '000000',
|
||||
'labels' => ['foo', 'bar'],
|
||||
'title' => "My Board",
|
||||
'owner' => "admin",
|
||||
'color' => "000000",
|
||||
'labels' => ["foo", "bar"],
|
||||
'permissions' => [],
|
||||
'stacks' => [],
|
||||
'deletedAt' => 0,
|
||||
@@ -95,9 +95,9 @@ class BoardTest extends TestCase {
|
||||
$board->setShared(1);
|
||||
$this->assertEquals([
|
||||
'id' => 1,
|
||||
'title' => 'My Board',
|
||||
'owner' => 'admin',
|
||||
'color' => '000000',
|
||||
'title' => "My Board",
|
||||
'owner' => "admin",
|
||||
'color' => "000000",
|
||||
'labels' => [],
|
||||
'permissions' => [],
|
||||
'stacks' => [],
|
||||
|
||||
@@ -32,13 +32,13 @@ class CardTest extends TestCase {
|
||||
private function createCard() {
|
||||
$card = new Card();
|
||||
$card->setId(1);
|
||||
$card->setTitle('My Card');
|
||||
$card->setDescription('a long description');
|
||||
$card->setTitle("My Card");
|
||||
$card->setDescription("a long description");
|
||||
$card->setStackId(1);
|
||||
$card->setType('text');
|
||||
$card->setLastModified(234);
|
||||
$card->setCreatedAt(123);
|
||||
$card->setOwner('admin');
|
||||
$card->setOwner("admin");
|
||||
$card->setOrder(12);
|
||||
$card->setArchived(false);
|
||||
$card->setDone(null);
|
||||
@@ -68,8 +68,8 @@ class CardTest extends TestCase {
|
||||
$card = $this->createCard();
|
||||
$this->assertEquals([
|
||||
'id' => 1,
|
||||
'title' => 'My Card',
|
||||
'description' => 'a long description',
|
||||
'title' => "My Card",
|
||||
'description' => "a long description",
|
||||
'type' => 'text',
|
||||
'lastModified' => 234,
|
||||
'createdAt' => 123,
|
||||
@@ -96,8 +96,8 @@ class CardTest extends TestCase {
|
||||
$card->setLabels([]);
|
||||
$this->assertEquals([
|
||||
'id' => 1,
|
||||
'title' => 'My Card',
|
||||
'description' => 'a long description',
|
||||
'title' => "My Card",
|
||||
'description' => "a long description",
|
||||
'type' => 'text',
|
||||
'lastModified' => 234,
|
||||
'createdAt' => 123,
|
||||
@@ -126,8 +126,8 @@ class CardTest extends TestCase {
|
||||
$card->setLabels([]);
|
||||
$this->assertEquals([
|
||||
'id' => 1,
|
||||
'title' => 'My Card',
|
||||
'description' => 'a long description',
|
||||
'title' => "My Card",
|
||||
'description' => "a long description",
|
||||
'type' => 'text',
|
||||
'lastModified' => 234,
|
||||
'createdAt' => 123,
|
||||
|
||||
@@ -29,8 +29,8 @@ class LabelTest extends TestCase {
|
||||
private function createLabel() {
|
||||
$label = new Label();
|
||||
$label->setId(1);
|
||||
$label->setTitle('My Label');
|
||||
$label->setColor('000000');
|
||||
$label->setTitle("My Label");
|
||||
$label->setColor("000000");
|
||||
return $label;
|
||||
}
|
||||
public function testJsonSerializeBoard() {
|
||||
|
||||
@@ -27,7 +27,7 @@ class StackTest extends \Test\TestCase {
|
||||
private function createStack() {
|
||||
$board = new Stack();
|
||||
$board->setId(1);
|
||||
$board->setTitle('My Stack');
|
||||
$board->setTitle("My Stack");
|
||||
$board->setBoardId(1);
|
||||
$board->setOrder(1);
|
||||
return $board;
|
||||
@@ -36,7 +36,7 @@ class StackTest extends \Test\TestCase {
|
||||
$stack = $this->createStack();
|
||||
$this->assertEquals([
|
||||
'id' => 1,
|
||||
'title' => 'My Stack',
|
||||
'title' => "My Stack",
|
||||
'order' => 1,
|
||||
'boardId' => 1,
|
||||
'deletedAt' => 0,
|
||||
@@ -45,15 +45,15 @@ class StackTest extends \Test\TestCase {
|
||||
], $stack->jsonSerialize());
|
||||
}
|
||||
public function testJsonSerializeWithCards() {
|
||||
$cards = ['foo', 'bar'];
|
||||
$cards = ["foo", "bar"];
|
||||
$stack = $this->createStack();
|
||||
$stack->setCards($cards);
|
||||
$this->assertEquals([
|
||||
'id' => 1,
|
||||
'title' => 'My Stack',
|
||||
'title' => "My Stack",
|
||||
'order' => 1,
|
||||
'boardId' => 1,
|
||||
'cards' => ['foo', 'bar'],
|
||||
'cards' => ["foo", "bar"],
|
||||
'deletedAt' => 0,
|
||||
'lastModified' => 0,
|
||||
'ETag' => $stack->getETag(),
|
||||
|
||||
@@ -32,20 +32,21 @@ use OCA\Deck\Service\PermissionService;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
use OCP\IConfig;
|
||||
use OCP\ILogger;
|
||||
use OCP\IRequest;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class ExceptionMiddlewareTest extends \Test\TestCase {
|
||||
|
||||
private LoggerInterface&MockObject $logger;
|
||||
private IConfig&MockObject $config;
|
||||
private IRequest&MockObject $request;
|
||||
private Controller&MockObject $controller;
|
||||
/** @var ILogger */
|
||||
private $logger;
|
||||
/** @var IConfig */
|
||||
private $config;
|
||||
private $request;
|
||||
private $controller;
|
||||
private $exceptionMiddleware;
|
||||
|
||||
public function setUp(): void {
|
||||
$this->logger = $this->createMock(LoggerInterface::class);
|
||||
$this->logger = $this->createMock(ILogger::class);
|
||||
$this->config = $this->createMock(IConfig::class);
|
||||
$this->request = $this->createMock(IRequest::class);
|
||||
$this->controller = $this->createMock(Controller::class);
|
||||
@@ -69,8 +70,8 @@ class ExceptionMiddlewareTest extends \Test\TestCase {
|
||||
public function testAfterException($exception, $status, $message) {
|
||||
$result = $this->exceptionMiddleware->afterException($this->controller, 'bar', $exception);
|
||||
$expected = new JSONResponse([
|
||||
'status' => $status,
|
||||
'message' => $message
|
||||
"status" => $status,
|
||||
"message" => $message
|
||||
], $status);
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ class NotificationHelperTest extends \Test\TestCase {
|
||||
protected $cardMapper;
|
||||
/** @var BoardMapper|MockObject */
|
||||
protected $boardMapper;
|
||||
/** @var AssignmentMapper|MockObject */
|
||||
/** @var AssignmentMapper|MockObject */
|
||||
protected $assignedUsersMapper;
|
||||
/** @var PermissionService|MockObject */
|
||||
protected $permissionService;
|
||||
|
||||
@@ -78,7 +78,7 @@ class AssignmentServiceTest extends TestCase {
|
||||
*/
|
||||
private $assignmentService;
|
||||
/**
|
||||
* @var AssignmentServiceValidator
|
||||
* @var AssignmentServiceValidator
|
||||
*/
|
||||
private $assignmentServiceValidator;
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ class AttachmentServiceTest extends TestCase {
|
||||
private $cardMapper;
|
||||
/** @var PermissionService|MockObject */
|
||||
private $permissionService;
|
||||
/** @var string */
|
||||
/** @var string */
|
||||
private $userId = 'admin';
|
||||
/** @var Application|MockObject */
|
||||
private $application;
|
||||
@@ -79,7 +79,7 @@ class AttachmentServiceTest extends TestCase {
|
||||
private $attachmentService;
|
||||
/** @var MockObject */
|
||||
private $attachmentServiceImpl;
|
||||
/** @var ActivityManager */
|
||||
/** @var ActivityManager */
|
||||
private $activityManager;
|
||||
private $appContainer;
|
||||
/** @var IL10N */
|
||||
@@ -91,7 +91,7 @@ class AttachmentServiceTest extends TestCase {
|
||||
*/
|
||||
private $filesAppServiceImpl;
|
||||
/**
|
||||
* @var AttachmentServiceValidator
|
||||
* @var AttachmentServiceValidator
|
||||
*/
|
||||
private $attachmentServiceValidator;
|
||||
|
||||
|
||||
@@ -34,29 +34,38 @@ use OCP\Files\SimpleFS\ISimpleFile;
|
||||
use OCP\Files\SimpleFS\ISimpleFolder;
|
||||
use OCP\IConfig;
|
||||
use OCP\IL10N;
|
||||
use OCP\ILogger;
|
||||
use OCP\IRequest;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Test\TestCase;
|
||||
|
||||
class FileServiceTest extends TestCase {
|
||||
|
||||
private IL10N&MockObject $l10n;
|
||||
private IAppData&MockObject $appData;
|
||||
private IRequest&MockObject $request;
|
||||
private LoggerInterface&MockObject $logger;
|
||||
private IRootFolder&MockObject $rootFolder;
|
||||
private IConfig&MockObject $config;
|
||||
private AttachmentMapper&MockObject $attachmentMapper;
|
||||
private IMimeTypeDetector&MockObject $mimeTypeDetector;
|
||||
private FileService $fileService;
|
||||
|
||||
/** @var IL10N|MockObject */
|
||||
private $l10n;
|
||||
/** @var IAppData|MockObject */
|
||||
private $appData;
|
||||
/** @var IRequest|MockObject */
|
||||
private $request;
|
||||
/** @var ILogger|MockObject */
|
||||
private $logger;
|
||||
/** @var FileService */
|
||||
private $fileService;
|
||||
/** @var IRootFolder */
|
||||
private $rootFolder;
|
||||
/** @var IConfig */
|
||||
private $config;
|
||||
/** @var AttachmentMapper|MockObject */
|
||||
private $attachmentMapper;
|
||||
/** @var IMimeTypeDetector|MockObject */
|
||||
private $mimeTypeDetector;
|
||||
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
$this->request = $this->createMock(IRequest::class);
|
||||
$this->appData = $this->createMock(IAppData::class);
|
||||
$this->l10n = $this->createMock(IL10N::class);
|
||||
$this->logger = $this->createMock(LoggerInterface::class);
|
||||
$this->logger = $this->createMock(ILogger::class);
|
||||
$this->rootFolder = $this->createMock(IRootFolder::class);
|
||||
$this->config = $this->createMock(IConfig::class);
|
||||
$this->attachmentMapper = $this->createMock(AttachmentMapper::class);
|
||||
|
||||
@@ -31,17 +31,17 @@ use Test\TestCase;
|
||||
|
||||
class LabelServiceTest extends TestCase {
|
||||
|
||||
/** @var LabelMapper|\PHPUnit\Framework\MockObject\MockObject */
|
||||
/** @var LabelMapper|\PHPUnit\Framework\MockObject\MockObject */
|
||||
private $labelMapper;
|
||||
/** @var PermissionService|\PHPUnit\Framework\MockObject\MockObject */
|
||||
/** @var PermissionService|\PHPUnit\Framework\MockObject\MockObject */
|
||||
private $permissionService;
|
||||
/** @var LabelService */
|
||||
/** @var LabelService */
|
||||
private $labelService;
|
||||
/** @var BoardService|\PHPUnit\Framework\MockObject\MockObject */
|
||||
private $boardService;
|
||||
/** @var ChangeHelper|\PHPUnit\Framework\MockObject\MockObject */
|
||||
private $changeHelper;
|
||||
/** @var LabelServiceValidator\MockObject */
|
||||
/** @var LabelServiceValidator\MockObject */
|
||||
private $labelServiceValidator;
|
||||
|
||||
public function setUp(): void {
|
||||
|
||||
@@ -212,8 +212,8 @@ class StackServiceTest extends TestCase {
|
||||
$this->stackMapper->expects($this->once())->method('update')->willReturn($stackToBeDeleted);
|
||||
$this->cardMapper->expects($this->once())->method('findAll')->willReturn([]);
|
||||
$this->stackService->delete(123);
|
||||
$this->assertTrue($stackToBeDeleted->getDeletedAt() <= time(), 'deletedAt is in the past');
|
||||
$this->assertTrue($stackToBeDeleted->getDeletedAt() > 0, 'deletedAt is set');
|
||||
$this->assertTrue($stackToBeDeleted->getDeletedAt() <= time(), "deletedAt is in the past");
|
||||
$this->assertTrue($stackToBeDeleted->getDeletedAt() > 0, "deletedAt is set");
|
||||
}
|
||||
|
||||
public function testUpdate() {
|
||||
|
||||
@@ -111,8 +111,8 @@ class CardApiControllerTest extends \Test\TestCase {
|
||||
$this->stackExample['id']);
|
||||
|
||||
$this->cardService->expects($this->once())
|
||||
->method('update')
|
||||
->willReturn($card);
|
||||
->method('update')
|
||||
->willReturn($card);
|
||||
|
||||
$expected = new DataResponse($card, HTTP::STATUS_OK);
|
||||
$actual = $this->controller->update('title', 'plain', 0, 'description', $this->userId, null);
|
||||
|
||||
Reference in New Issue
Block a user