From 5841dca20184e2939dcdb36631c6618a74a57ee1 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 26 Aug 2026 07:08:41 +0200 Subject: [PATCH 01/31] chore(CI): Adjust testing matrix for Nextcloud 35 on stable35 Signed-off-by: Joas Schilling --- .github/workflows/integration.yml | 2 +- composer.json | 2 +- composer.lock | 23 +++++++++++------------ 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 69d2ffdd2a..5132e03f37 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -32,7 +32,7 @@ jobs: matrix: php-versions: ['8.4'] databases: ['sqlite', 'mysql', 'pgsql'] - server-versions: ['master'] + server-versions: ['stable35'] name: php${{ matrix.php-versions }}-${{ matrix.databases }}-${{ matrix.server-versions }} diff --git a/composer.json b/composer.json index 196423e109..56ded721a8 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ "roave/security-advisories": "dev-latest", "phpunit/phpunit": "^9", "nextcloud/coding-standard": "^1.1", - "nextcloud/ocp": "dev-master" + "nextcloud/ocp": "dev-stable35" }, "config": { "optimize-autoloader": true, diff --git a/composer.lock b/composer.lock index b04e9f8c40..c2f2c3292b 100644 --- a/composer.lock +++ b/composer.lock @@ -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": "d3c4dd16a9d9702b12542dd5b6ada365", + "content-hash": "bc90c78d84e4d58456ff6fd07b86d78a", "packages": [ { "name": "bamarni/composer-bin-plugin", @@ -442,16 +442,16 @@ }, { "name": "nextcloud/ocp", - "version": "dev-master", + "version": "dev-stable35", "source": { "type": "git", "url": "https://github.com/nextcloud-deps/ocp.git", - "reference": "3e678865ee95f70754aecdeaaa6fbf4872935c73" + "reference": "75e04c37b52633c6601b63af3a33a71e0f48967e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nextcloud-deps/ocp/zipball/3e678865ee95f70754aecdeaaa6fbf4872935c73", - "reference": "3e678865ee95f70754aecdeaaa6fbf4872935c73", + "url": "https://api.github.com/repos/nextcloud-deps/ocp/zipball/75e04c37b52633c6601b63af3a33a71e0f48967e", + "reference": "75e04c37b52633c6601b63af3a33a71e0f48967e", "shasum": "" }, "require": { @@ -466,7 +466,6 @@ "symfony/polyfill-php85": "^1.41", "symfony/polyfill-php86": "^1.41" }, - "default-branch": true, "type": "library", "extra": { "branch-alias": { @@ -492,7 +491,7 @@ "issues": "https://github.com/nextcloud-deps/ocp/issues", "source": "https://github.com/nextcloud-deps/ocp/tree/master" }, - "time": "2026-08-19T00:35:23+00:00" + "time": "2026-08-24T17:09:03+00:00" }, { "name": "nikic/php-parser", @@ -3863,15 +3862,15 @@ "aliases": [], "minimum-stability": "stable", "stability-flags": { - "roave/security-advisories": 20, - "nextcloud/ocp": 20 + "nextcloud/ocp": 20, + "roave/security-advisories": 20 }, "prefer-stable": false, "prefer-lowest": false, - "platform": [], - "platform-dev": [], + "platform": {}, + "platform-dev": {}, "platform-overrides": { "php": "8.3" }, - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.9.0" } From 0a75caed5cd5809995a8e9f009d485a870fa0ed3 Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Thu, 27 Aug 2026 01:18:31 +0000 Subject: [PATCH 02/31] fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- l10n/uk.js | 4 ++-- l10n/uk.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/l10n/uk.js b/l10n/uk.js index b8a0ff1528..cc010081c7 100644 --- a/l10n/uk.js +++ b/l10n/uk.js @@ -163,10 +163,10 @@ OC.L10N.register( "Apply filter" : "Швидкий фільтр", "Filter by tag" : "Відібрати за мітками", "Filter by assigned user" : "Відібрати за призначеним користувачем", - "Unassigned" : "Скасовано призначення", + "Unassigned" : "Не призначено", "Filter by status" : "Фільтр за статусом", "Open and completed" : "Відкрито та завершено", - "Open" : "Відкрити", + "Open" : "Відкрито", "Completed" : "Виконано", "Filter by due date" : "Відібрати за датою завершення", "Overdue" : "Протерміновано", diff --git a/l10n/uk.json b/l10n/uk.json index f56a390c92..87e1154084 100644 --- a/l10n/uk.json +++ b/l10n/uk.json @@ -161,10 +161,10 @@ "Apply filter" : "Швидкий фільтр", "Filter by tag" : "Відібрати за мітками", "Filter by assigned user" : "Відібрати за призначеним користувачем", - "Unassigned" : "Скасовано призначення", + "Unassigned" : "Не призначено", "Filter by status" : "Фільтр за статусом", "Open and completed" : "Відкрито та завершено", - "Open" : "Відкрити", + "Open" : "Відкрито", "Completed" : "Виконано", "Filter by due date" : "Відібрати за датою завершення", "Overdue" : "Протерміновано", From 48a57e857edbd8495478ebbd706b47429cf39a52 Mon Sep 17 00:00:00 2001 From: samin-z Date: Wed, 12 Aug 2026 17:17:00 +0200 Subject: [PATCH 03/31] allow creating team attached boards via API Signed-off-by: samin-z --- appinfo/routes.php | 4 +- lib/Controller/BoardApiController.php | 11 ++++ lib/Controller/BoardController.php | 5 ++ lib/Db/Board.php | 4 ++ .../Version11002Date20260812120000.php | 41 +++++++++++++++ lib/Service/BoardService.php | 51 +++++++++++++++++++ tests/unit/Service/BoardServiceTest.php | 1 + 7 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 lib/Migration/Version11002Date20260812120000.php diff --git a/appinfo/routes.php b/appinfo/routes.php index 1a64b7eb84..ede98857a5 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -19,6 +19,7 @@ // boards ['name' => 'board#index', 'url' => '/boards', 'verb' => 'GET'], ['name' => 'board#create', 'url' => '/boards', 'verb' => 'POST'], + ['name' => 'board#createForTeam', 'url' => '/boards/team', 'verb' => 'POST'], ['name' => 'board#read', 'url' => '/boards/{boardId}', 'verb' => 'GET'], ['name' => 'board#update', 'url' => '/boards/{boardId}', 'verb' => 'PUT'], ['name' => 'board#delete', 'url' => '/boards/{boardId}', 'verb' => 'DELETE'], @@ -78,8 +79,9 @@ // api ['name' => 'board_api#index', 'url' => '/api/v{apiVersion}/boards', 'verb' => 'GET'], - ['name' => 'board_api#get', 'url' => '/api/v{apiVersion}/boards/{boardId}', 'verb' => 'GET'], ['name' => 'board_api#create', 'url' => '/api/v{apiVersion}/boards', 'verb' => 'POST'], + ['name' => 'board_api#createForTeam', 'url' => '/api/v{apiVersion}/boards/team', 'verb' => 'POST'], + ['name' => 'board_api#get', 'url' => '/api/v{apiVersion}/boards/{boardId}', 'verb' => 'GET'], ['name' => 'board_api#delete', 'url' => '/api/v{apiVersion}/boards/{boardId}', 'verb' => 'DELETE'], ['name' => 'board_api#update', 'url' => '/api/v{apiVersion}/boards/{boardId}', 'verb' => 'PUT'], ['name' => 'board_api#undo_delete', 'url' => '/api/v{apiVersion}/boards/{boardId}/undo_delete', 'verb' => 'POST'], diff --git a/lib/Controller/BoardApiController.php b/lib/Controller/BoardApiController.php index 4953c1b989..a27498dda5 100644 --- a/lib/Controller/BoardApiController.php +++ b/lib/Controller/BoardApiController.php @@ -86,6 +86,17 @@ public function create(string $title, string $color): DataResponse { return new DataResponse($board, HTTP::STATUS_OK); } + /** + * Create a board attached to a team (circle). + */ + #[NoAdminRequired] + #[NoCSRFRequired] + #[CORS] + public function createForTeam(string $title, string $teamId, ?string $color = null): DataResponse { + $board = $this->boardService->createForTeam($title, $this->userId, $color, $teamId); + return new DataResponse($board, HTTP::STATUS_OK); + } + /** * Update a board with the specified boardId, title and color, and archived state. */ diff --git a/lib/Controller/BoardController.php b/lib/Controller/BoardController.php index 5c43ab7b12..459fafa283 100644 --- a/lib/Controller/BoardController.php +++ b/lib/Controller/BoardController.php @@ -50,6 +50,11 @@ public function create(string $title, string $color): Board { return $this->boardService->create($title, $this->userId, $color); } + #[NoAdminRequired] + public function createForTeam(string $title, string $teamId, ?string $color = null): Board { + return $this->boardService->createForTeam($title, $this->userId, $color, $teamId); + } + #[NoAdminRequired] public function update(int $id, string $title, string $color, bool $archived): Board { return $this->boardService->update($id, $title, $color, $archived); diff --git a/lib/Db/Board.php b/lib/Db/Board.php index a0663dbd3d..9714a0117f 100644 --- a/lib/Db/Board.php +++ b/lib/Db/Board.php @@ -22,6 +22,8 @@ * @method void setLastModified(int $lastModified) * @method string getOwner() * @method void setOwner(string $owner) + * @method string|null getTeamId() + * @method void setTeamId(?string $teamId) * @method string getColor() * @method void setColor(string $color) * @method void setShareToken(string $shareToken) @@ -32,6 +34,7 @@ class Board extends RelationalEntity { protected $title; protected $owner; + protected $teamId = null; protected $color; protected $archived = false; /** @var Label[]|null */ @@ -58,6 +61,7 @@ public function __construct() { $this->addType('lastModified', 'integer'); $this->addType('shareToken', 'string'); $this->addType('externalId', 'integer'); + $this->addType('teamId', 'string'); $this->addRelation('labels'); $this->addRelation('acl'); $this->addRelation('shared'); diff --git a/lib/Migration/Version11002Date20260812120000.php b/lib/Migration/Version11002Date20260812120000.php new file mode 100644 index 0000000000..ab9996dff7 --- /dev/null +++ b/lib/Migration/Version11002Date20260812120000.php @@ -0,0 +1,41 @@ +hasTable('deck_boards')) { + return null; + } + + $table = $schema->getTable('deck_boards'); + if (!$table->hasColumn('team_id')) { + $table->addColumn('team_id', 'string', [ + 'notnull' => false, + 'length' => 64, + 'default' => null, + ]); + } + + if (!$table->hasIndex('deck_boards_team_id')) { + $table->addIndex(['team_id'], 'deck_boards_team_id'); + } + + return $schema; + } +} diff --git a/lib/Service/BoardService.php b/lib/Service/BoardService.php index 1610352ae3..2edb86a0b4 100644 --- a/lib/Service/BoardService.php +++ b/lib/Service/BoardService.php @@ -82,6 +82,7 @@ public function __construct( private IUserManager $userManager, private ISecureRandom $random, private ConfigService $configService, + private CirclesService $circlesService, private ?string $userId, ) { } @@ -228,6 +229,56 @@ public function create(string $title, string $userId, string $color): Board { return $board; } + /** + * Create a board with the current user as owner and attach it to a team + * + * @throws BadRequestException + * @throws NoPermissionException + * @throws DoesNotExistException + * @throws MultipleObjectsReturnedException + */ + public function createForTeam(string $title, string $userId, ?string $color, string $teamId): Board { + if ($color === null || $color === '') { + $color = sprintf('%06x', random_int(0, 0xffffff)); + } elseif (str_starts_with($color, '#')) { + $color = substr($color, 1); + } + + $this->boardServiceValidator->check(compact('title', 'userId', 'color')); + + if ($teamId === '') { + throw new BadRequestException('teamId must not be empty'); + } + + if (!$this->circlesService->isCirclesEnabled()) { + throw new BadRequestException('Circles/Teams app is not enabled'); + } + + if ($this->circlesService->getCircle($teamId) === null) { + throw new BadRequestException('Team not found'); + } + + if (!$this->circlesService->isUserInCircle($teamId, $userId)) { + throw new NoPermissionException('You must be a member of the team to create a team board'); + } + + $board = $this->create($title, $userId, $color); + $board->setTeamId($teamId); + $board = $this->boardMapper->update($board); + + // give edit access to the team members + $this->addAcl( + $board->getId(), + Acl::PERMISSION_TYPE_CIRCLE, + $teamId, + true, + false, + false, + ); + + return $this->find($board->getId()); + } + /** * @throws DoesNotExistException * @throws NoPermissionException diff --git a/tests/unit/Service/BoardServiceTest.php b/tests/unit/Service/BoardServiceTest.php index e28a133a73..c4e430cb54 100644 --- a/tests/unit/Service/BoardServiceTest.php +++ b/tests/unit/Service/BoardServiceTest.php @@ -151,6 +151,7 @@ public function setUp(): void { $this->userManager, $this->createMock(SecureRandom::class), $this->createMock(ConfigService::class), + $this->createMock(CirclesService::class), $this->userId ); From 371b66dd4af5f48a2a03fe22ed8c7925119476a9 Mon Sep 17 00:00:00 2001 From: samin-z Date: Thu, 13 Aug 2026 16:20:32 +0200 Subject: [PATCH 04/31] on user leave or team delete, transfer ownership or delete board Signed-off-by: samin-z --- lib/AppInfo/Application.php | 2 + lib/Db/BoardMapper.php | 14 ++++ lib/Listeners/ParticipantCleanupListener.php | 40 ++++++++--- lib/Service/CirclesService.php | 42 +++++++++++ lib/Service/TeamBoardService.php | 73 ++++++++++++++++++++ 5 files changed, 160 insertions(+), 11 deletions(-) create mode 100644 lib/Service/TeamBoardService.php diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 51efc0a480..fa1df26ff0 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -9,6 +9,7 @@ use Exception; use OCA\Circles\Events\CircleDestroyedEvent; +use OCA\Circles\Events\RemovingCircleMemberEvent; use OCA\Deck\Capabilities; use OCA\Deck\Collaboration\Resources\ResourceProvider; use OCA\Deck\Collaboration\Resources\ResourceProviderCard; @@ -170,6 +171,7 @@ public function register(IRegistrationContext $context): void { $context->registerEventListener(UserDeletedEvent::class, ParticipantCleanupListener::class); $context->registerEventListener(GroupDeletedEvent::class, ParticipantCleanupListener::class); + $context->registerEventListener(RemovingCircleMemberEvent::class, ParticipantCleanupListener::class); $context->registerEventListener(CircleDestroyedEvent::class, ParticipantCleanupListener::class); // Event listening for realtime updates via notify_push diff --git a/lib/Db/BoardMapper.php b/lib/Db/BoardMapper.php index d9d7d2c4b8..adaf2962e1 100644 --- a/lib/Db/BoardMapper.php +++ b/lib/Db/BoardMapper.php @@ -306,6 +306,20 @@ public function findAllByOwner(string $userId, ?int $limit = null, ?int $offset return $this->findEntities($qb); } + /** + * Find all board with the team_id set to the given teamId + * + * @return Board[] + */ + public function findAllAttachedToTeam(string $teamId): array { + $qb = $this->db->getQueryBuilder(); + $qb->select('*') + ->from('deck_boards') + ->where($qb->expr()->eq('team_id', $qb->createNamedParameter($teamId, IQueryBuilder::PARAM_STR))) + ->orderBy('id'); + return $this->findEntities($qb); + } + /** * Find all boards for a given user */ diff --git a/lib/Listeners/ParticipantCleanupListener.php b/lib/Listeners/ParticipantCleanupListener.php index ebf35eab6b..0d58207d14 100644 --- a/lib/Listeners/ParticipantCleanupListener.php +++ b/lib/Listeners/ParticipantCleanupListener.php @@ -8,43 +8,61 @@ namespace OCA\Deck\Listeners; use OCA\Circles\Events\CircleDestroyedEvent; +use OCA\Circles\Events\RemovingCircleMemberEvent; +use OCA\Circles\Model\Member; use OCA\Deck\Db\Acl; use OCA\Deck\Db\AclMapper; use OCA\Deck\Db\AssignmentMapper; use OCA\Deck\Db\BoardMapper; +use OCA\Deck\Service\TeamBoardService; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; use OCP\Group\Events\GroupDeletedEvent; use OCP\User\Events\UserDeletedEvent; -/** @template-implements IEventListener */ +/** @template-implements IEventListener */ class ParticipantCleanupListener implements IEventListener { - private AclMapper $aclMapper; - private AssignmentMapper $assignmentMapper; - private BoardMapper $boardMapper; - - public function __construct(AclMapper $aclMapper, AssignmentMapper $assignmentMapper, BoardMapper $boardMapper) { - $this->aclMapper = $aclMapper; - $this->assignmentMapper = $assignmentMapper; - $this->boardMapper = $boardMapper; + public function __construct( + private AclMapper $aclMapper, + private AssignmentMapper $assignmentMapper, + private BoardMapper $boardMapper, + private TeamBoardService $teamBoardService, + ) { } public function handle(Event $event): void { if ($event instanceof UserDeletedEvent) { - $boards = $this->boardMapper->findAllByOwner($event->getUser()->getUID()); + $userId = $event->getUser()->getUID(); + $transferredBoardIds = $this->teamBoardService->transferTeamBoardsFromDeletedUser($userId); + + $boards = $this->boardMapper->findAllByOwner($userId); foreach ($boards as $board) { + if (in_array($board->getId(), $transferredBoardIds, true)) { + continue; + } $this->boardMapper->delete($board); } - $this->cleanupByParticipant(Acl::PERMISSION_TYPE_USER, $event->getUser()->getUID()); + $this->cleanupByParticipant(Acl::PERMISSION_TYPE_USER, $userId); } if ($event instanceof GroupDeletedEvent) { $this->cleanupByParticipant(Acl::PERMISSION_TYPE_GROUP, $event->getGroup()->getGID()); } + if ($event instanceof RemovingCircleMemberEvent) { + $member = $event->getMember(); + if ($member !== null && $member->getUserType() === Member::TYPE_USER) { + $this->teamBoardService->handleMemberLeftTeam( + $event->getCircle()->getSingleId(), + $member->getUserId() + ); + } + } + if ($event instanceof CircleDestroyedEvent) { $circleId = $event->getCircle()->getSingleId(); + $this->teamBoardService->deleteBoardsAttachedToTeam($circleId); $this->cleanupByParticipant(Acl::PERMISSION_TYPE_CIRCLE, $circleId); } } diff --git a/lib/Service/CirclesService.php b/lib/Service/CirclesService.php index b003fd6550..6c16fd757c 100644 --- a/lib/Service/CirclesService.php +++ b/lib/Service/CirclesService.php @@ -105,4 +105,46 @@ public function getUserCircles(string $userId): array { } return []; } + + /** + * Replace with the next team member to own the board, with higher circles level + */ + public function findNextMemberUserId(string $circleId, ?string $excludeUserId = null): ?string { + if (!$this->circlesEnabled) { + return null; + } + + try { + $circlesManager = Server::get(CirclesManager::class); + $circlesManager->startSuperSession(); + $circle = $circlesManager->getCircle($circleId); + $circleMembers = []; + foreach ($circle->getMembers() as $member) { + if ($member->getUserType() !== Member::TYPE_USER) { + continue; + } + if ($member->getLevel() < Member::LEVEL_MEMBER) { + continue; + } + if ($excludeUserId !== null && $member->getUserId() === $excludeUserId) { + continue; + } + $circleMembers[] = $member; + } + + if ($circleMembers === []) { + return null; + } + + usort( + $circleMembers, + static fn (Member $a, Member $b): int => $b->getLevel() <=> $a->getLevel() + ); + + return $circleMembers[0]->getUserId(); + } catch (Throwable $e) { + } + + return null; + } } diff --git a/lib/Service/TeamBoardService.php b/lib/Service/TeamBoardService.php new file mode 100644 index 0000000000..dc56d32702 --- /dev/null +++ b/lib/Service/TeamBoardService.php @@ -0,0 +1,73 @@ +boardMapper->findAllByOwner($userId) as $board) { + $teamId = $board->getTeamId(); + if ($teamId === null || $teamId === '') { + continue; + } + + $nextOwner = $this->circlesService->findNextMemberUserId($teamId, $userId); + if ($nextOwner === null) { + continue; + } + + $this->boardMapper->transferOwnership($userId, $nextOwner, $board->getId()); + $transferredBoardIds[] = $board->getId(); + } + + return $transferredBoardIds; + } + + /** + * When a user leaves the team,transfer ownership, or delete board + */ + public function handleMemberLeftTeam(string $teamId, string $userId): void { + foreach ($this->boardMapper->findAllAttachedToTeam($teamId) as $board) { + if ($board->getOwner() !== $userId) { + continue; + } + + $nextOwner = $this->circlesService->findNextMemberUserId($teamId, $userId); + if ($nextOwner === null) { + $this->boardMapper->delete($board); + continue; + } + + $this->boardMapper->transferOwnership($userId, $nextOwner, $board->getId()); + } + } + + /** + * When a team is deleted all boards attached to it are deleted too + */ + public function deleteBoardsAttachedToTeam(string $teamId): void { + foreach ($this->boardMapper->findAllAttachedToTeam($teamId) as $board) { + $this->boardMapper->delete($board); + } + } +} From 99194fcb0758017a7bb3bd32509ddca17b1d0c70 Mon Sep 17 00:00:00 2001 From: samin-z Date: Thu, 13 Aug 2026 17:29:33 +0200 Subject: [PATCH 05/31] add unit test Signed-off-by: samin-z --- lib/Db/BoardMapper.php | 2 +- tests/unit/Service/BoardServiceTest.php | 131 ++++++++++++++++- tests/unit/Service/TeamBoardServiceTest.php | 153 ++++++++++++++++++++ 3 files changed, 284 insertions(+), 2 deletions(-) create mode 100644 tests/unit/Service/TeamBoardServiceTest.php diff --git a/lib/Db/BoardMapper.php b/lib/Db/BoardMapper.php index adaf2962e1..b334a03910 100644 --- a/lib/Db/BoardMapper.php +++ b/lib/Db/BoardMapper.php @@ -308,7 +308,7 @@ public function findAllByOwner(string $userId, ?int $limit = null, ?int $offset /** * Find all board with the team_id set to the given teamId - * + * * @return Board[] */ public function findAllAttachedToTeam(string $teamId): array { diff --git a/tests/unit/Service/BoardServiceTest.php b/tests/unit/Service/BoardServiceTest.php index c4e430cb54..6a86a693ac 100644 --- a/tests/unit/Service/BoardServiceTest.php +++ b/tests/unit/Service/BoardServiceTest.php @@ -31,7 +31,9 @@ use OC\Federation\CloudIdManager; use OC\L10N\L10N; use OC\Security\SecureRandom; +use OCA\Circles\Model\Circle; use OCA\Deck\Activity\ActivityManager; +use OCA\Deck\BadRequestException; use OCA\Deck\Db\Acl; use OCA\Deck\Db\AclMapper; use OCA\Deck\Db\Assignment; @@ -104,6 +106,9 @@ class BoardServiceTest extends TestCase { /** @var IUserManager */ private $userManager; + /** @var CirclesService|MockObject */ + private $circlesService; + public function setUp(): void { parent::setUp(); $this->l10n = $this->createMock(L10N::class); @@ -125,6 +130,7 @@ public function setUp(): void { $this->boardServiceValidator = $this->createMock(BoardServiceValidator::class); $this->sessionMapper = $this->createMock(SessionMapper::class); $this->userManager = $this->createMock(IUserManager::class); + $this->circlesService = $this->createMock(CirclesService::class); $this->service = new BoardService( $this->boardMapper, @@ -151,7 +157,7 @@ public function setUp(): void { $this->userManager, $this->createMock(SecureRandom::class), $this->createMock(ConfigService::class), - $this->createMock(CirclesService::class), + $this->circlesService, $this->userId ); @@ -227,6 +233,129 @@ public function testCreateDenied() { $b = $this->service->create('MyBoard', 'admin', '00ff00'); } + public function testCreateForTeamEmptyTeamId(): void { + $this->expectException(BadRequestException::class); + $this->service->createForTeam('Team board', $this->userId, '00ff00', ''); + } + + public function testCreateForTeamCirclesDisabled(): void { + $this->circlesService->expects($this->once()) + ->method('isCirclesEnabled') + ->willReturn(false); + $this->expectException(BadRequestException::class); + $this->service->createForTeam('Team board', $this->userId, '00ff00', 'team-a'); + } + + public function testCreateForTeamNotFound(): void { + $this->circlesService->expects($this->once()) + ->method('isCirclesEnabled') + ->willReturn(true); + $this->circlesService->expects($this->once()) + ->method('getCircle') + ->with('team-a') + ->willReturn(null); + $this->expectException(BadRequestException::class); + $this->service->createForTeam('Team board', $this->userId, '00ff00', 'team-a'); + } + + public function testCreateForTeamNotMember(): void { + $this->circlesService->expects($this->once()) + ->method('isCirclesEnabled') + ->willReturn(true); + $this->circlesService->expects($this->once()) + ->method('getCircle') + ->with('team-a') + ->willReturn($this->createMock(Circle::class)); + $this->circlesService->expects($this->once()) + ->method('isUserInCircle') + ->with('team-a', $this->userId) + ->willReturn(false); + $this->expectException(NoPermissionException::class); + $this->service->createForTeam('Team board', $this->userId, '00ff00', 'team-a'); + } + + public function testCreateForTeamSuccess(): void { + $createdBoard = new Board(); + $createdBoard->setId(42); + $createdBoard->setTitle('Team board'); + $createdBoard->setOwner($this->userId); + $createdBoard->setColor('00ff00'); + + $updatedBoard = new Board(); + $updatedBoard->setId(42); + $updatedBoard->setTitle('Team board'); + $updatedBoard->setOwner($this->userId); + $updatedBoard->setColor('00ff00'); + $updatedBoard->setTeamId('team-a'); + + $this->circlesService->expects($this->once()) + ->method('isCirclesEnabled') + ->willReturn(true); + $this->circlesService->expects($this->once()) + ->method('getCircle') + ->with('team-a') + ->willReturn($this->createMock(Circle::class)); + $this->circlesService->expects($this->once()) + ->method('isUserInCircle') + ->with('team-a', $this->userId) + ->willReturn(true); + + /** @var BoardService|MockObject $service */ + $service = $this->getMockBuilder(BoardService::class) + ->setConstructorArgs([ + $this->boardMapper, + $this->stackMapper, + $this->cardMapper, + $this->config, + $this->l10n, + $this->labelMapper, + $this->aclMapper, + $this->permissionService, + $this->assignmentService, + $this->notificationHelper, + $this->assignedUsersMapper, + $this->activityManager, + $this->createMock(CloudFederationProviderManager::class), + $this->createMock(CloudIdManager::class), + $this->createMock(CloudFederationFactory::class), + $this->eventDispatcher, + $this->changeHelper, + $this->urlGenerator, + $this->connection, + $this->boardServiceValidator, + $this->sessionMapper, + $this->userManager, + $this->createMock(SecureRandom::class), + $this->createMock(ConfigService::class), + $this->circlesService, + $this->userId, + ]) + ->onlyMethods(['create', 'addAcl', 'find']) + ->getMock(); + + $service->expects($this->once()) + ->method('create') + ->with('Team board', $this->userId, '00ff00') + ->willReturn($createdBoard); + $this->boardMapper->expects($this->once()) + ->method('update') + ->with($this->callback(function (Board $board) { + return $board->getId() === 42 && $board->getTeamId() === 'team-a'; + })) + ->willReturn($updatedBoard); + $service->expects($this->once()) + ->method('addAcl') + ->with(42, Acl::PERMISSION_TYPE_CIRCLE, 'team-a', true, false, false); + $service->expects($this->once()) + ->method('find') + ->with(42) + ->willReturn($updatedBoard); + + $result = $service->createForTeam('Team board', $this->userId, '00ff00', 'team-a'); + $this->assertSame($updatedBoard, $result); + $this->assertEquals('team-a', $result->getTeamId()); + } + public function testUpdate() { $board = new Board(); $board->setId(123); diff --git a/tests/unit/Service/TeamBoardServiceTest.php b/tests/unit/Service/TeamBoardServiceTest.php new file mode 100644 index 0000000000..00d8c0e861 --- /dev/null +++ b/tests/unit/Service/TeamBoardServiceTest.php @@ -0,0 +1,153 @@ +boardMapper = $this->createMock(BoardMapper::class); + $this->circlesService = $this->createMock(CirclesService::class); + $this->service = new TeamBoardService( + $this->boardMapper, + $this->circlesService, + ); + } + + public function testTransferTeamBoardsFromDeletedUser(): void { + $personalBoard = new Board(); + $personalBoard->setId(1); + $personalBoard->setOwner($this->userId1); + $personalBoard->setTeamId(null); + + $orphanedTeamBoard = new Board(); + $orphanedTeamBoard->setId(2); + $orphanedTeamBoard->setOwner($this->userId1); + $orphanedTeamBoard->setTeamId('team-a'); + + $transferableBoard = new Board(); + $transferableBoard->setId(3); + $transferableBoard->setOwner($this->userId1); + $transferableBoard->setTeamId('team-b'); + + $this->boardMapper->expects($this->once()) + ->method('findAllByOwner') + ->with($this->userId1) + ->willReturn([$personalBoard, $orphanedTeamBoard, $transferableBoard]); + + $this->circlesService->expects($this->exactly(2)) + ->method('findNextMemberUserId') + ->willReturnMap([ + ['team-a', $this->userId1, null], + ['team-b', $this->userId1, $this->userId2], + ]); + + $this->boardMapper->expects($this->once()) + ->method('transferOwnership') + ->with($this->userId1, $this->userId2, 3); + + $this->assertSame([3], $this->service->transferTeamBoardsFromDeletedUser($this->userId1)); + } + + public function testHandleMemberLeftTeamTransfersOwnership(): void { + $board = new Board(); + $board->setId(10); + $board->setOwner($this->userId1); + $board->setTeamId('team-a'); + + $this->boardMapper->expects($this->once()) + ->method('findAllAttachedToTeam') + ->with('team-a') + ->willReturn([$board]); + $this->circlesService->expects($this->once()) + ->method('findNextMemberUserId') + ->with('team-a', $this->userId1) + ->willReturn($this->userId2); + $this->boardMapper->expects($this->once()) + ->method('transferOwnership') + ->with($this->userId1, $this->userId2, 10); + $this->boardMapper->expects($this->never()) + ->method('delete'); + + $this->service->handleMemberLeftTeam('team-a', $this->userId1); + } + + public function testHandleMemberLeftTeamDeletesWhenNoNextMember(): void { + $board = new Board(); + $board->setId(11); + $board->setOwner($this->userId1); + $board->setTeamId('team-a'); + + $this->boardMapper->expects($this->once()) + ->method('findAllAttachedToTeam') + ->with('team-a') + ->willReturn([$board]); + $this->circlesService->expects($this->once()) + ->method('findNextMemberUserId') + ->with('team-a', $this->userId1) + ->willReturn(null); + $this->boardMapper->expects($this->once()) + ->method('delete') + ->with($board); + $this->boardMapper->expects($this->never()) + ->method('transferOwnership'); + + $this->service->handleMemberLeftTeam('team-a', $this->userId1); + } + + public function testHandleMemberLeftTeamSkipsNonOwnerBoards(): void { + $board = new Board(); + $board->setId(12); + $board->setOwner($this->userId2); + $board->setTeamId('team-a'); + + $this->boardMapper->expects($this->once()) + ->method('findAllAttachedToTeam') + ->with('team-a') + ->willReturn([$board]); + $this->circlesService->expects($this->never()) + ->method('findNextMemberUserId'); + $this->boardMapper->expects($this->never()) + ->method('transferOwnership'); + $this->boardMapper->expects($this->never()) + ->method('delete'); + + $this->service->handleMemberLeftTeam('team-a', $this->userId1); + } + + public function testDeleteBoardsAttachedToTeam(): void { + $boardA = new Board(); + $boardA->setId(20); + $boardB = new Board(); + $boardB->setId(21); + + $this->boardMapper->expects($this->once()) + ->method('findAllAttachedToTeam') + ->with('team-a') + ->willReturn([$boardA, $boardB]); + $this->boardMapper->expects($this->exactly(2)) + ->method('delete') + ->withConsecutive([$boardA], [$boardB]); + + $this->service->deleteBoardsAttachedToTeam('team-a'); + } +} From 4fb7a87abf2f4aa28eb65b6cfe52f1a58b95a708 Mon Sep 17 00:00:00 2001 From: samin-z Date: Wed, 26 Aug 2026 15:34:07 +0200 Subject: [PATCH 06/31] update psalm stubs and unit tests Signed-off-by: samin-z --- lib/Listeners/ParticipantCleanupListener.php | 2 +- tests/data/deck.json | 2 ++ tests/stub.phpstub | 8 ++++++++ tests/unit/Db/BoardTest.php | 12 ++++++++---- tests/unit/Service/BoardServiceTest.php | 4 ++++ tests/unit/stubs/CirclesCircle.php | 16 ++++++++++++++++ 6 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 tests/unit/stubs/CirclesCircle.php diff --git a/lib/Listeners/ParticipantCleanupListener.php b/lib/Listeners/ParticipantCleanupListener.php index 0d58207d14..3faba095a7 100644 --- a/lib/Listeners/ParticipantCleanupListener.php +++ b/lib/Listeners/ParticipantCleanupListener.php @@ -52,7 +52,7 @@ public function handle(Event $event): void { if ($event instanceof RemovingCircleMemberEvent) { $member = $event->getMember(); - if ($member !== null && $member->getUserType() === Member::TYPE_USER) { + if ($member->getUserType() === Member::TYPE_USER) { $this->teamBoardService->handleMemberLeftTeam( $event->getCircle()->getSingleId(), $member->getUserId() diff --git a/tests/data/deck.json b/tests/data/deck.json index 0fa4514aef..fd50417abd 100644 --- a/tests/data/deck.json +++ b/tests/data/deck.json @@ -10,6 +10,7 @@ "displayname": "admin", "type": 0 }, + "teamId": null, "color": "e0ed31", "archived": false, "labels": [ @@ -401,6 +402,7 @@ "displayname": "admin", "type": 0 }, + "teamId": null, "color": "30b6d8", "archived": false, "labels": [ diff --git a/tests/stub.phpstub b/tests/stub.phpstub index 8ca73d9dd8..73673f72e5 100644 --- a/tests/stub.phpstub +++ b/tests/stub.phpstub @@ -73,6 +73,7 @@ namespace OCA\Circles\Model { public function getLevel(): int {} public function getUserType(): int{} + public function getUserId(): string {} } class Circle { @@ -80,6 +81,8 @@ namespace OCA\Circles\Model { public function getDisplayName(): string {} public function getOwner(): string {} public function getSingleId(): string {} + /** @return Member[] */ + public function getMembers(int $limit = 0): array {} public function getInheritedMembers(): array {} public function getInitiator(): Member {} } @@ -93,6 +96,11 @@ namespace OCA\Circles\Events { public function __construct(FederatedEvent $federatedEvent, array $results) {} abstract public function getCircle(): \OCA\Circles\Model\Circle {} } + + class RemovingCircleMemberEvent extends \OCP\EventDispatcher\Event { + public function getCircle(): \OCA\Circles\Model\Circle {} + public function getMember(): \OCA\Circles\Model\Member {} + } } namespace OCA\Circles\Model\Probes { class CircleProbe { diff --git a/tests/unit/Db/BoardTest.php b/tests/unit/Db/BoardTest.php index 5d729b518e..feccc041ff 100644 --- a/tests/unit/Db/BoardTest.php +++ b/tests/unit/Db/BoardTest.php @@ -35,7 +35,8 @@ public function testJsonSerialize() { 'activeSessions' => [], 'ETag' => $board->getETag(), 'shareToken' => null, - 'externalId' => null + 'externalId' => null, + 'teamId' => null, ], $board->jsonSerialize()); } @@ -61,7 +62,8 @@ public function testUnfetchedValues() { 'activeSessions' => [], 'ETag' => $board->getETag(), 'shareToken' => null, - 'externalId' => null + 'externalId' => null, + 'teamId' => null, ], $board->jsonSerialize()); } @@ -85,7 +87,8 @@ public function testSetLabels() { 'activeSessions' => [], 'ETag' => $board->getETag(), 'shareToken' => null, - 'externalId' => null + 'externalId' => null, + 'teamId' => null, ], $board->jsonSerialize()); } public function testSetAcl() { @@ -117,7 +120,8 @@ public function testSetShared() { 'activeSessions' => [], 'ETag' => $board->getETag(), 'shareToken' => null, - 'externalId' => null + 'externalId' => null, + 'teamId' => null, ], $board->jsonSerialize()); } } diff --git a/tests/unit/Service/BoardServiceTest.php b/tests/unit/Service/BoardServiceTest.php index 6a86a693ac..c51a049d99 100644 --- a/tests/unit/Service/BoardServiceTest.php +++ b/tests/unit/Service/BoardServiceTest.php @@ -26,6 +26,10 @@ namespace OCA\Deck\Service; +if (!class_exists(\OCA\Circles\Model\Circle::class)) { + require_once __DIR__ . '/../stubs/CirclesCircle.php'; +} + use OC\Federation\CloudFederationFactory; use OC\Federation\CloudFederationProviderManager; use OC\Federation\CloudIdManager; diff --git a/tests/unit/stubs/CirclesCircle.php b/tests/unit/stubs/CirclesCircle.php new file mode 100644 index 0000000000..f3d2428f6f --- /dev/null +++ b/tests/unit/stubs/CirclesCircle.php @@ -0,0 +1,16 @@ + Date: Wed, 26 Aug 2026 17:13:07 +0200 Subject: [PATCH 07/31] move createForTeam to OCS and simplify team ownership transfer Signed-off-by: samin-z --- appinfo/routes.php | 3 +-- lib/Controller/BoardApiController.php | 11 --------- lib/Controller/BoardController.php | 5 ---- lib/Controller/BoardOcsController.php | 8 +++++++ lib/Listeners/ParticipantCleanupListener.php | 13 +--------- lib/Service/CirclesService.php | 25 +++++++------------- lib/Service/TeamBoardService.php | 25 +++++++------------- tests/unit/Service/TeamBoardServiceTest.php | 8 +++++-- 8 files changed, 34 insertions(+), 64 deletions(-) diff --git a/appinfo/routes.php b/appinfo/routes.php index ede98857a5..8a2b9be5fe 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -19,7 +19,6 @@ // boards ['name' => 'board#index', 'url' => '/boards', 'verb' => 'GET'], ['name' => 'board#create', 'url' => '/boards', 'verb' => 'POST'], - ['name' => 'board#createForTeam', 'url' => '/boards/team', 'verb' => 'POST'], ['name' => 'board#read', 'url' => '/boards/{boardId}', 'verb' => 'GET'], ['name' => 'board#update', 'url' => '/boards/{boardId}', 'verb' => 'PUT'], ['name' => 'board#delete', 'url' => '/boards/{boardId}', 'verb' => 'DELETE'], @@ -80,7 +79,6 @@ // api ['name' => 'board_api#index', 'url' => '/api/v{apiVersion}/boards', 'verb' => 'GET'], ['name' => 'board_api#create', 'url' => '/api/v{apiVersion}/boards', 'verb' => 'POST'], - ['name' => 'board_api#createForTeam', 'url' => '/api/v{apiVersion}/boards/team', 'verb' => 'POST'], ['name' => 'board_api#get', 'url' => '/api/v{apiVersion}/boards/{boardId}', 'verb' => 'GET'], ['name' => 'board_api#delete', 'url' => '/api/v{apiVersion}/boards/{boardId}', 'verb' => 'DELETE'], ['name' => 'board_api#update', 'url' => '/api/v{apiVersion}/boards/{boardId}', 'verb' => 'PUT'], @@ -143,6 +141,7 @@ ['name' => 'board_ocs#read', 'url' => '/api/v{apiVersion}/board/{boardId}', 'verb' => 'GET'], ['name' => 'stack_ocs#index', 'url' => '/api/v{apiVersion}/stacks/{boardId}', 'verb' => 'GET'], ['name' => 'board_ocs#create', 'url' => '/api/v{apiVersion}/boards', 'verb' => 'POST'], + ['name' => 'board_ocs#createForTeam', 'url' => '/api/v{apiVersion}/boards/team', 'verb' => 'POST'], ['name' => 'board_ocs#addAcl', 'url' => '/api/v{apiVersion}/boards/{boardId}/acl', 'verb' => 'POST'], ['name' => 'card_ocs#create', 'url' => '/api/v{apiVersion}/cards', 'verb' => 'POST'], diff --git a/lib/Controller/BoardApiController.php b/lib/Controller/BoardApiController.php index a27498dda5..4953c1b989 100644 --- a/lib/Controller/BoardApiController.php +++ b/lib/Controller/BoardApiController.php @@ -86,17 +86,6 @@ public function create(string $title, string $color): DataResponse { return new DataResponse($board, HTTP::STATUS_OK); } - /** - * Create a board attached to a team (circle). - */ - #[NoAdminRequired] - #[NoCSRFRequired] - #[CORS] - public function createForTeam(string $title, string $teamId, ?string $color = null): DataResponse { - $board = $this->boardService->createForTeam($title, $this->userId, $color, $teamId); - return new DataResponse($board, HTTP::STATUS_OK); - } - /** * Update a board with the specified boardId, title and color, and archived state. */ diff --git a/lib/Controller/BoardController.php b/lib/Controller/BoardController.php index 459fafa283..5c43ab7b12 100644 --- a/lib/Controller/BoardController.php +++ b/lib/Controller/BoardController.php @@ -50,11 +50,6 @@ public function create(string $title, string $color): Board { return $this->boardService->create($title, $this->userId, $color); } - #[NoAdminRequired] - public function createForTeam(string $title, string $teamId, ?string $color = null): Board { - return $this->boardService->createForTeam($title, $this->userId, $color, $teamId); - } - #[NoAdminRequired] public function update(int $id, string $title, string $color, bool $archived): Board { return $this->boardService->update($id, $title, $color, $archived); diff --git a/lib/Controller/BoardOcsController.php b/lib/Controller/BoardOcsController.php index 2616194cd9..fcfe09adbf 100644 --- a/lib/Controller/BoardOcsController.php +++ b/lib/Controller/BoardOcsController.php @@ -49,6 +49,14 @@ public function create(string $title, string $color): DataResponse { return new DataResponse($this->boardService->create($title, $this->userId, $color)); } + /** + * Create a board attached to a team (circle). + */ + #[NoAdminRequired] + public function createForTeam(string $title, string $teamId, ?string $color = null): DataResponse { + return new DataResponse($this->boardService->createForTeam($title, $this->userId, $color, $teamId)); + } + #[NoAdminRequired] public function addAcl(int $boardId, int $type, string $participant, bool $permissionEdit, bool $permissionShare, bool $permissionManage, ?string $remote = null): DataResponse { return new DataResponse($this->boardService->addAcl($boardId, $type, $participant, $permissionEdit, $permissionShare, $permissionManage)); diff --git a/lib/Listeners/ParticipantCleanupListener.php b/lib/Listeners/ParticipantCleanupListener.php index 3faba095a7..bbc86e0b82 100644 --- a/lib/Listeners/ParticipantCleanupListener.php +++ b/lib/Listeners/ParticipantCleanupListener.php @@ -13,7 +13,6 @@ use OCA\Deck\Db\Acl; use OCA\Deck\Db\AclMapper; use OCA\Deck\Db\AssignmentMapper; -use OCA\Deck\Db\BoardMapper; use OCA\Deck\Service\TeamBoardService; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; @@ -25,7 +24,6 @@ class ParticipantCleanupListener implements IEventListener { public function __construct( private AclMapper $aclMapper, private AssignmentMapper $assignmentMapper, - private BoardMapper $boardMapper, private TeamBoardService $teamBoardService, ) { } @@ -33,16 +31,7 @@ public function __construct( public function handle(Event $event): void { if ($event instanceof UserDeletedEvent) { $userId = $event->getUser()->getUID(); - $transferredBoardIds = $this->teamBoardService->transferTeamBoardsFromDeletedUser($userId); - - $boards = $this->boardMapper->findAllByOwner($userId); - foreach ($boards as $board) { - if (in_array($board->getId(), $transferredBoardIds, true)) { - continue; - } - $this->boardMapper->delete($board); - } - + $this->teamBoardService->handleBoardsOwnedByDeletedUser($userId); $this->cleanupByParticipant(Acl::PERMISSION_TYPE_USER, $userId); } diff --git a/lib/Service/CirclesService.php b/lib/Service/CirclesService.php index 6c16fd757c..7c81e9bb42 100644 --- a/lib/Service/CirclesService.php +++ b/lib/Service/CirclesService.php @@ -107,7 +107,7 @@ public function getUserCircles(string $userId): array { } /** - * Replace with the next team member to own the board, with higher circles level + * Find a remaining team owner or admin to take over board ownership. */ public function findNextMemberUserId(string $circleId, ?string $excludeUserId = null): ?string { if (!$this->circlesEnabled) { @@ -118,30 +118,23 @@ public function findNextMemberUserId(string $circleId, ?string $excludeUserId = $circlesManager = Server::get(CirclesManager::class); $circlesManager->startSuperSession(); $circle = $circlesManager->getCircle($circleId); - $circleMembers = []; + $adminUserId = null; foreach ($circle->getMembers() as $member) { if ($member->getUserType() !== Member::TYPE_USER) { continue; } - if ($member->getLevel() < Member::LEVEL_MEMBER) { - continue; - } if ($excludeUserId !== null && $member->getUserId() === $excludeUserId) { continue; } - $circleMembers[] = $member; - } - - if ($circleMembers === []) { - return null; + if ($member->getLevel() === Member::LEVEL_OWNER) { + return $member->getUserId(); + } + if ($adminUserId === null && $member->getLevel() >= Member::LEVEL_ADMIN) { + $adminUserId = $member->getUserId(); + } } - usort( - $circleMembers, - static fn (Member $a, Member $b): int => $b->getLevel() <=> $a->getLevel() - ); - - return $circleMembers[0]->getUserId(); + return $adminUserId; } catch (Throwable $e) { } diff --git a/lib/Service/TeamBoardService.php b/lib/Service/TeamBoardService.php index dc56d32702..b21001385e 100644 --- a/lib/Service/TeamBoardService.php +++ b/lib/Service/TeamBoardService.php @@ -19,28 +19,21 @@ public function __construct( } /** - * When user is deleted all the boards attached to the team are transfered to another team member - * - * @return int[] + * When user is deleted transfer team boards to another owner/admin when possible,otherwise delete them. */ - public function transferTeamBoardsFromDeletedUser(string $userId): array { - $transferredBoardIds = []; + public function handleBoardsOwnedByDeletedUser(string $userId): void { foreach ($this->boardMapper->findAllByOwner($userId) as $board) { $teamId = $board->getTeamId(); - if ($teamId === null || $teamId === '') { - continue; + if ($teamId !== null && $teamId !== '') {s + $nextOwner = $this->circlesService->findNextMemberUserId($teamId, $userId); + if ($nextOwner !== null) { + $this->boardMapper->transferOwnership($userId, $nextOwner, $board->getId()); + continue; + } } - $nextOwner = $this->circlesService->findNextMemberUserId($teamId, $userId); - if ($nextOwner === null) { - continue; - } - - $this->boardMapper->transferOwnership($userId, $nextOwner, $board->getId()); - $transferredBoardIds[] = $board->getId(); + $this->boardMapper->delete($board); } - - return $transferredBoardIds; } /** diff --git a/tests/unit/Service/TeamBoardServiceTest.php b/tests/unit/Service/TeamBoardServiceTest.php index 00d8c0e861..09e8744e65 100644 --- a/tests/unit/Service/TeamBoardServiceTest.php +++ b/tests/unit/Service/TeamBoardServiceTest.php @@ -33,7 +33,7 @@ public function setUp(): void { ); } - public function testTransferTeamBoardsFromDeletedUser(): void { + public function testHandleBoardsOwnedByDeletedUser(): void { $personalBoard = new Board(); $personalBoard->setId(1); $personalBoard->setOwner($this->userId1); @@ -65,7 +65,11 @@ public function testTransferTeamBoardsFromDeletedUser(): void { ->method('transferOwnership') ->with($this->userId1, $this->userId2, 3); - $this->assertSame([3], $this->service->transferTeamBoardsFromDeletedUser($this->userId1)); + $this->boardMapper->expects($this->exactly(2)) + ->method('delete') + ->withConsecutive([$personalBoard], [$orphanedTeamBoard]); + + $this->service->handleBoardsOwnedByDeletedUser($this->userId1); } public function testHandleMemberLeftTeamTransfersOwnership(): void { From ad28a24b57427bb93f9cb07d912d551aa094489e Mon Sep 17 00:00:00 2001 From: samin-z Date: Thu, 27 Aug 2026 11:41:08 +0200 Subject: [PATCH 08/31] transfer deleted-user team boards in listener by highest member level Signed-off-by: samin-z --- lib/Listeners/ParticipantCleanupListener.php | 18 ++++++++- lib/Service/CirclesService.php | 12 +++--- lib/Service/TeamBoardService.php | 18 --------- tests/unit/Service/TeamBoardServiceTest.php | 39 -------------------- 4 files changed, 24 insertions(+), 63 deletions(-) diff --git a/lib/Listeners/ParticipantCleanupListener.php b/lib/Listeners/ParticipantCleanupListener.php index bbc86e0b82..ef7987869b 100644 --- a/lib/Listeners/ParticipantCleanupListener.php +++ b/lib/Listeners/ParticipantCleanupListener.php @@ -13,6 +13,8 @@ use OCA\Deck\Db\Acl; use OCA\Deck\Db\AclMapper; use OCA\Deck\Db\AssignmentMapper; +use OCA\Deck\Db\BoardMapper; +use OCA\Deck\Service\CirclesService; use OCA\Deck\Service\TeamBoardService; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; @@ -24,6 +26,8 @@ class ParticipantCleanupListener implements IEventListener { public function __construct( private AclMapper $aclMapper, private AssignmentMapper $assignmentMapper, + private BoardMapper $boardMapper, + private CirclesService $circlesService, private TeamBoardService $teamBoardService, ) { } @@ -31,7 +35,19 @@ public function __construct( public function handle(Event $event): void { if ($event instanceof UserDeletedEvent) { $userId = $event->getUser()->getUID(); - $this->teamBoardService->handleBoardsOwnedByDeletedUser($userId); + $boards = $this->boardMapper->findAllByOwner($userId); + foreach ($boards as $board) { + $teamId = $board->getTeamId(); + if ($teamId !== null && $teamId !== '') { + $nextOwner = $this->circlesService->findNextMemberUserId($teamId, $userId); + if ($nextOwner !== null) { + $this->boardMapper->transferOwnership($userId, $nextOwner, $board->getId()); + continue; + } + } + $this->boardMapper->delete($board); + } + $this->cleanupByParticipant(Acl::PERMISSION_TYPE_USER, $userId); } diff --git a/lib/Service/CirclesService.php b/lib/Service/CirclesService.php index 7c81e9bb42..71213fb16e 100644 --- a/lib/Service/CirclesService.php +++ b/lib/Service/CirclesService.php @@ -107,7 +107,7 @@ public function getUserCircles(string $userId): array { } /** - * Find a remaining team owner or admin to take over board ownership. + * Find a remaining team member with the highest level to take over board ownership. */ public function findNextMemberUserId(string $circleId, ?string $excludeUserId = null): ?string { if (!$this->circlesEnabled) { @@ -118,7 +118,8 @@ public function findNextMemberUserId(string $circleId, ?string $excludeUserId = $circlesManager = Server::get(CirclesManager::class); $circlesManager->startSuperSession(); $circle = $circlesManager->getCircle($circleId); - $adminUserId = null; + $maxUserId = null; + $maxLevel = -1; foreach ($circle->getMembers() as $member) { if ($member->getUserType() !== Member::TYPE_USER) { continue; @@ -129,12 +130,13 @@ public function findNextMemberUserId(string $circleId, ?string $excludeUserId = if ($member->getLevel() === Member::LEVEL_OWNER) { return $member->getUserId(); } - if ($adminUserId === null && $member->getLevel() >= Member::LEVEL_ADMIN) { - $adminUserId = $member->getUserId(); + if ($member->getLevel() > $maxLevel) { + $maxLevel = $member->getLevel(); + $maxUserId = $member->getUserId(); } } - return $adminUserId; + return $maxUserId; } catch (Throwable $e) { } diff --git a/lib/Service/TeamBoardService.php b/lib/Service/TeamBoardService.php index b21001385e..b52f74df5b 100644 --- a/lib/Service/TeamBoardService.php +++ b/lib/Service/TeamBoardService.php @@ -18,24 +18,6 @@ public function __construct( ) { } - /** - * When user is deleted transfer team boards to another owner/admin when possible,otherwise delete them. - */ - public function handleBoardsOwnedByDeletedUser(string $userId): void { - foreach ($this->boardMapper->findAllByOwner($userId) as $board) { - $teamId = $board->getTeamId(); - if ($teamId !== null && $teamId !== '') {s - $nextOwner = $this->circlesService->findNextMemberUserId($teamId, $userId); - if ($nextOwner !== null) { - $this->boardMapper->transferOwnership($userId, $nextOwner, $board->getId()); - continue; - } - } - - $this->boardMapper->delete($board); - } - } - /** * When a user leaves the team,transfer ownership, or delete board */ diff --git a/tests/unit/Service/TeamBoardServiceTest.php b/tests/unit/Service/TeamBoardServiceTest.php index 09e8744e65..4100e196f7 100644 --- a/tests/unit/Service/TeamBoardServiceTest.php +++ b/tests/unit/Service/TeamBoardServiceTest.php @@ -33,45 +33,6 @@ public function setUp(): void { ); } - public function testHandleBoardsOwnedByDeletedUser(): void { - $personalBoard = new Board(); - $personalBoard->setId(1); - $personalBoard->setOwner($this->userId1); - $personalBoard->setTeamId(null); - - $orphanedTeamBoard = new Board(); - $orphanedTeamBoard->setId(2); - $orphanedTeamBoard->setOwner($this->userId1); - $orphanedTeamBoard->setTeamId('team-a'); - - $transferableBoard = new Board(); - $transferableBoard->setId(3); - $transferableBoard->setOwner($this->userId1); - $transferableBoard->setTeamId('team-b'); - - $this->boardMapper->expects($this->once()) - ->method('findAllByOwner') - ->with($this->userId1) - ->willReturn([$personalBoard, $orphanedTeamBoard, $transferableBoard]); - - $this->circlesService->expects($this->exactly(2)) - ->method('findNextMemberUserId') - ->willReturnMap([ - ['team-a', $this->userId1, null], - ['team-b', $this->userId1, $this->userId2], - ]); - - $this->boardMapper->expects($this->once()) - ->method('transferOwnership') - ->with($this->userId1, $this->userId2, 3); - - $this->boardMapper->expects($this->exactly(2)) - ->method('delete') - ->withConsecutive([$personalBoard], [$orphanedTeamBoard]); - - $this->service->handleBoardsOwnedByDeletedUser($this->userId1); - } - public function testHandleMemberLeftTeamTransfersOwnership(): void { $board = new Board(); $board->setId(10); From 7551d3f26a9a954bc044695e499e988bdf38cae3 Mon Sep 17 00:00:00 2001 From: grnd-alt Date: Thu, 27 Aug 2026 16:39:53 +0200 Subject: [PATCH 09/31] release/1.19.0-beta.2 Signed-off-by: grnd-alt --- appinfo/info.xml | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/appinfo/info.xml b/appinfo/info.xml index aef4674be6..3a6e81071a 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -20,7 +20,7 @@ - 🚀 Get your project organized - 1.19.0-beta.1 + 1.19.0-beta.2 agpl Julius Härtl Deck diff --git a/package-lock.json b/package-lock.json index 45d1311664..8e0a0498c2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "deck", - "version": "1.19.0-beta.1", + "version": "1.19.0-beta.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "deck", - "version": "1.19.0-beta.1", + "version": "1.19.0-beta.2", "license": "agpl", "dependencies": { "@babel/polyfill": "^7.12.1", diff --git a/package.json b/package.json index 09e3a14cbb..8d15492cbd 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "deck", "description": "", - "version": "1.19.0-beta.1", + "version": "1.19.0-beta.2", "authors": [ { "name": "Julius Härtl", From f7eda09b9346c6381a156470282d77a14efe97f6 Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Sat, 29 Aug 2026 00:56:06 +0000 Subject: [PATCH 10/31] fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- l10n/tr.js | 28 ++++++++++++++-------------- l10n/tr.json | 28 ++++++++++++++-------------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/l10n/tr.js b/l10n/tr.js index 7b6747f9c0..81126ec9a8 100644 --- a/l10n/tr.js +++ b/l10n/tr.js @@ -67,8 +67,8 @@ OC.L10N.register( "{user} has restored the attachment {attachment} to card {card}" : "{user}, {card} kartındaki {attachment} dosyasını geri yükledi", "You have commented on card {card}" : "{card} kartı ile ilgili yorum yaptınız", "{user} has commented on card {card}" : "{user}, {card} kartı ile ilgili yorum yaptı", - "Deck" : "Tahta", - "Changes in the Deck app" : "Tahta uygulamasında değişiklik yapıldığında", + "Deck" : "Deste", + "Changes in the Deck app" : "Deste uygulamasında değişiklik yapıldığında", "A board, list or card was changed" : "Bir pano, liste ya da kart değiştirildi", "A comment was created on a card" : "Bir kart için bir yorum yapıldığında", "A card description has been changed" : "Bir kart açıklaması değiştirildi", @@ -88,7 +88,7 @@ OC.L10N.register( "Cards due tomorrow" : "Bitiş tarihi yarın olan kartlar", "Upcoming cards" : "Yaklaşan kartlar", "Load more" : "Diğerlerini yükle", - "Welcome to Nextcloud Deck!" : "Nextcloud Tahta uygulamasına hoş geldiniz!", + "Welcome to Nextcloud Deck!" : "Nextcloud Deste uygulamasına hoş geldiniz!", "The card \"%s\" on \"%s\" has been assigned to you by %s." : "\"%s\" kartı \"%s\" zamanında %s tarafından size atandı.", "{user} has assigned the card {deck-card} on {deck-board} to you." : "{user}, {deck-board} panosundaki {deck-card} kartını size atadı.", "The card \"%1$s\" on \"%2$s\" has reached its due date." : "\"%1$s\" kartının \"%2$s\" zamanında bitiş tarihi geldi.", @@ -98,14 +98,14 @@ OC.L10N.register( "The board \"%s\" has been shared with you by %s." : "\"%s\" panosu %s tarafından sizinle paylaşıldı.", "{user} has shared {deck-board} with you." : "{user}, {deck-card} kartını sizinle paylaştı.", "The remote board %1$s has been shared with you by %2$s" : "%1$s uzak panosu %2$s tarafından sizinle paylaşıldı", - "Deck board" : "Tahta panosu", + "Deck board" : "Deste panosu", "Owned by %1$s" : "Sahibi: %1$s", - "Deck boards, cards and comments" : "Tahta panoları, kartlar ve yorumlar", + "Deck boards, cards and comments" : "Deste panoları, kartlar ve yorumlar", "From %1$s, in %2$s/%3$s, owned by %4$s" : "%1$s tarafından, %2$s/%3$s içinde, sahibi %4$s olan", - "Create a new deck card" : "Yeni tahta kartı oluştur", + "Create a new deck card" : "Yeni Deste kartı oluştur", "Card comments" : "Kart yorumları", "%s on %s" : "%s, %s ile ilgili", - "Deck boards and cards" : "Tahta panoları ve kartlar", + "Deck boards and cards" : "Deste panoları ve kartlar", "No data was provided to create an attachment." : "Bir ek dosya oluşturmak için herhangi bir veri belirtilmedi.", "Finished" : "Tamamlandı", "To review" : "İncelenecek", @@ -131,7 +131,7 @@ OC.L10N.register( "Invalid date, date format must be YYYY-MM-DD" : "Tarih geçersiz. Tarih biçimi YYYY-AA-GG olmalıdır", "All boards owned by you including stacks, cards, labels, assignments, and comments" : "Yığınlar, kartlar, etiketler, ödevler ve yorumlar gibi size ait tüm panolar", "Personal planning and team project organization" : "Kişisel planlama ve takım projesi yönetimi", - "Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Tahta, Nextcloud ile bütünleştirilmiş takımlar için Kanban tarzında bir kişisel planlama ve proje yönetimi uygulamasıdır.\n\n\n- 📥 Görevleri kartlara ekleyerek sıralayabilirsiniz\n- 📄 Markdown ile biçimlendirilmiş notlar ekleyebilirsiniz\n- 🔖 Daha iyi düzenleme için etiketler atayabilirsiniz\n- 👥 Takımınız, arkadaşlarınız ya da aileniz ile paylaşabilirsiniz\n- 📎 Dosyalar ekleyebilir ve Markdown açıklamasına gömebilirsiniz\n- 💬 Yorumları kullanarak konular üzerinde takımınız ile yazışabilirsiniz\n- ⚡ İşlem akışı ile değişiklikleri görebilirsiniz\n- 🚀 Projelerinizi düzenli tutarak izleyebilirsiniz", + "Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deste, Nextcloud ile bütünleştirilmiş takımlar için Kanban tarzında bir kişisel planlama ve proje yönetimi uygulamasıdır.\n\n\n- 📥 Görevleri kartlara ekleyerek sıralayabilirsiniz\n- 📄 Markdown ile biçimlendirilmiş notlar ekleyebilirsiniz\n- 🔖 Daha iyi düzenleme için etiketler atayabilirsiniz\n- 👥 Takımınız, arkadaşlarınız ya da aileniz ile paylaşabilirsiniz\n- 📎 Dosyalar ekleyebilir ve Markdown açıklamasına gömebilirsiniz\n- 💬 Yorumları kullanarak konular üzerinde takımınız ile yazışabilirsiniz\n- ⚡ İşlem akışı ile değişiklikleri görebilirsiniz\n- 🚀 Projelerinizi düzenli tutarak izleyebilirsiniz", "Add board" : "Pano ekle", "Card details" : "Kart ayrıntıları", "Select the board to link to a project" : "Bir proje ile ilişkilendirilecek pano bağlantısını seçin", @@ -181,12 +181,12 @@ OC.L10N.register( "Gantt view" : "Gantt görünümü", "Hide archived cards" : "Arşivlenmiş kartları gizle", "Show archived cards" : "Arşivlenmiş kartları görüntüle", - "Toggle compact mode" : "Sıkışık kipi aç/kapat", + "Toggle compact mode" : "Dar kipi aç/kapat", "Hide card cover images" : "Kart kapak görsellerini gizle", "Show card cover images" : "Kart kapak görsellerini görüntüle", "Open details" : "Ayrıntıları aç", "Details" : "Ayrıntılar", - "Deck settings" : "Tahta ayarları", + "Deck settings" : "Deste ayarları", "General" : "Genel", "Use bigger card view" : "Daha büyük kart görünümü kullanılsın", "Appearance" : "Görünüm", @@ -396,13 +396,13 @@ OC.L10N.register( "Export {boardTitle}" : "{boardTitle} panosunu dışa aktar", "Export as JSON" : "JSON olarak dışa aktar", "Export as CSV" : "CSV olarak dışa aktar", - "Note: Only the JSON format is supported for importing back into the Deck app." : "Not: Yeniden Tahta uygulaması içine aktarmak için yalnızca JSON biçimi desteklenir.", + "Note: Only the JSON format is supported for importing back into the Deck app." : "Not: Deste uygulaması içine aktarmak için yalnızca JSON biçimi desteklenir.", "Export" : "Dışa aktar", "Loading filtered view" : "Süzülmüş görünüm yükleniyor", "Search for {searchQuery} in other boards" : "Diğer panolarda {searchQuery} ara", "Search for {searchQuery} in all boards" : "Tüm panolarda {searchQuery} ara", "No results found" : "Herhangi bir sonuç bulunamadı", - "Deck board {name}\n* Last modified on {lastMod}" : "{name} tahta panosu\n* Son değişiklik: {lastMod}", + "Deck board {name}\n* Last modified on {lastMod}" : "{name} Deste panosu\n* Son değişiklik: {lastMod}", "* Created on {created}\n* Last modified on {lastMod}\n* {nbAttachments} attachments\n* {nbComments} comments" : "* Oluşturulma: {created}\n* Son değiştirilme: {lastMod}\n* {nbAttachments} ek dosya\n* {nbComments} yorum", "{nbCards} cards" : "{nbCards} kart", "Due on {date}" : "{date} tarihinde bitecek", @@ -433,8 +433,8 @@ OC.L10N.register( "Created" : "Oluşturulma", "Modified" : "Değiştirilme", "Error creating the share" : "Paylaşım oluşturulurken sorun çıktı", - "Share with a Deck card" : "Bir tahta kartı ile paylaş", - "Share {file} with a Deck card" : "{file} dosyasını bir tahta kartı ile paylaş", + "Share with a Deck card" : "Bir Deste kartı ile paylaş", + "Share {file} with a Deck card" : "{file} dosyasını bir Deste kartı ile paylaş", "Share" : "Paylaş", "The card \"%s\" on \"%s\" has reached its due date." : "\"%s\" kartı \"%s\" zamanında son kullanma tarihine ulaştı.", "Share board with a user, group or team …" : "Panoyu kullanıcı, grup ya da takımla paylaş…", diff --git a/l10n/tr.json b/l10n/tr.json index 8249cb4712..7e07540436 100644 --- a/l10n/tr.json +++ b/l10n/tr.json @@ -65,8 +65,8 @@ "{user} has restored the attachment {attachment} to card {card}" : "{user}, {card} kartındaki {attachment} dosyasını geri yükledi", "You have commented on card {card}" : "{card} kartı ile ilgili yorum yaptınız", "{user} has commented on card {card}" : "{user}, {card} kartı ile ilgili yorum yaptı", - "Deck" : "Tahta", - "Changes in the Deck app" : "Tahta uygulamasında değişiklik yapıldığında", + "Deck" : "Deste", + "Changes in the Deck app" : "Deste uygulamasında değişiklik yapıldığında", "A board, list or card was changed" : "Bir pano, liste ya da kart değiştirildi", "A comment was created on a card" : "Bir kart için bir yorum yapıldığında", "A card description has been changed" : "Bir kart açıklaması değiştirildi", @@ -86,7 +86,7 @@ "Cards due tomorrow" : "Bitiş tarihi yarın olan kartlar", "Upcoming cards" : "Yaklaşan kartlar", "Load more" : "Diğerlerini yükle", - "Welcome to Nextcloud Deck!" : "Nextcloud Tahta uygulamasına hoş geldiniz!", + "Welcome to Nextcloud Deck!" : "Nextcloud Deste uygulamasına hoş geldiniz!", "The card \"%s\" on \"%s\" has been assigned to you by %s." : "\"%s\" kartı \"%s\" zamanında %s tarafından size atandı.", "{user} has assigned the card {deck-card} on {deck-board} to you." : "{user}, {deck-board} panosundaki {deck-card} kartını size atadı.", "The card \"%1$s\" on \"%2$s\" has reached its due date." : "\"%1$s\" kartının \"%2$s\" zamanında bitiş tarihi geldi.", @@ -96,14 +96,14 @@ "The board \"%s\" has been shared with you by %s." : "\"%s\" panosu %s tarafından sizinle paylaşıldı.", "{user} has shared {deck-board} with you." : "{user}, {deck-card} kartını sizinle paylaştı.", "The remote board %1$s has been shared with you by %2$s" : "%1$s uzak panosu %2$s tarafından sizinle paylaşıldı", - "Deck board" : "Tahta panosu", + "Deck board" : "Deste panosu", "Owned by %1$s" : "Sahibi: %1$s", - "Deck boards, cards and comments" : "Tahta panoları, kartlar ve yorumlar", + "Deck boards, cards and comments" : "Deste panoları, kartlar ve yorumlar", "From %1$s, in %2$s/%3$s, owned by %4$s" : "%1$s tarafından, %2$s/%3$s içinde, sahibi %4$s olan", - "Create a new deck card" : "Yeni tahta kartı oluştur", + "Create a new deck card" : "Yeni Deste kartı oluştur", "Card comments" : "Kart yorumları", "%s on %s" : "%s, %s ile ilgili", - "Deck boards and cards" : "Tahta panoları ve kartlar", + "Deck boards and cards" : "Deste panoları ve kartlar", "No data was provided to create an attachment." : "Bir ek dosya oluşturmak için herhangi bir veri belirtilmedi.", "Finished" : "Tamamlandı", "To review" : "İncelenecek", @@ -129,7 +129,7 @@ "Invalid date, date format must be YYYY-MM-DD" : "Tarih geçersiz. Tarih biçimi YYYY-AA-GG olmalıdır", "All boards owned by you including stacks, cards, labels, assignments, and comments" : "Yığınlar, kartlar, etiketler, ödevler ve yorumlar gibi size ait tüm panolar", "Personal planning and team project organization" : "Kişisel planlama ve takım projesi yönetimi", - "Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Tahta, Nextcloud ile bütünleştirilmiş takımlar için Kanban tarzında bir kişisel planlama ve proje yönetimi uygulamasıdır.\n\n\n- 📥 Görevleri kartlara ekleyerek sıralayabilirsiniz\n- 📄 Markdown ile biçimlendirilmiş notlar ekleyebilirsiniz\n- 🔖 Daha iyi düzenleme için etiketler atayabilirsiniz\n- 👥 Takımınız, arkadaşlarınız ya da aileniz ile paylaşabilirsiniz\n- 📎 Dosyalar ekleyebilir ve Markdown açıklamasına gömebilirsiniz\n- 💬 Yorumları kullanarak konular üzerinde takımınız ile yazışabilirsiniz\n- ⚡ İşlem akışı ile değişiklikleri görebilirsiniz\n- 🚀 Projelerinizi düzenli tutarak izleyebilirsiniz", + "Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deste, Nextcloud ile bütünleştirilmiş takımlar için Kanban tarzında bir kişisel planlama ve proje yönetimi uygulamasıdır.\n\n\n- 📥 Görevleri kartlara ekleyerek sıralayabilirsiniz\n- 📄 Markdown ile biçimlendirilmiş notlar ekleyebilirsiniz\n- 🔖 Daha iyi düzenleme için etiketler atayabilirsiniz\n- 👥 Takımınız, arkadaşlarınız ya da aileniz ile paylaşabilirsiniz\n- 📎 Dosyalar ekleyebilir ve Markdown açıklamasına gömebilirsiniz\n- 💬 Yorumları kullanarak konular üzerinde takımınız ile yazışabilirsiniz\n- ⚡ İşlem akışı ile değişiklikleri görebilirsiniz\n- 🚀 Projelerinizi düzenli tutarak izleyebilirsiniz", "Add board" : "Pano ekle", "Card details" : "Kart ayrıntıları", "Select the board to link to a project" : "Bir proje ile ilişkilendirilecek pano bağlantısını seçin", @@ -179,12 +179,12 @@ "Gantt view" : "Gantt görünümü", "Hide archived cards" : "Arşivlenmiş kartları gizle", "Show archived cards" : "Arşivlenmiş kartları görüntüle", - "Toggle compact mode" : "Sıkışık kipi aç/kapat", + "Toggle compact mode" : "Dar kipi aç/kapat", "Hide card cover images" : "Kart kapak görsellerini gizle", "Show card cover images" : "Kart kapak görsellerini görüntüle", "Open details" : "Ayrıntıları aç", "Details" : "Ayrıntılar", - "Deck settings" : "Tahta ayarları", + "Deck settings" : "Deste ayarları", "General" : "Genel", "Use bigger card view" : "Daha büyük kart görünümü kullanılsın", "Appearance" : "Görünüm", @@ -394,13 +394,13 @@ "Export {boardTitle}" : "{boardTitle} panosunu dışa aktar", "Export as JSON" : "JSON olarak dışa aktar", "Export as CSV" : "CSV olarak dışa aktar", - "Note: Only the JSON format is supported for importing back into the Deck app." : "Not: Yeniden Tahta uygulaması içine aktarmak için yalnızca JSON biçimi desteklenir.", + "Note: Only the JSON format is supported for importing back into the Deck app." : "Not: Deste uygulaması içine aktarmak için yalnızca JSON biçimi desteklenir.", "Export" : "Dışa aktar", "Loading filtered view" : "Süzülmüş görünüm yükleniyor", "Search for {searchQuery} in other boards" : "Diğer panolarda {searchQuery} ara", "Search for {searchQuery} in all boards" : "Tüm panolarda {searchQuery} ara", "No results found" : "Herhangi bir sonuç bulunamadı", - "Deck board {name}\n* Last modified on {lastMod}" : "{name} tahta panosu\n* Son değişiklik: {lastMod}", + "Deck board {name}\n* Last modified on {lastMod}" : "{name} Deste panosu\n* Son değişiklik: {lastMod}", "* Created on {created}\n* Last modified on {lastMod}\n* {nbAttachments} attachments\n* {nbComments} comments" : "* Oluşturulma: {created}\n* Son değiştirilme: {lastMod}\n* {nbAttachments} ek dosya\n* {nbComments} yorum", "{nbCards} cards" : "{nbCards} kart", "Due on {date}" : "{date} tarihinde bitecek", @@ -431,8 +431,8 @@ "Created" : "Oluşturulma", "Modified" : "Değiştirilme", "Error creating the share" : "Paylaşım oluşturulurken sorun çıktı", - "Share with a Deck card" : "Bir tahta kartı ile paylaş", - "Share {file} with a Deck card" : "{file} dosyasını bir tahta kartı ile paylaş", + "Share with a Deck card" : "Bir Deste kartı ile paylaş", + "Share {file} with a Deck card" : "{file} dosyasını bir Deste kartı ile paylaş", "Share" : "Paylaş", "The card \"%s\" on \"%s\" has reached its due date." : "\"%s\" kartı \"%s\" zamanında son kullanma tarihine ulaştı.", "Share board with a user, group or team …" : "Panoyu kullanıcı, grup ya da takımla paylaş…", From e666a2c13733e3ca33a275cfd8f0067faa86a5a6 Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Mon, 31 Aug 2026 00:53:17 +0000 Subject: [PATCH 11/31] fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- l10n/de.js | 1 + l10n/de.json | 1 + l10n/de_DE.js | 1 + l10n/de_DE.json | 1 + l10n/fr.js | 2 ++ l10n/fr.json | 2 ++ l10n/pt_BR.js | 1 + l10n/pt_BR.json | 1 + l10n/sv.js | 4 ++++ l10n/sv.json | 4 ++++ l10n/tr.js | 1 + l10n/tr.json | 1 + 12 files changed, 20 insertions(+) diff --git a/l10n/de.js b/l10n/de.js index eee91d2fe7..1d8bbb06d5 100644 --- a/l10n/de.js +++ b/l10n/de.js @@ -189,6 +189,7 @@ OC.L10N.register( "Deck settings" : "Deck-Einstellungen", "General" : "Allgemein", "Use bigger card view" : "Größere Kartenansicht verwenden", + "Add new cards at the top of a list" : "Neue Karten oben in einer Liste hinzufügen", "Appearance" : "Aussehen", "Show card ID badge" : "Abzeichen mit Karten-ID zeigen", "Show boards in calendar/tasks" : "Board in Kalender/Aufgaben anzeigen", diff --git a/l10n/de.json b/l10n/de.json index 3802fc14c6..4a6455a8fb 100644 --- a/l10n/de.json +++ b/l10n/de.json @@ -187,6 +187,7 @@ "Deck settings" : "Deck-Einstellungen", "General" : "Allgemein", "Use bigger card view" : "Größere Kartenansicht verwenden", + "Add new cards at the top of a list" : "Neue Karten oben in einer Liste hinzufügen", "Appearance" : "Aussehen", "Show card ID badge" : "Abzeichen mit Karten-ID zeigen", "Show boards in calendar/tasks" : "Board in Kalender/Aufgaben anzeigen", diff --git a/l10n/de_DE.js b/l10n/de_DE.js index c95fb47049..40963c3b56 100644 --- a/l10n/de_DE.js +++ b/l10n/de_DE.js @@ -189,6 +189,7 @@ OC.L10N.register( "Deck settings" : "Deck-Einstellungen", "General" : "Allgemein", "Use bigger card view" : "Größere Kartenansicht verwenden", + "Add new cards at the top of a list" : "Neue Karten oben in einer Liste hinzufügen", "Appearance" : "Aussehen", "Show card ID badge" : "Abzeichen mit Karten-ID zeigen", "Show boards in calendar/tasks" : "Board in Kalender/Aufgaben anzeigen", diff --git a/l10n/de_DE.json b/l10n/de_DE.json index 4b85488477..c0649e21b1 100644 --- a/l10n/de_DE.json +++ b/l10n/de_DE.json @@ -187,6 +187,7 @@ "Deck settings" : "Deck-Einstellungen", "General" : "Allgemein", "Use bigger card view" : "Größere Kartenansicht verwenden", + "Add new cards at the top of a list" : "Neue Karten oben in einer Liste hinzufügen", "Appearance" : "Aussehen", "Show card ID badge" : "Abzeichen mit Karten-ID zeigen", "Show boards in calendar/tasks" : "Board in Kalender/Aufgaben anzeigen", diff --git a/l10n/fr.js b/l10n/fr.js index 23b9de02c9..b5631903df 100644 --- a/l10n/fr.js +++ b/l10n/fr.js @@ -189,6 +189,7 @@ OC.L10N.register( "Deck settings" : "Paramètres de Deck", "General" : "Général", "Use bigger card view" : "Utiliser la vue large des cartes", + "Add new cards at the top of a list" : "Ajouter de nouvelles cartes en haut d'une liste", "Appearance" : "Apparence", "Show card ID badge" : "Afficher l'ID de la carte", "Show boards in calendar/tasks" : "Afficher les tableaux dans les agendas/tâches", @@ -212,6 +213,7 @@ OC.L10N.register( "Mark card as completed/not completed" : "Marquer la carte (non) terminée", "Open card menu" : "Ouvrir le menu de la carte", "Currently present people" : "Personnes actuellement présentes", + "Supported prefixes: {prefixes}. Wrap phrases in double quotes." : "Préfixes pris en charge : {prefixes}. Placez les expressions entre guillemets doubles.", "Search cards" : "Rechercher des cartes", "Loading board" : "Chargement du tableau…", "Board not found" : "Tableau non trouvé", diff --git a/l10n/fr.json b/l10n/fr.json index 1fd46b1016..5d4ddf921f 100644 --- a/l10n/fr.json +++ b/l10n/fr.json @@ -187,6 +187,7 @@ "Deck settings" : "Paramètres de Deck", "General" : "Général", "Use bigger card view" : "Utiliser la vue large des cartes", + "Add new cards at the top of a list" : "Ajouter de nouvelles cartes en haut d'une liste", "Appearance" : "Apparence", "Show card ID badge" : "Afficher l'ID de la carte", "Show boards in calendar/tasks" : "Afficher les tableaux dans les agendas/tâches", @@ -210,6 +211,7 @@ "Mark card as completed/not completed" : "Marquer la carte (non) terminée", "Open card menu" : "Ouvrir le menu de la carte", "Currently present people" : "Personnes actuellement présentes", + "Supported prefixes: {prefixes}. Wrap phrases in double quotes." : "Préfixes pris en charge : {prefixes}. Placez les expressions entre guillemets doubles.", "Search cards" : "Rechercher des cartes", "Loading board" : "Chargement du tableau…", "Board not found" : "Tableau non trouvé", diff --git a/l10n/pt_BR.js b/l10n/pt_BR.js index 10c20ee0b0..4398563e72 100644 --- a/l10n/pt_BR.js +++ b/l10n/pt_BR.js @@ -189,6 +189,7 @@ OC.L10N.register( "Deck settings" : "Configurações do Deck", "General" : "Geral", "Use bigger card view" : "Use uma exibição de cartão maior", + "Add new cards at the top of a list" : "Adicionar novos cartões no topo de uma lista", "Appearance" : "Aparência", "Show card ID badge" : "Exibir o distintivo de identificação do cartão", "Show boards in calendar/tasks" : "Exibir os painéis em calendários/tarefas", diff --git a/l10n/pt_BR.json b/l10n/pt_BR.json index dd4747ab8b..72fd667cf1 100644 --- a/l10n/pt_BR.json +++ b/l10n/pt_BR.json @@ -187,6 +187,7 @@ "Deck settings" : "Configurações do Deck", "General" : "Geral", "Use bigger card view" : "Use uma exibição de cartão maior", + "Add new cards at the top of a list" : "Adicionar novos cartões no topo de uma lista", "Appearance" : "Aparência", "Show card ID badge" : "Exibir o distintivo de identificação do cartão", "Show boards in calendar/tasks" : "Exibir os painéis em calendários/tarefas", diff --git a/l10n/sv.js b/l10n/sv.js index 4826f0d850..5d6d231548 100644 --- a/l10n/sv.js +++ b/l10n/sv.js @@ -189,6 +189,7 @@ OC.L10N.register( "Deck settings" : "Deck-inställningar", "General" : "Allmänt", "Use bigger card view" : "Visa större kort", + "Add new cards at the top of a list" : "Lägg till nya kort högst upp i en lista", "Appearance" : "Utseende", "Show card ID badge" : "Visa kortets ID-märke", "Show boards in calendar/tasks" : "Visa tavlor i kalender / uppgifter", @@ -212,6 +213,8 @@ OC.L10N.register( "Mark card as completed/not completed" : "Markera kortet som slutfört/inte slutfört", "Open card menu" : "Öppna kortmenyn", "Currently present people" : "Närvarande personer", + "Supported prefixes: {prefixes}. Wrap phrases in double quotes." : "Prefix som stöds: {prefixes}. Omge fraser med dubbla citattecken.", + "Search cards" : "Sök kort", "Loading board" : "Läser in tavla", "Board not found" : "Tavlan hittades inte", "Create a new list to add cards to this board" : "Skapa en ny lista för att lägga till kort på denna tavla", @@ -258,6 +261,7 @@ OC.L10N.register( "title and color value must be provided" : "titel och färg måste anges", "Edit" : "Redigera", "Add a new tag" : "Lägg till en ny tagg", + "Search boards" : "Sök tavlor", "Board name" : "Tavlans namn", "Members" : "Medlemmar", "Assign to users/groups/team" : "Tilldela användare, grupper eller team", diff --git a/l10n/sv.json b/l10n/sv.json index c29f894a5f..b3e4ba5f65 100644 --- a/l10n/sv.json +++ b/l10n/sv.json @@ -187,6 +187,7 @@ "Deck settings" : "Deck-inställningar", "General" : "Allmänt", "Use bigger card view" : "Visa större kort", + "Add new cards at the top of a list" : "Lägg till nya kort högst upp i en lista", "Appearance" : "Utseende", "Show card ID badge" : "Visa kortets ID-märke", "Show boards in calendar/tasks" : "Visa tavlor i kalender / uppgifter", @@ -210,6 +211,8 @@ "Mark card as completed/not completed" : "Markera kortet som slutfört/inte slutfört", "Open card menu" : "Öppna kortmenyn", "Currently present people" : "Närvarande personer", + "Supported prefixes: {prefixes}. Wrap phrases in double quotes." : "Prefix som stöds: {prefixes}. Omge fraser med dubbla citattecken.", + "Search cards" : "Sök kort", "Loading board" : "Läser in tavla", "Board not found" : "Tavlan hittades inte", "Create a new list to add cards to this board" : "Skapa en ny lista för att lägga till kort på denna tavla", @@ -256,6 +259,7 @@ "title and color value must be provided" : "titel och färg måste anges", "Edit" : "Redigera", "Add a new tag" : "Lägg till en ny tagg", + "Search boards" : "Sök tavlor", "Board name" : "Tavlans namn", "Members" : "Medlemmar", "Assign to users/groups/team" : "Tilldela användare, grupper eller team", diff --git a/l10n/tr.js b/l10n/tr.js index 81126ec9a8..e3444d2f90 100644 --- a/l10n/tr.js +++ b/l10n/tr.js @@ -189,6 +189,7 @@ OC.L10N.register( "Deck settings" : "Deste ayarları", "General" : "Genel", "Use bigger card view" : "Daha büyük kart görünümü kullanılsın", + "Add new cards at the top of a list" : "Yeni kartlar bir listenin en üstüne eklensin", "Appearance" : "Görünüm", "Show card ID badge" : "Kart kimliği etiketi görüntülensin", "Show boards in calendar/tasks" : "Takvimler ve görevlerde panolar görüntülensin", diff --git a/l10n/tr.json b/l10n/tr.json index 7e07540436..151e622ff2 100644 --- a/l10n/tr.json +++ b/l10n/tr.json @@ -187,6 +187,7 @@ "Deck settings" : "Deste ayarları", "General" : "Genel", "Use bigger card view" : "Daha büyük kart görünümü kullanılsın", + "Add new cards at the top of a list" : "Yeni kartlar bir listenin en üstüne eklensin", "Appearance" : "Görünüm", "Show card ID badge" : "Kart kimliği etiketi görüntülensin", "Show boards in calendar/tasks" : "Takvimler ve görevlerde panolar görüntülensin", From a88613c90c307a69d26cd068a07fa47cd6ce2610 Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Tue, 1 Sep 2026 00:54:51 +0000 Subject: [PATCH 12/31] fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- l10n/et_EE.js | 1 + l10n/et_EE.json | 1 + l10n/lb.js | 10 ++++++++++ l10n/lb.json | 10 ++++++++++ l10n/zh_TW.js | 1 + l10n/zh_TW.json | 1 + 6 files changed, 24 insertions(+) diff --git a/l10n/et_EE.js b/l10n/et_EE.js index efb1060602..a8e1fed6bf 100644 --- a/l10n/et_EE.js +++ b/l10n/et_EE.js @@ -189,6 +189,7 @@ OC.L10N.register( "Deck settings" : "Kanbani rakenduse seadistused", "General" : "Üldine", "Use bigger card view" : "Kasuta suuremat kaardivaadet", + "Add new cards at the top of a list" : "Lisa uued kaardid loendi ülaossa", "Appearance" : "Välimus", "Show card ID badge" : "Näita silti kaardi tunnusega", "Show boards in calendar/tasks" : "Näita tahvleid kalendrite ja ülesannete vaates", diff --git a/l10n/et_EE.json b/l10n/et_EE.json index 77b7b5907b..086c187435 100644 --- a/l10n/et_EE.json +++ b/l10n/et_EE.json @@ -187,6 +187,7 @@ "Deck settings" : "Kanbani rakenduse seadistused", "General" : "Üldine", "Use bigger card view" : "Kasuta suuremat kaardivaadet", + "Add new cards at the top of a list" : "Lisa uued kaardid loendi ülaossa", "Appearance" : "Välimus", "Show card ID badge" : "Näita silti kaardi tunnusega", "Show boards in calendar/tasks" : "Näita tahvleid kalendrite ja ülesannete vaates", diff --git a/l10n/lb.js b/l10n/lb.js index 1417df39e7..d7162c5a9d 100644 --- a/l10n/lb.js +++ b/l10n/lb.js @@ -6,9 +6,13 @@ OC.L10N.register( "The file was only partially uploaded" : "D'Datei gouf nëmmen deelweis eropgelueden", "No file was uploaded" : "Et ass kee Fichier ropgeluede ginn", "Missing a temporary folder" : "Et feelt en temporären Dossier", + "Later" : "Spéider", "In Progress" : "A Beaarbechtung", "Done" : "Done", + "File" : "Fichier", "Cancel" : "Ofbriechen", + "Unassigned" : "Net zougewisen", + "Open" : "Op", "Completed" : "Erfëllt", "Details" : "Detailer", "General" : "Allgemeng", @@ -17,6 +21,10 @@ OC.L10N.register( "Tags" : "Tags", "Activity" : "Aktivitéit", "Hours" : "Stonnen", + "Days" : "Deeg", + "Transfer" : "Iwwerdroen", + "(Group)" : "(Grupp)", + "(remote)" : "(extern)", "Can edit" : "Can edit", "Can share" : "Can share", "Owner" : "Owner", @@ -24,12 +32,14 @@ OC.L10N.register( "Edit" : "Änneren", "Download" : "Eroflueden", "Comments" : "Kommentarer", + "Submit" : "Iwwermëttelen", "Created:" : "Erstallt:", "Reply" : "Äntwerten", "Update" : "Update", "Description" : "Beschreiwung", "Shared with you" : "Mat dir gedeelt", "Advanced options" : "Erweidert Astellungen", + "Clone" : "Klonen", "Export" : "Exportéieren", "Close" : "Zoumaachen", "Modified" : "Geännert", diff --git a/l10n/lb.json b/l10n/lb.json index 49674162e4..4c8c8d8ded 100644 --- a/l10n/lb.json +++ b/l10n/lb.json @@ -4,9 +4,13 @@ "The file was only partially uploaded" : "D'Datei gouf nëmmen deelweis eropgelueden", "No file was uploaded" : "Et ass kee Fichier ropgeluede ginn", "Missing a temporary folder" : "Et feelt en temporären Dossier", + "Later" : "Spéider", "In Progress" : "A Beaarbechtung", "Done" : "Done", + "File" : "Fichier", "Cancel" : "Ofbriechen", + "Unassigned" : "Net zougewisen", + "Open" : "Op", "Completed" : "Erfëllt", "Details" : "Detailer", "General" : "Allgemeng", @@ -15,6 +19,10 @@ "Tags" : "Tags", "Activity" : "Aktivitéit", "Hours" : "Stonnen", + "Days" : "Deeg", + "Transfer" : "Iwwerdroen", + "(Group)" : "(Grupp)", + "(remote)" : "(extern)", "Can edit" : "Can edit", "Can share" : "Can share", "Owner" : "Owner", @@ -22,12 +30,14 @@ "Edit" : "Änneren", "Download" : "Eroflueden", "Comments" : "Kommentarer", + "Submit" : "Iwwermëttelen", "Created:" : "Erstallt:", "Reply" : "Äntwerten", "Update" : "Update", "Description" : "Beschreiwung", "Shared with you" : "Mat dir gedeelt", "Advanced options" : "Erweidert Astellungen", + "Clone" : "Klonen", "Export" : "Exportéieren", "Close" : "Zoumaachen", "Modified" : "Geännert", diff --git a/l10n/zh_TW.js b/l10n/zh_TW.js index 6f66779c73..2d189ee412 100644 --- a/l10n/zh_TW.js +++ b/l10n/zh_TW.js @@ -189,6 +189,7 @@ OC.L10N.register( "Deck settings" : "Deck 設定", "General" : "一般", "Use bigger card view" : "使用較大的卡片檢視", + "Add new cards at the top of a list" : "將新卡片新增至清單頂部", "Appearance" : "外觀", "Show card ID badge" : "顯示卡片 ID 徽章", "Show boards in calendar/tasks" : "在日曆/工作項目中顯示佈告欄", diff --git a/l10n/zh_TW.json b/l10n/zh_TW.json index 1397cf6b70..4ba2f4c788 100644 --- a/l10n/zh_TW.json +++ b/l10n/zh_TW.json @@ -187,6 +187,7 @@ "Deck settings" : "Deck 設定", "General" : "一般", "Use bigger card view" : "使用較大的卡片檢視", + "Add new cards at the top of a list" : "將新卡片新增至清單頂部", "Appearance" : "外觀", "Show card ID badge" : "顯示卡片 ID 徽章", "Show boards in calendar/tasks" : "在日曆/工作項目中顯示佈告欄", From e5ef5cdead3d58162b1848e5018b48fd503dc64c Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Thu, 3 Sep 2026 00:53:56 +0000 Subject: [PATCH 13/31] fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- l10n/is.js | 2 ++ l10n/is.json | 2 ++ 2 files changed, 4 insertions(+) diff --git a/l10n/is.js b/l10n/is.js index 3b3d35a94d..fb3fc499bb 100644 --- a/l10n/is.js +++ b/l10n/is.js @@ -119,6 +119,7 @@ OC.L10N.register( "Create your first card!" : "Útbúðu fyrsta spjaldið þitt!", "This comment has more than %s characters.\nAdded as an attachment to the card with name %s.\nAccessible on URL: %s." : "Þessi athugasemd er lengri en %s stafir.\nBætt við sem viðhengi á spjald með heitinu %s.\nAðgengileg á slóðinni: %s.", "Attachments" : "Viðhengi", + "File" : "Skrá", "Card not found" : "Spjald fannst ekki", "Path is already shared with this card" : "Slóðinni er þegar deilt með þessu spjaldi", "Invalid date, date format must be YYYY-MM-DD" : "Ógild dagsetning, dagsetningasniðið verður að vera ÁÁÁÁ-MM-DD", @@ -184,6 +185,7 @@ OC.L10N.register( "Show boards in calendar/tasks" : "Birta borð í dagatali/verkefnum", "Limit board creation to some groups" : "Takmarka gerð borða við suma hópa", "Users outside of those groups will not be able to create their own boards, but will still be able to work on boards that have been shared with them." : "Notendur sem tilheyra ekki þessum hópum eru útilokaðir frá því að útbúa sín eigin borð, en munu samt geta áfram unnið með borð sem hefur verið deilt til þeirra.", + "Enable federation" : "Virkja skýjasamband", "Board actions" : "Aðgerðir borðs", "Scroll sideways" : "Skruna til hliðar", "Navigate between cards" : "Flakka á milli spjalda", diff --git a/l10n/is.json b/l10n/is.json index 00f32ba5fe..bbaab6c8ae 100644 --- a/l10n/is.json +++ b/l10n/is.json @@ -117,6 +117,7 @@ "Create your first card!" : "Útbúðu fyrsta spjaldið þitt!", "This comment has more than %s characters.\nAdded as an attachment to the card with name %s.\nAccessible on URL: %s." : "Þessi athugasemd er lengri en %s stafir.\nBætt við sem viðhengi á spjald með heitinu %s.\nAðgengileg á slóðinni: %s.", "Attachments" : "Viðhengi", + "File" : "Skrá", "Card not found" : "Spjald fannst ekki", "Path is already shared with this card" : "Slóðinni er þegar deilt með þessu spjaldi", "Invalid date, date format must be YYYY-MM-DD" : "Ógild dagsetning, dagsetningasniðið verður að vera ÁÁÁÁ-MM-DD", @@ -182,6 +183,7 @@ "Show boards in calendar/tasks" : "Birta borð í dagatali/verkefnum", "Limit board creation to some groups" : "Takmarka gerð borða við suma hópa", "Users outside of those groups will not be able to create their own boards, but will still be able to work on boards that have been shared with them." : "Notendur sem tilheyra ekki þessum hópum eru útilokaðir frá því að útbúa sín eigin borð, en munu samt geta áfram unnið með borð sem hefur verið deilt til þeirra.", + "Enable federation" : "Virkja skýjasamband", "Board actions" : "Aðgerðir borðs", "Scroll sideways" : "Skruna til hliðar", "Navigate between cards" : "Flakka á milli spjalda", From e1ea391e708c88f8a53c7aa81f6109f1a2663b58 Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Fri, 4 Sep 2026 00:56:55 +0000 Subject: [PATCH 14/31] fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- l10n/pt_BR.js | 206 ++++++++++++++++++++++++------------------------ l10n/pt_BR.json | 206 ++++++++++++++++++++++++------------------------ l10n/sk.js | 18 +++++ l10n/sk.json | 18 +++++ 4 files changed, 242 insertions(+), 206 deletions(-) diff --git a/l10n/pt_BR.js b/l10n/pt_BR.js index 4398563e72..96c9647eef 100644 --- a/l10n/pt_BR.js +++ b/l10n/pt_BR.js @@ -1,60 +1,60 @@ OC.L10N.register( "deck", { - "You have created a new board {board}" : "Você criou um novo painel {board}", - "{user} has created a new board {board}" : "{user} criou um novo painel {board}", - "You have deleted the board {board}" : "Você excluiu o painel {board}", - "{user} has deleted the board {board}" : "{user} excluiu o painel {board}", - "You have restored the board {board}" : "Você restaurou o painel {board}", - "{user} has restored the board {board}" : "{user} restaurou o painel {board}", - "You have shared the board {board} with {acl}" : "Você compartilhou o painel {board} com {acl}", - "{user} has shared the board {board} with {acl}" : "{user} compartilhou o painel {board} com {acl}", - "You have removed {acl} from the board {board}" : "Você excluiu {acl} do painel {board}", - "{user} has removed {acl} from the board {board}" : "{user} excluiu {acl} do painel {board}", - "You have renamed the board {before} to {board}" : "Você renomeou o painel {before} para {board}", - "{user} has renamed the board {before} to {board}" : "{user} renomeou o painel {before} para {board}", - "You have archived the board {board}" : "Você arquivou o painel {board}", - "{user} has archived the board {before}" : "{user} arquivou o painel {before}", - "You have unarchived the board {board}" : "Você desarquivou o painel {board}", - "{user} has unarchived the board {before}" : "{user} desarquivou o painel {board}", - "You have created a new list {stack} on board {board}" : "Você criou uma nova lista {stack} no painel {board}", - "{user} has created a new list {stack} on board {board}" : "{user} criou uma nova lista {stack} no painel {board}", - "You have renamed list {before} to {stack} on board {board}" : "Você renomeou a lista {before} para {stack} no painel {board}", - "{user} has renamed list {before} to {stack} on board {board}" : "{user} renomeou a lista {before} para {stack} no painel {board}", - "You have deleted list {stack} on board {board}" : "Você excluiu a lista {stack} do painel {board}", - "{user} has deleted list {stack} on board {board}" : "{user} excluiu a lista {stack} do painel {board}", - "You have created card {card} in list {stack} on board {board}" : "Você criou o cartão {card} na lista {stack} do painel {board}", - "{user} has created card {card} in list {stack} on board {board}" : "{user} criou o cartão {card} na lista {stack} do painel {board}", - "You have deleted card {card} in list {stack} on board {board}" : "Você excluiu o cartão {card} na lista {stack} do painel {board}", - "{user} has deleted card {card} in list {stack} on board {board}" : "{user} excluiu o cartão {card} na lista {stack} do painel {board}", + "You have created a new board {board}" : "Você criou um novo quadro {board}", + "{user} has created a new board {board}" : "{user} criou um novo quadro {board}", + "You have deleted the board {board}" : "Você excluiu o quadro {board}", + "{user} has deleted the board {board}" : "{user} excluiu o quadro {board}", + "You have restored the board {board}" : "Você restaurou o quadro {board}", + "{user} has restored the board {board}" : "{user} restaurou o quadro {board}", + "You have shared the board {board} with {acl}" : "Você compartilhou o quadro {board} com {acl}", + "{user} has shared the board {board} with {acl}" : "{user} compartilhou o quadro {board} com {acl}", + "You have removed {acl} from the board {board}" : "Você excluiu {acl} do quadro {board}", + "{user} has removed {acl} from the board {board}" : "{user} excluiu {acl} do quadro {board}", + "You have renamed the board {before} to {board}" : "Você renomeou o quadro {before} para {board}", + "{user} has renamed the board {before} to {board}" : "{user} renomeou o quadro {before} para {board}", + "You have archived the board {board}" : "Você arquivou o quadro {board}", + "{user} has archived the board {before}" : "{user} arquivou o quadro {before}", + "You have unarchived the board {board}" : "Você desarquivou o quadro {board}", + "{user} has unarchived the board {before}" : "{user} desarquivou o quadro {before}", + "You have created a new list {stack} on board {board}" : "Você criou uma nova lista {stack} no quadro {board}", + "{user} has created a new list {stack} on board {board}" : "{user} criou uma nova lista {stack} no quadro {board}", + "You have renamed list {before} to {stack} on board {board}" : "Você renomeou a lista {before} para {stack} no quadro {board}", + "{user} has renamed list {before} to {stack} on board {board}" : "{user} renomeou a lista {before} para {stack} no quadro {board}", + "You have deleted list {stack} on board {board}" : "Você excluiu a lista {stack} do quadro {board}", + "{user} has deleted list {stack} on board {board}" : "{user} excluiu a lista {stack} do quadro {board}", + "You have created card {card} in list {stack} on board {board}" : "Você criou o cartão {card} na lista {stack} do quadro {board}", + "{user} has created card {card} in list {stack} on board {board}" : "{user} criou o cartão {card} na lista {stack} do quadro {board}", + "You have deleted card {card} in list {stack} on board {board}" : "Você excluiu o cartão {card} na lista {stack} do quadro {board}", + "{user} has deleted card {card} in list {stack} on board {board}" : "{user} excluiu o cartão {card} na lista {stack} do quadro {board}", "You have renamed the card {before} to {card}" : "Você renomeou o cartão {before} para {card}", "{user} has renamed the card {before} to {card}" : "{user} renomeou o cartão {before} para {card}", - "You have added a description to card {card} in list {stack} on board {board}" : "Você adicionou uma descrição ao cartão {card} na lista {stack} do painel {board}", - "{user} has added a description to card {card} in list {stack} on board {board}" : "{user} adicionou uma descrição ao cartão {card} na lista {stack} do painel {board}", - "You have updated the description of card {card} in list {stack} on board {board}" : "Você atualizou a descrição do cartão {card} na lista {stack} do painel {board}", - "{user} has updated the description of the card {card} in list {stack} on board {board}" : "{user} atualizou a descrição do cartão {card} na lista {stack} do painel {board}", - "You have archived card {card} in list {stack} on board {board}" : "Você arquivou o cartão {card} na lista {stack} do painel {board}", - "{user} has archived card {card} in list {stack} on board {board}" : "{user} arquivou o cartão {card} na lista {stack} do painel {board}", - "You have unarchived card {card} in list {stack} on board {board}" : "Você desarquivou o cartão {card} na lista {stack} do painel {board}", - "{user} has unarchived card {card} in list {stack} on board {board}" : "{user} desarquivou o cartão {card} na lista {stack} do painel {board}", - "You have marked the card {card} as done in list {stack} on board {board}" : "Você marcou o cartão {card} como concluído na lista {stack} no painel {board}", - "{user} has marked card {card} as done in list {stack} on board {board}" : "{user} marcou o cartão {card} como concluído na lista {stack} no painel {board}", - "You have marked the card {card} as undone in list {stack} on board {board}" : "Você marcou o cartão {card} como não concluído na lista {stack} no painel {board}", - "{user} has marked the card {card} as undone in list {stack} on board {board}" : "{user} marcou o cartão {card} como não concluído na lista {stack} no painel {board}", + "You have added a description to card {card} in list {stack} on board {board}" : "Você adicionou uma descrição ao cartão {card} na lista {stack} do quadro {board}", + "{user} has added a description to card {card} in list {stack} on board {board}" : "{user} adicionou uma descrição ao cartão {card} na lista {stack} do quadro {board}", + "You have updated the description of card {card} in list {stack} on board {board}" : "Você atualizou a descrição do cartão {card} na lista {stack} do quadro {board}", + "{user} has updated the description of the card {card} in list {stack} on board {board}" : "{user} atualizou a descrição do cartão {card} na lista {stack} do quadro {board}", + "You have archived card {card} in list {stack} on board {board}" : "Você arquivou o cartão {card} na lista {stack} do quadro {board}", + "{user} has archived card {card} in list {stack} on board {board}" : "{user} arquivou o cartão {card} na lista {stack} do quadro {board}", + "You have unarchived card {card} in list {stack} on board {board}" : "Você desarquivou o cartão {card} na lista {stack} do quadro {board}", + "{user} has unarchived card {card} in list {stack} on board {board}" : "{user} desarquivou o cartão {card} na lista {stack} do quadro {board}", + "You have marked the card {card} as done in list {stack} on board {board}" : "Você marcou o cartão {card} como concluído na lista {stack} no quadro {board}", + "{user} has marked card {card} as done in list {stack} on board {board}" : "{user} marcou o cartão {card} como concluído na lista {stack} no quadro {board}", + "You have marked the card {card} as undone in list {stack} on board {board}" : "Você marcou o cartão {card} como não concluído na lista {stack} no quadro {board}", + "{user} has marked the card {card} as undone in list {stack} on board {board}" : "{user} marcou o cartão {card} como não concluído na lista {stack} no quadro {board}", "You have removed the due date of card {card}" : "Você excluiu a data de vencimento do cartão {card}", "{user} has removed the due date of card {card}" : "{user} excluiu a data de vencimento do cartão {card}", "You have set the due date of card {card} to {after}" : "Você definiu a data de vencimento do cartão {card} para {after}", "{user} has set the due date of card {card} to {after}" : "{user} definiu a data de vencimento do cartão {card} para {after}", "You have updated the due date of card {card} to {after}" : "Você atualizou a data de vencimento do cartão {card} para {after}", "{user} has updated the due date of card {card} to {after}" : "{user} atualizou a data de vencimento do cartão {card} para {after}", - "You have added the tag {label} to card {card} in list {stack} on board {board}" : "Você adicionou a etiqueta {label} ao cartão {card} na lista {stack} do painel {board}", - "{user} has added the tag {label} to card {card} in list {stack} on board {board}" : "{user} adicionou a etiqueta {label} ao cartão {card} na lista {stack} do painel {board}", - "You have removed the tag {label} from card {card} in list {stack} on board {board}" : "Você removeu a etiqueta {label} do cartão {card} na lista {stack} do painel {board}", - "{user} has removed the tag {label} from card {card} in list {stack} on board {board}" : "{user} removeu a etiqueta {label} do cartão {card} na lista {stack} do painel {board}", - "You have assigned {assigneduser} to card {card} on board {board}" : "Você vinculou {assigneduser} ao cartão {card} do painel {board}", - "{user} has assigned {assigneduser} to card {card} on board {board}" : "{user} vinculou {assigneduser} ao cartão {card} do painel {board}", - "You have unassigned {assigneduser} from card {card} on board {board}" : "Você desvinculou {assigneduser} do cartão {card} no painel {board}", - "{user} has unassigned {assigneduser} from card {card} on board {board}" : "{user} desvinculou {assigneduser} do cartão {card} no painel {board}", + "You have added the tag {label} to card {card} in list {stack} on board {board}" : "Você adicionou a etiqueta {label} ao cartão {card} na lista {stack} do quadro {board}", + "{user} has added the tag {label} to card {card} in list {stack} on board {board}" : "{user} adicionou a etiqueta {label} ao cartão {card} na lista {stack} do quadro {board}", + "You have removed the tag {label} from card {card} in list {stack} on board {board}" : "Você removeu a etiqueta {label} do cartão {card} na lista {stack} do quadro {board}", + "{user} has removed the tag {label} from card {card} in list {stack} on board {board}" : "{user} removeu a etiqueta {label} do cartão {card} na lista {stack} do quadro {board}", + "You have assigned {assigneduser} to card {card} on board {board}" : "Você vinculou {assigneduser} ao cartão {card} do quadro {board}", + "{user} has assigned {assigneduser} to card {card} on board {board}" : "{user} vinculou {assigneduser} ao cartão {card} do quadro {board}", + "You have unassigned {assigneduser} from card {card} on board {board}" : "Você desvinculou {assigneduser} do cartão {card} no quadro {board}", + "{user} has unassigned {assigneduser} from card {card} on board {board}" : "{user} desvinculou {assigneduser} do cartão {card} no quadro {board}", "You have moved the card {card} from list {stackBefore} to {stack}" : "Você moveu o cartão {card} da lista {stackBefore} para {stack}", "{user} has moved the card {card} from list {stackBefore} to {stack}" : "{user} moveu o cartão {card} da lista {stackBefore} para {stack}", "You have added the attachment {attachment} to card {card}" : "Você adicionou o anexo {attachment} no cartão {card}", @@ -69,7 +69,7 @@ OC.L10N.register( "{user} has commented on card {card}" : "{user} comentou no cartão {card}", "Deck" : "Deck", "Changes in the Deck app" : "Mudanças no aplicativo Deck", - "A board, list or card was changed" : "Um painel, lista ou cartão foi alterado", + "A board, list or card was changed" : "Um quadro, lista ou cartão foi alterado", "A comment was created on a card" : "Um comentário foi criado no cartão", "A card description has been changed" : "Uma descrição do cartão foi alterada", "The file was uploaded" : "O arquivo foi enviado", @@ -83,7 +83,7 @@ OC.L10N.register( "No file uploaded or file size exceeds maximum of %s" : "Nenhum arquivo enviado ou o tamanho excede o máximo de %s", "Invalid file type. Only JSON files are allowed." : "Tipo de arquivo inválido. Somente arquivos JSON são permitidos.", "Invalid JSON data" : "Dados JSON inválidos", - "Failed to import board" : "Falha ao importar painel", + "Failed to import board" : "Falha ao importar quadro", "Cards due today" : "Cartões com vencimento hoje", "Cards due tomorrow" : "Cartões com vencimento amanhã", "Upcoming cards" : "Próximos cartões", @@ -95,17 +95,17 @@ OC.L10N.register( "The card {deck-card} on {deck-board} has reached its due date." : "O cartão {deck-card} em {deck-board} atingiu sua data de vencimento.", "%s has mentioned you in a comment on \"%s\"." : "%s citou você num comentário em \"%s\".", "{user} has mentioned you in a comment on {deck-card}." : "{user} mencionou você em um comentário em {deck-card}.", - "The board \"%s\" has been shared with you by %s." : "O painel \"%s\" foi compartilhado com você por %s.", + "The board \"%s\" has been shared with you by %s." : "O quadro \"%s\" foi compartilhado com você por %s.", "{user} has shared {deck-board} with you." : "{user} compartilhou o {deck-board} com você.", - "The remote board %1$s has been shared with you by %2$s" : "O painel remoto %1$s foi compartilhado com você por %2$s", - "Deck board" : "Painel de Deck", + "The remote board %1$s has been shared with you by %2$s" : "O quadro remoto %1$s foi compartilhado com você por %2$s", + "Deck board" : "Quadro do Deck", "Owned by %1$s" : "Propriedade de %1$s", - "Deck boards, cards and comments" : "Paineis, cartões e comentários de Deck", + "Deck boards, cards and comments" : "Quadros, cartões e comentários do Deck", "From %1$s, in %2$s/%3$s, owned by %4$s" : "De %1$s, em %2$s/%3$s, propriedade de %4$s", "Create a new deck card" : "Criar um novo cartão de Deck", "Card comments" : "Comentários do cartão", "%s on %s" : "%s em %s", - "Deck boards and cards" : "Paineis e cartões de Deck", + "Deck boards and cards" : "Quadros e cartões do Deck", "No data was provided to create an attachment." : "Nenhum dado foi fornecido para criar um anexo.", "Finished" : "Terminado", "To review" : "Para revisão", @@ -117,7 +117,7 @@ OC.L10N.register( "To Do" : "A Fazer", "In Progress" : "Em Andamento", "Done" : "Concluído", - "1. Open to learn more about boards and cards" : "1. Abra para saber mais sobre painéis e cartões", + "1. Open to learn more about boards and cards" : "1. Abra para saber mais sobre quadros e cartões", "2. Drag cards left and right, up and down" : "2. Arraste os cartões para a esquerda e para a direita, para cima e para baixo", "3. Apply rich formatting and link content" : "3. Aplique formatação avançada e conteúdo de links", "4. Share, comment and collaborate!" : "4. Compartilhe, comente e colabore!", @@ -129,16 +129,16 @@ OC.L10N.register( "Card not found" : "Cartão não encontrado", "Path is already shared with this card" : "O caminho já é compartilhado com este cartão", "Invalid date, date format must be YYYY-MM-DD" : "Data inválida, o formato da data deve ser AAAA-MM-DD", - "All boards owned by you including stacks, cards, labels, assignments, and comments" : "Todos os painéis de que você é proprietário, incluindo pilhas, cartões, etiquetas, tarefas e comentários", + "All boards owned by you including stacks, cards, labels, assignments, and comments" : "Todos os quadros de que você é proprietário, incluindo pilhas, cartões, etiquetas, tarefas e comentários", "Personal planning and team project organization" : "Planejamento pessoal e organização de projetos em equipe", "Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "O Deck é uma ferramenta de organização ao estilo kanban voltada para o planejamento pessoal e para a organização de projetos para equipes, integrada ao Nextcloud.\n\n\n- 📥Adicione suas tarefas aos cartões e coloque-os em ordem\n- 📄 Escreva notas adicionais formatadas em Markdown \n- 🔖 Atribua rótulos para uma organização ainda melhor\n- 👥 Compartilhe com sua equipe, seus amigos ou sua família\n- 📎 Anexe arquivos e incorpore-os à sua descrição em Markdown\n- 💬 Discuta com sua equipe usando comentários\n- ⚡ Acompanhe as alterações no fluxo de atividades \n- 🚀 Organize seu projeto ", - "Add board" : "Adicionar painel", + "Add board" : "Adicionar quadro", "Card details" : "Detalhes do cartão", - "Select the board to link to a project" : "Selecione o painel para vincular a um projeto", - "Search by board title" : "Pesquisar pelo título do painel", - "Select board" : "Selecionar painel", + "Select the board to link to a project" : "Selecione o quadro para vincular a um projeto", + "Search by board title" : "Pesquisar pelo título do quadro", + "Select board" : "Selecionar quadro", "Move/copy card" : "Mover/copiar cartão", - "Select a board" : "Selecionar um painel", + "Select a board" : "Selecionar um quadro", "No lists available" : "Nenhuma lista disponível", "Select a list" : "Selecione uma lista", "Move card" : "Mover cartão", @@ -147,7 +147,7 @@ OC.L10N.register( "Link to card" : "Vincular ao cartão", "Select a card" : "Selecionar um cartão", "Cancel" : "Cancelar", - "This board is read only" : "Este painel é somente leitura", + "This board is read only" : "Este quadro é somente leitura", "Drop your files to upload" : "Arraste seus arquivos para enviar", "File already exists" : "Arquivo já existe", "A file with the name {filename} already exists." : "Um arquivo com o nome {filename} já existe.", @@ -192,12 +192,12 @@ OC.L10N.register( "Add new cards at the top of a list" : "Adicionar novos cartões no topo de uma lista", "Appearance" : "Aparência", "Show card ID badge" : "Exibir o distintivo de identificação do cartão", - "Show boards in calendar/tasks" : "Exibir os painéis em calendários/tarefas", + "Show boards in calendar/tasks" : "Exibir os quadros em calendários/tarefas", "Admin settings" : "Configurações administrativas", - "Limit board creation to some groups" : "Limitar a criação de painéis a alguns grupos", - "Users outside of those groups will not be able to create their own boards, but will still be able to work on boards that have been shared with them." : "Os usuários fora desses grupos não poderão criar seus próprios painéis, mas ainda poderão trabalhar nos painéis que foram compartilhados com eles.", + "Limit board creation to some groups" : "Limitar a criação de quadros a alguns grupos", + "Users outside of those groups will not be able to create their own boards, but will still be able to work on boards that have been shared with them." : "Os usuários fora desses grupos não poderão criar seus próprios quadros, mas ainda poderão trabalhar nos quadros que foram compartilhados com eles.", "Enable federation" : "Ativar federação", - "Board actions" : "Ações de painel", + "Board actions" : "Ações de quadro", "Scroll sideways" : "Rolar para o lado", "Navigate between cards" : "Navegar entre os cartões", "Close card details" : "Fechar detalhes do cartão", @@ -215,9 +215,9 @@ OC.L10N.register( "Currently present people" : "Pessoas atualmente presentes", "Supported prefixes: {prefixes}. Wrap phrases in double quotes." : "Prefixos suportados: {prefixes}. Coloque as frases entre aspas duplas.", "Search cards" : "Pesquisar cartões", - "Loading board" : "Carregando painel", - "Board not found" : "Painel não encontrado", - "Create a new list to add cards to this board" : "Criar uma nova lista para adicionar cartões a este painel", + "Loading board" : "Carregando quadro", + "Board not found" : "Quadro não encontrado", + "Create a new list to add cards to this board" : "Criar uma nova lista para adicionar cartões a este quadro", "Sharing" : "Compartilhando", "Tags" : "Etiquetas", "Deleted items" : "Itens excluídos", @@ -233,12 +233,12 @@ OC.L10N.register( "Set a start date and due date on your cards to see them on the Gantt chart" : "Defina uma data de início e um prazo nos seus cartões para visualizá-los no gráfico de Gantt", "Cards without dates ({count})" : "Cartões sem datas ({count})", "Failed to create share with {displayName}" : "Falha ao criar compartilhamento com {displayName}", - "Are you sure you want to transfer the board {title} to {user}?" : "Deseja realmente transferir o painel {title} para {user}?", - "Transfer the board." : "Transferir o painel.", + "Are you sure you want to transfer the board {title} to {user}?" : "Deseja realmente transferir o quadro {title} para {user}?", + "Transfer the board." : "Transfira o quadro.", "Transfer" : "Transferir", - "The board has been transferred to {user}" : "A painel foi transferida para {user}", - "Failed to transfer the board to {user}" : "Não foi possível transferir o painel para {user}", - "Board owner" : "Proprietário do painel", + "The board has been transferred to {user}" : "A quadro foi transferida para {user}", + "Failed to transfer the board to {user}" : "Não foi possível transferir o quadro para {user}", + "Board owner" : "Proprietário do quadro", "(Group)" : "(Grupo)", "(Team)" : "(Equipe)", "(remote)" : "(remoto)", @@ -261,8 +261,8 @@ OC.L10N.register( "title and color value must be provided" : "o título e o valor da cor devem ser fornecidos", "Edit" : "Editar", "Add a new tag" : "Adicionar uma nova etiqueta", - "Search boards" : "Pesquisar painéis", - "Board name" : "Nome do painel", + "Search boards" : "Pesquisar quadros", + "Board name" : "Nome do quadro", "Members" : "Membros", "Assign to users/groups/team" : "Atribuir a usuários/grupos/equipe", "Assign a user to this card…" : "Atribuir um usuário a este cartão...", @@ -350,41 +350,41 @@ OC.L10N.register( "Assign to me" : "Atribuir a mim", "Unassign myself" : "Desatribuir-me", "Delete card" : "Excluir cartão", - "All boards" : "Todos os painéis", - "Archived boards" : "Painéis arquivados", + "All boards" : "Todos os quadros", + "Archived boards" : "Quadros arquivados", "Shared with you" : "Compartilhado com você", "Cancel edit" : "Cancelar edição", - "Save board" : "Salvar painel", - "Board {0} deleted" : "Painel {0} excluído", + "Save board" : "Salvar quadro", + "Board {0} deleted" : "Quadro {0} excluído", "All cards" : "Todos os cartões", "Only assigned cards" : "Apenas cartões atribuídos", "No reminder" : "Nenhum lembrete", - "Are you sure you want to delete the board {title}? This will delete all the data of this board including archived cards." : "Deseja realmente excluir o painel {title}? Isso excluirá todos os dados deste painel, inclusive os cartões arquivados.", - "Delete the board?" : "Excluir o painel?", - "Are you sure you want to leave the board {title}?" : "Tem certeza de que deseja sair do painel {title}?", - "Leave the board?" : "Sair do painel?", + "Are you sure you want to delete the board {title}? This will delete all the data of this board including archived cards." : "Deseja realmente excluir o quadro {title}? Isso excluirá todos os dados deste quadro, inclusive os cartões arquivados.", + "Delete the board?" : "Excluir o quadro?", + "Are you sure you want to leave the board {title}?" : "Tem certeza de que deseja sair do quadro {title}?", + "Leave the board?" : "Sair do quadro?", "Leave" : "Sair", - "Failed to leave the board" : "Falha ao sair do painel", - "Exporting board..." : "Exportando painel...", + "Failed to leave the board" : "Falha ao sair do quadro", + "Exporting board..." : "Exportando quadro...", "An error occurred" : "Ocorreu um erro", - "Board details" : "Detalhes do painel", - "Edit board" : "Editar painel", - "Clone board" : "Clonar painel", - "Unarchive board" : "Desarquivar painel", - "Archive board" : "Arquivar painel", - "Export board" : "Exportar painel", + "Board details" : "Detalhes do quadro", + "Edit board" : "Editar quadro", + "Clone board" : "Clonar quadro", + "Unarchive board" : "Desarquivar quadro", + "Archive board" : "Arquivar quadro", + "Export board" : "Exportar quadro", "Turn on due date reminders" : "Ativar lembretes de vencimento", "Turn off due date reminders" : "Desativar lembretes de vencimento", - "Remove as default board" : "Remover como painel padrão", - "Set as default board" : "Definir como painel padrão", + "Remove as default board" : "Remover como quadro padrão", + "Set as default board" : "Definir como quadro padrão", "Due date reminders" : "Lembretes de vencimento", "Assigned cards" : "Cartões atribuídos", "No notifications" : "Sem notificações", - "Delete board" : "Excluir painel", - "Leave board" : "Sair do painel", - "Importing board..." : "Importando painel...", - "Board imported successfully" : "Painel importado com sucesso", - "Import board" : "Importar painel", + "Delete board" : "Excluir quadro", + "Leave board" : "Sair do quadro", + "Importing board..." : "Importando quadro...", + "Board imported successfully" : "Quadro importado com sucesso", + "Import board" : "Importar quadro", "Clone {boardTitle}" : "Clonar {boardTitle}", "Clone cards" : "Clonar cartões", "Clone assignments" : "Clonar atribuições", @@ -400,10 +400,10 @@ OC.L10N.register( "Note: Only the JSON format is supported for importing back into the Deck app." : "Observação: somente o formato JSON é compatível com a importação de volta para o aplicativo Deck.", "Export" : "Exportar", "Loading filtered view" : "Carregando exibição filtrada", - "Search for {searchQuery} in other boards" : "Pesquisar {searchQuery} em outros painéis.", - "Search for {searchQuery} in all boards" : "Pesquisar por {searchQuery} em todos os painéis", + "Search for {searchQuery} in other boards" : "Pesquisar {searchQuery} em outros quadros.", + "Search for {searchQuery} in all boards" : "Pesquisar por {searchQuery} em todos os quadros", "No results found" : "Nenhum resultado encontrado", - "Deck board {name}\n* Last modified on {lastMod}" : "Painel de Deck {name}\n* Última modificação em {lastMod}", + "Deck board {name}\n* Last modified on {lastMod}" : "Quadro do Deck {name}\n* Última modificação em {lastMod}", "* Created on {created}\n* Last modified on {lastMod}\n* {nbAttachments} attachments\n* {nbComments} comments" : "* Criado em {created}\n* Última modificação em {lastMod}\n* {nbAttachments} anexos\n* {nbComments} comentários", "{nbCards} cards" : "{nbCards} cartões", "Due on {date}" : "Vencimento em {date}", @@ -422,7 +422,7 @@ OC.L10N.register( "upcoming cards tomorrow" : "próximos cartões amanhã", "upcoming cards" : "próximos cartões", "New card" : "Novo cartão", - "Link to a board" : "Vincular a um painel", + "Link to a board" : "Vincular a um quadro", "Link to a card" : "Vincular a um cartão", "Create a card" : "Criar um cartão", "Message from {author} in {conversationName}" : "Mensagem de {author} em {conversationName}", @@ -438,7 +438,7 @@ OC.L10N.register( "Share {file} with a Deck card" : "Compartilhar {file} com um cartão Deck", "Share" : "Compartilhar", "The card \"%s\" on \"%s\" has reached its due date." : "O cartão \"%s\" em \"%s\" atingiu sua data de vencimento.", - "Share board with a user, group or team …" : "Compartilhar painel com um usuário, grupo ou equipe…", + "Share board with a user, group or team …" : "Compartilhar quadro com um usuário, grupo ou equipe…", "Searching for users, groups and teams …" : "Pesquisando usuários, grupos e equipes …", "No participants found" : "Nenhum participante encontrado", "Save" : "Salvar", diff --git a/l10n/pt_BR.json b/l10n/pt_BR.json index 72fd667cf1..c3bfd222ed 100644 --- a/l10n/pt_BR.json +++ b/l10n/pt_BR.json @@ -1,58 +1,58 @@ { "translations": { - "You have created a new board {board}" : "Você criou um novo painel {board}", - "{user} has created a new board {board}" : "{user} criou um novo painel {board}", - "You have deleted the board {board}" : "Você excluiu o painel {board}", - "{user} has deleted the board {board}" : "{user} excluiu o painel {board}", - "You have restored the board {board}" : "Você restaurou o painel {board}", - "{user} has restored the board {board}" : "{user} restaurou o painel {board}", - "You have shared the board {board} with {acl}" : "Você compartilhou o painel {board} com {acl}", - "{user} has shared the board {board} with {acl}" : "{user} compartilhou o painel {board} com {acl}", - "You have removed {acl} from the board {board}" : "Você excluiu {acl} do painel {board}", - "{user} has removed {acl} from the board {board}" : "{user} excluiu {acl} do painel {board}", - "You have renamed the board {before} to {board}" : "Você renomeou o painel {before} para {board}", - "{user} has renamed the board {before} to {board}" : "{user} renomeou o painel {before} para {board}", - "You have archived the board {board}" : "Você arquivou o painel {board}", - "{user} has archived the board {before}" : "{user} arquivou o painel {before}", - "You have unarchived the board {board}" : "Você desarquivou o painel {board}", - "{user} has unarchived the board {before}" : "{user} desarquivou o painel {board}", - "You have created a new list {stack} on board {board}" : "Você criou uma nova lista {stack} no painel {board}", - "{user} has created a new list {stack} on board {board}" : "{user} criou uma nova lista {stack} no painel {board}", - "You have renamed list {before} to {stack} on board {board}" : "Você renomeou a lista {before} para {stack} no painel {board}", - "{user} has renamed list {before} to {stack} on board {board}" : "{user} renomeou a lista {before} para {stack} no painel {board}", - "You have deleted list {stack} on board {board}" : "Você excluiu a lista {stack} do painel {board}", - "{user} has deleted list {stack} on board {board}" : "{user} excluiu a lista {stack} do painel {board}", - "You have created card {card} in list {stack} on board {board}" : "Você criou o cartão {card} na lista {stack} do painel {board}", - "{user} has created card {card} in list {stack} on board {board}" : "{user} criou o cartão {card} na lista {stack} do painel {board}", - "You have deleted card {card} in list {stack} on board {board}" : "Você excluiu o cartão {card} na lista {stack} do painel {board}", - "{user} has deleted card {card} in list {stack} on board {board}" : "{user} excluiu o cartão {card} na lista {stack} do painel {board}", + "You have created a new board {board}" : "Você criou um novo quadro {board}", + "{user} has created a new board {board}" : "{user} criou um novo quadro {board}", + "You have deleted the board {board}" : "Você excluiu o quadro {board}", + "{user} has deleted the board {board}" : "{user} excluiu o quadro {board}", + "You have restored the board {board}" : "Você restaurou o quadro {board}", + "{user} has restored the board {board}" : "{user} restaurou o quadro {board}", + "You have shared the board {board} with {acl}" : "Você compartilhou o quadro {board} com {acl}", + "{user} has shared the board {board} with {acl}" : "{user} compartilhou o quadro {board} com {acl}", + "You have removed {acl} from the board {board}" : "Você excluiu {acl} do quadro {board}", + "{user} has removed {acl} from the board {board}" : "{user} excluiu {acl} do quadro {board}", + "You have renamed the board {before} to {board}" : "Você renomeou o quadro {before} para {board}", + "{user} has renamed the board {before} to {board}" : "{user} renomeou o quadro {before} para {board}", + "You have archived the board {board}" : "Você arquivou o quadro {board}", + "{user} has archived the board {before}" : "{user} arquivou o quadro {before}", + "You have unarchived the board {board}" : "Você desarquivou o quadro {board}", + "{user} has unarchived the board {before}" : "{user} desarquivou o quadro {before}", + "You have created a new list {stack} on board {board}" : "Você criou uma nova lista {stack} no quadro {board}", + "{user} has created a new list {stack} on board {board}" : "{user} criou uma nova lista {stack} no quadro {board}", + "You have renamed list {before} to {stack} on board {board}" : "Você renomeou a lista {before} para {stack} no quadro {board}", + "{user} has renamed list {before} to {stack} on board {board}" : "{user} renomeou a lista {before} para {stack} no quadro {board}", + "You have deleted list {stack} on board {board}" : "Você excluiu a lista {stack} do quadro {board}", + "{user} has deleted list {stack} on board {board}" : "{user} excluiu a lista {stack} do quadro {board}", + "You have created card {card} in list {stack} on board {board}" : "Você criou o cartão {card} na lista {stack} do quadro {board}", + "{user} has created card {card} in list {stack} on board {board}" : "{user} criou o cartão {card} na lista {stack} do quadro {board}", + "You have deleted card {card} in list {stack} on board {board}" : "Você excluiu o cartão {card} na lista {stack} do quadro {board}", + "{user} has deleted card {card} in list {stack} on board {board}" : "{user} excluiu o cartão {card} na lista {stack} do quadro {board}", "You have renamed the card {before} to {card}" : "Você renomeou o cartão {before} para {card}", "{user} has renamed the card {before} to {card}" : "{user} renomeou o cartão {before} para {card}", - "You have added a description to card {card} in list {stack} on board {board}" : "Você adicionou uma descrição ao cartão {card} na lista {stack} do painel {board}", - "{user} has added a description to card {card} in list {stack} on board {board}" : "{user} adicionou uma descrição ao cartão {card} na lista {stack} do painel {board}", - "You have updated the description of card {card} in list {stack} on board {board}" : "Você atualizou a descrição do cartão {card} na lista {stack} do painel {board}", - "{user} has updated the description of the card {card} in list {stack} on board {board}" : "{user} atualizou a descrição do cartão {card} na lista {stack} do painel {board}", - "You have archived card {card} in list {stack} on board {board}" : "Você arquivou o cartão {card} na lista {stack} do painel {board}", - "{user} has archived card {card} in list {stack} on board {board}" : "{user} arquivou o cartão {card} na lista {stack} do painel {board}", - "You have unarchived card {card} in list {stack} on board {board}" : "Você desarquivou o cartão {card} na lista {stack} do painel {board}", - "{user} has unarchived card {card} in list {stack} on board {board}" : "{user} desarquivou o cartão {card} na lista {stack} do painel {board}", - "You have marked the card {card} as done in list {stack} on board {board}" : "Você marcou o cartão {card} como concluído na lista {stack} no painel {board}", - "{user} has marked card {card} as done in list {stack} on board {board}" : "{user} marcou o cartão {card} como concluído na lista {stack} no painel {board}", - "You have marked the card {card} as undone in list {stack} on board {board}" : "Você marcou o cartão {card} como não concluído na lista {stack} no painel {board}", - "{user} has marked the card {card} as undone in list {stack} on board {board}" : "{user} marcou o cartão {card} como não concluído na lista {stack} no painel {board}", + "You have added a description to card {card} in list {stack} on board {board}" : "Você adicionou uma descrição ao cartão {card} na lista {stack} do quadro {board}", + "{user} has added a description to card {card} in list {stack} on board {board}" : "{user} adicionou uma descrição ao cartão {card} na lista {stack} do quadro {board}", + "You have updated the description of card {card} in list {stack} on board {board}" : "Você atualizou a descrição do cartão {card} na lista {stack} do quadro {board}", + "{user} has updated the description of the card {card} in list {stack} on board {board}" : "{user} atualizou a descrição do cartão {card} na lista {stack} do quadro {board}", + "You have archived card {card} in list {stack} on board {board}" : "Você arquivou o cartão {card} na lista {stack} do quadro {board}", + "{user} has archived card {card} in list {stack} on board {board}" : "{user} arquivou o cartão {card} na lista {stack} do quadro {board}", + "You have unarchived card {card} in list {stack} on board {board}" : "Você desarquivou o cartão {card} na lista {stack} do quadro {board}", + "{user} has unarchived card {card} in list {stack} on board {board}" : "{user} desarquivou o cartão {card} na lista {stack} do quadro {board}", + "You have marked the card {card} as done in list {stack} on board {board}" : "Você marcou o cartão {card} como concluído na lista {stack} no quadro {board}", + "{user} has marked card {card} as done in list {stack} on board {board}" : "{user} marcou o cartão {card} como concluído na lista {stack} no quadro {board}", + "You have marked the card {card} as undone in list {stack} on board {board}" : "Você marcou o cartão {card} como não concluído na lista {stack} no quadro {board}", + "{user} has marked the card {card} as undone in list {stack} on board {board}" : "{user} marcou o cartão {card} como não concluído na lista {stack} no quadro {board}", "You have removed the due date of card {card}" : "Você excluiu a data de vencimento do cartão {card}", "{user} has removed the due date of card {card}" : "{user} excluiu a data de vencimento do cartão {card}", "You have set the due date of card {card} to {after}" : "Você definiu a data de vencimento do cartão {card} para {after}", "{user} has set the due date of card {card} to {after}" : "{user} definiu a data de vencimento do cartão {card} para {after}", "You have updated the due date of card {card} to {after}" : "Você atualizou a data de vencimento do cartão {card} para {after}", "{user} has updated the due date of card {card} to {after}" : "{user} atualizou a data de vencimento do cartão {card} para {after}", - "You have added the tag {label} to card {card} in list {stack} on board {board}" : "Você adicionou a etiqueta {label} ao cartão {card} na lista {stack} do painel {board}", - "{user} has added the tag {label} to card {card} in list {stack} on board {board}" : "{user} adicionou a etiqueta {label} ao cartão {card} na lista {stack} do painel {board}", - "You have removed the tag {label} from card {card} in list {stack} on board {board}" : "Você removeu a etiqueta {label} do cartão {card} na lista {stack} do painel {board}", - "{user} has removed the tag {label} from card {card} in list {stack} on board {board}" : "{user} removeu a etiqueta {label} do cartão {card} na lista {stack} do painel {board}", - "You have assigned {assigneduser} to card {card} on board {board}" : "Você vinculou {assigneduser} ao cartão {card} do painel {board}", - "{user} has assigned {assigneduser} to card {card} on board {board}" : "{user} vinculou {assigneduser} ao cartão {card} do painel {board}", - "You have unassigned {assigneduser} from card {card} on board {board}" : "Você desvinculou {assigneduser} do cartão {card} no painel {board}", - "{user} has unassigned {assigneduser} from card {card} on board {board}" : "{user} desvinculou {assigneduser} do cartão {card} no painel {board}", + "You have added the tag {label} to card {card} in list {stack} on board {board}" : "Você adicionou a etiqueta {label} ao cartão {card} na lista {stack} do quadro {board}", + "{user} has added the tag {label} to card {card} in list {stack} on board {board}" : "{user} adicionou a etiqueta {label} ao cartão {card} na lista {stack} do quadro {board}", + "You have removed the tag {label} from card {card} in list {stack} on board {board}" : "Você removeu a etiqueta {label} do cartão {card} na lista {stack} do quadro {board}", + "{user} has removed the tag {label} from card {card} in list {stack} on board {board}" : "{user} removeu a etiqueta {label} do cartão {card} na lista {stack} do quadro {board}", + "You have assigned {assigneduser} to card {card} on board {board}" : "Você vinculou {assigneduser} ao cartão {card} do quadro {board}", + "{user} has assigned {assigneduser} to card {card} on board {board}" : "{user} vinculou {assigneduser} ao cartão {card} do quadro {board}", + "You have unassigned {assigneduser} from card {card} on board {board}" : "Você desvinculou {assigneduser} do cartão {card} no quadro {board}", + "{user} has unassigned {assigneduser} from card {card} on board {board}" : "{user} desvinculou {assigneduser} do cartão {card} no quadro {board}", "You have moved the card {card} from list {stackBefore} to {stack}" : "Você moveu o cartão {card} da lista {stackBefore} para {stack}", "{user} has moved the card {card} from list {stackBefore} to {stack}" : "{user} moveu o cartão {card} da lista {stackBefore} para {stack}", "You have added the attachment {attachment} to card {card}" : "Você adicionou o anexo {attachment} no cartão {card}", @@ -67,7 +67,7 @@ "{user} has commented on card {card}" : "{user} comentou no cartão {card}", "Deck" : "Deck", "Changes in the Deck app" : "Mudanças no aplicativo Deck", - "A board, list or card was changed" : "Um painel, lista ou cartão foi alterado", + "A board, list or card was changed" : "Um quadro, lista ou cartão foi alterado", "A comment was created on a card" : "Um comentário foi criado no cartão", "A card description has been changed" : "Uma descrição do cartão foi alterada", "The file was uploaded" : "O arquivo foi enviado", @@ -81,7 +81,7 @@ "No file uploaded or file size exceeds maximum of %s" : "Nenhum arquivo enviado ou o tamanho excede o máximo de %s", "Invalid file type. Only JSON files are allowed." : "Tipo de arquivo inválido. Somente arquivos JSON são permitidos.", "Invalid JSON data" : "Dados JSON inválidos", - "Failed to import board" : "Falha ao importar painel", + "Failed to import board" : "Falha ao importar quadro", "Cards due today" : "Cartões com vencimento hoje", "Cards due tomorrow" : "Cartões com vencimento amanhã", "Upcoming cards" : "Próximos cartões", @@ -93,17 +93,17 @@ "The card {deck-card} on {deck-board} has reached its due date." : "O cartão {deck-card} em {deck-board} atingiu sua data de vencimento.", "%s has mentioned you in a comment on \"%s\"." : "%s citou você num comentário em \"%s\".", "{user} has mentioned you in a comment on {deck-card}." : "{user} mencionou você em um comentário em {deck-card}.", - "The board \"%s\" has been shared with you by %s." : "O painel \"%s\" foi compartilhado com você por %s.", + "The board \"%s\" has been shared with you by %s." : "O quadro \"%s\" foi compartilhado com você por %s.", "{user} has shared {deck-board} with you." : "{user} compartilhou o {deck-board} com você.", - "The remote board %1$s has been shared with you by %2$s" : "O painel remoto %1$s foi compartilhado com você por %2$s", - "Deck board" : "Painel de Deck", + "The remote board %1$s has been shared with you by %2$s" : "O quadro remoto %1$s foi compartilhado com você por %2$s", + "Deck board" : "Quadro do Deck", "Owned by %1$s" : "Propriedade de %1$s", - "Deck boards, cards and comments" : "Paineis, cartões e comentários de Deck", + "Deck boards, cards and comments" : "Quadros, cartões e comentários do Deck", "From %1$s, in %2$s/%3$s, owned by %4$s" : "De %1$s, em %2$s/%3$s, propriedade de %4$s", "Create a new deck card" : "Criar um novo cartão de Deck", "Card comments" : "Comentários do cartão", "%s on %s" : "%s em %s", - "Deck boards and cards" : "Paineis e cartões de Deck", + "Deck boards and cards" : "Quadros e cartões do Deck", "No data was provided to create an attachment." : "Nenhum dado foi fornecido para criar um anexo.", "Finished" : "Terminado", "To review" : "Para revisão", @@ -115,7 +115,7 @@ "To Do" : "A Fazer", "In Progress" : "Em Andamento", "Done" : "Concluído", - "1. Open to learn more about boards and cards" : "1. Abra para saber mais sobre painéis e cartões", + "1. Open to learn more about boards and cards" : "1. Abra para saber mais sobre quadros e cartões", "2. Drag cards left and right, up and down" : "2. Arraste os cartões para a esquerda e para a direita, para cima e para baixo", "3. Apply rich formatting and link content" : "3. Aplique formatação avançada e conteúdo de links", "4. Share, comment and collaborate!" : "4. Compartilhe, comente e colabore!", @@ -127,16 +127,16 @@ "Card not found" : "Cartão não encontrado", "Path is already shared with this card" : "O caminho já é compartilhado com este cartão", "Invalid date, date format must be YYYY-MM-DD" : "Data inválida, o formato da data deve ser AAAA-MM-DD", - "All boards owned by you including stacks, cards, labels, assignments, and comments" : "Todos os painéis de que você é proprietário, incluindo pilhas, cartões, etiquetas, tarefas e comentários", + "All boards owned by you including stacks, cards, labels, assignments, and comments" : "Todos os quadros de que você é proprietário, incluindo pilhas, cartões, etiquetas, tarefas e comentários", "Personal planning and team project organization" : "Planejamento pessoal e organização de projetos em equipe", "Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "O Deck é uma ferramenta de organização ao estilo kanban voltada para o planejamento pessoal e para a organização de projetos para equipes, integrada ao Nextcloud.\n\n\n- 📥Adicione suas tarefas aos cartões e coloque-os em ordem\n- 📄 Escreva notas adicionais formatadas em Markdown \n- 🔖 Atribua rótulos para uma organização ainda melhor\n- 👥 Compartilhe com sua equipe, seus amigos ou sua família\n- 📎 Anexe arquivos e incorpore-os à sua descrição em Markdown\n- 💬 Discuta com sua equipe usando comentários\n- ⚡ Acompanhe as alterações no fluxo de atividades \n- 🚀 Organize seu projeto ", - "Add board" : "Adicionar painel", + "Add board" : "Adicionar quadro", "Card details" : "Detalhes do cartão", - "Select the board to link to a project" : "Selecione o painel para vincular a um projeto", - "Search by board title" : "Pesquisar pelo título do painel", - "Select board" : "Selecionar painel", + "Select the board to link to a project" : "Selecione o quadro para vincular a um projeto", + "Search by board title" : "Pesquisar pelo título do quadro", + "Select board" : "Selecionar quadro", "Move/copy card" : "Mover/copiar cartão", - "Select a board" : "Selecionar um painel", + "Select a board" : "Selecionar um quadro", "No lists available" : "Nenhuma lista disponível", "Select a list" : "Selecione uma lista", "Move card" : "Mover cartão", @@ -145,7 +145,7 @@ "Link to card" : "Vincular ao cartão", "Select a card" : "Selecionar um cartão", "Cancel" : "Cancelar", - "This board is read only" : "Este painel é somente leitura", + "This board is read only" : "Este quadro é somente leitura", "Drop your files to upload" : "Arraste seus arquivos para enviar", "File already exists" : "Arquivo já existe", "A file with the name {filename} already exists." : "Um arquivo com o nome {filename} já existe.", @@ -190,12 +190,12 @@ "Add new cards at the top of a list" : "Adicionar novos cartões no topo de uma lista", "Appearance" : "Aparência", "Show card ID badge" : "Exibir o distintivo de identificação do cartão", - "Show boards in calendar/tasks" : "Exibir os painéis em calendários/tarefas", + "Show boards in calendar/tasks" : "Exibir os quadros em calendários/tarefas", "Admin settings" : "Configurações administrativas", - "Limit board creation to some groups" : "Limitar a criação de painéis a alguns grupos", - "Users outside of those groups will not be able to create their own boards, but will still be able to work on boards that have been shared with them." : "Os usuários fora desses grupos não poderão criar seus próprios painéis, mas ainda poderão trabalhar nos painéis que foram compartilhados com eles.", + "Limit board creation to some groups" : "Limitar a criação de quadros a alguns grupos", + "Users outside of those groups will not be able to create their own boards, but will still be able to work on boards that have been shared with them." : "Os usuários fora desses grupos não poderão criar seus próprios quadros, mas ainda poderão trabalhar nos quadros que foram compartilhados com eles.", "Enable federation" : "Ativar federação", - "Board actions" : "Ações de painel", + "Board actions" : "Ações de quadro", "Scroll sideways" : "Rolar para o lado", "Navigate between cards" : "Navegar entre os cartões", "Close card details" : "Fechar detalhes do cartão", @@ -213,9 +213,9 @@ "Currently present people" : "Pessoas atualmente presentes", "Supported prefixes: {prefixes}. Wrap phrases in double quotes." : "Prefixos suportados: {prefixes}. Coloque as frases entre aspas duplas.", "Search cards" : "Pesquisar cartões", - "Loading board" : "Carregando painel", - "Board not found" : "Painel não encontrado", - "Create a new list to add cards to this board" : "Criar uma nova lista para adicionar cartões a este painel", + "Loading board" : "Carregando quadro", + "Board not found" : "Quadro não encontrado", + "Create a new list to add cards to this board" : "Criar uma nova lista para adicionar cartões a este quadro", "Sharing" : "Compartilhando", "Tags" : "Etiquetas", "Deleted items" : "Itens excluídos", @@ -231,12 +231,12 @@ "Set a start date and due date on your cards to see them on the Gantt chart" : "Defina uma data de início e um prazo nos seus cartões para visualizá-los no gráfico de Gantt", "Cards without dates ({count})" : "Cartões sem datas ({count})", "Failed to create share with {displayName}" : "Falha ao criar compartilhamento com {displayName}", - "Are you sure you want to transfer the board {title} to {user}?" : "Deseja realmente transferir o painel {title} para {user}?", - "Transfer the board." : "Transferir o painel.", + "Are you sure you want to transfer the board {title} to {user}?" : "Deseja realmente transferir o quadro {title} para {user}?", + "Transfer the board." : "Transfira o quadro.", "Transfer" : "Transferir", - "The board has been transferred to {user}" : "A painel foi transferida para {user}", - "Failed to transfer the board to {user}" : "Não foi possível transferir o painel para {user}", - "Board owner" : "Proprietário do painel", + "The board has been transferred to {user}" : "A quadro foi transferida para {user}", + "Failed to transfer the board to {user}" : "Não foi possível transferir o quadro para {user}", + "Board owner" : "Proprietário do quadro", "(Group)" : "(Grupo)", "(Team)" : "(Equipe)", "(remote)" : "(remoto)", @@ -259,8 +259,8 @@ "title and color value must be provided" : "o título e o valor da cor devem ser fornecidos", "Edit" : "Editar", "Add a new tag" : "Adicionar uma nova etiqueta", - "Search boards" : "Pesquisar painéis", - "Board name" : "Nome do painel", + "Search boards" : "Pesquisar quadros", + "Board name" : "Nome do quadro", "Members" : "Membros", "Assign to users/groups/team" : "Atribuir a usuários/grupos/equipe", "Assign a user to this card…" : "Atribuir um usuário a este cartão...", @@ -348,41 +348,41 @@ "Assign to me" : "Atribuir a mim", "Unassign myself" : "Desatribuir-me", "Delete card" : "Excluir cartão", - "All boards" : "Todos os painéis", - "Archived boards" : "Painéis arquivados", + "All boards" : "Todos os quadros", + "Archived boards" : "Quadros arquivados", "Shared with you" : "Compartilhado com você", "Cancel edit" : "Cancelar edição", - "Save board" : "Salvar painel", - "Board {0} deleted" : "Painel {0} excluído", + "Save board" : "Salvar quadro", + "Board {0} deleted" : "Quadro {0} excluído", "All cards" : "Todos os cartões", "Only assigned cards" : "Apenas cartões atribuídos", "No reminder" : "Nenhum lembrete", - "Are you sure you want to delete the board {title}? This will delete all the data of this board including archived cards." : "Deseja realmente excluir o painel {title}? Isso excluirá todos os dados deste painel, inclusive os cartões arquivados.", - "Delete the board?" : "Excluir o painel?", - "Are you sure you want to leave the board {title}?" : "Tem certeza de que deseja sair do painel {title}?", - "Leave the board?" : "Sair do painel?", + "Are you sure you want to delete the board {title}? This will delete all the data of this board including archived cards." : "Deseja realmente excluir o quadro {title}? Isso excluirá todos os dados deste quadro, inclusive os cartões arquivados.", + "Delete the board?" : "Excluir o quadro?", + "Are you sure you want to leave the board {title}?" : "Tem certeza de que deseja sair do quadro {title}?", + "Leave the board?" : "Sair do quadro?", "Leave" : "Sair", - "Failed to leave the board" : "Falha ao sair do painel", - "Exporting board..." : "Exportando painel...", + "Failed to leave the board" : "Falha ao sair do quadro", + "Exporting board..." : "Exportando quadro...", "An error occurred" : "Ocorreu um erro", - "Board details" : "Detalhes do painel", - "Edit board" : "Editar painel", - "Clone board" : "Clonar painel", - "Unarchive board" : "Desarquivar painel", - "Archive board" : "Arquivar painel", - "Export board" : "Exportar painel", + "Board details" : "Detalhes do quadro", + "Edit board" : "Editar quadro", + "Clone board" : "Clonar quadro", + "Unarchive board" : "Desarquivar quadro", + "Archive board" : "Arquivar quadro", + "Export board" : "Exportar quadro", "Turn on due date reminders" : "Ativar lembretes de vencimento", "Turn off due date reminders" : "Desativar lembretes de vencimento", - "Remove as default board" : "Remover como painel padrão", - "Set as default board" : "Definir como painel padrão", + "Remove as default board" : "Remover como quadro padrão", + "Set as default board" : "Definir como quadro padrão", "Due date reminders" : "Lembretes de vencimento", "Assigned cards" : "Cartões atribuídos", "No notifications" : "Sem notificações", - "Delete board" : "Excluir painel", - "Leave board" : "Sair do painel", - "Importing board..." : "Importando painel...", - "Board imported successfully" : "Painel importado com sucesso", - "Import board" : "Importar painel", + "Delete board" : "Excluir quadro", + "Leave board" : "Sair do quadro", + "Importing board..." : "Importando quadro...", + "Board imported successfully" : "Quadro importado com sucesso", + "Import board" : "Importar quadro", "Clone {boardTitle}" : "Clonar {boardTitle}", "Clone cards" : "Clonar cartões", "Clone assignments" : "Clonar atribuições", @@ -398,10 +398,10 @@ "Note: Only the JSON format is supported for importing back into the Deck app." : "Observação: somente o formato JSON é compatível com a importação de volta para o aplicativo Deck.", "Export" : "Exportar", "Loading filtered view" : "Carregando exibição filtrada", - "Search for {searchQuery} in other boards" : "Pesquisar {searchQuery} em outros painéis.", - "Search for {searchQuery} in all boards" : "Pesquisar por {searchQuery} em todos os painéis", + "Search for {searchQuery} in other boards" : "Pesquisar {searchQuery} em outros quadros.", + "Search for {searchQuery} in all boards" : "Pesquisar por {searchQuery} em todos os quadros", "No results found" : "Nenhum resultado encontrado", - "Deck board {name}\n* Last modified on {lastMod}" : "Painel de Deck {name}\n* Última modificação em {lastMod}", + "Deck board {name}\n* Last modified on {lastMod}" : "Quadro do Deck {name}\n* Última modificação em {lastMod}", "* Created on {created}\n* Last modified on {lastMod}\n* {nbAttachments} attachments\n* {nbComments} comments" : "* Criado em {created}\n* Última modificação em {lastMod}\n* {nbAttachments} anexos\n* {nbComments} comentários", "{nbCards} cards" : "{nbCards} cartões", "Due on {date}" : "Vencimento em {date}", @@ -420,7 +420,7 @@ "upcoming cards tomorrow" : "próximos cartões amanhã", "upcoming cards" : "próximos cartões", "New card" : "Novo cartão", - "Link to a board" : "Vincular a um painel", + "Link to a board" : "Vincular a um quadro", "Link to a card" : "Vincular a um cartão", "Create a card" : "Criar um cartão", "Message from {author} in {conversationName}" : "Mensagem de {author} em {conversationName}", @@ -436,7 +436,7 @@ "Share {file} with a Deck card" : "Compartilhar {file} com um cartão Deck", "Share" : "Compartilhar", "The card \"%s\" on \"%s\" has reached its due date." : "O cartão \"%s\" em \"%s\" atingiu sua data de vencimento.", - "Share board with a user, group or team …" : "Compartilhar painel com um usuário, grupo ou equipe…", + "Share board with a user, group or team …" : "Compartilhar quadro com um usuário, grupo ou equipe…", "Searching for users, groups and teams …" : "Pesquisando usuários, grupos e equipes …", "No participants found" : "Nenhum participante encontrado", "Save" : "Salvar", diff --git a/l10n/sk.js b/l10n/sk.js index 53d7d909ce..6f0bb35b83 100644 --- a/l10n/sk.js +++ b/l10n/sk.js @@ -129,6 +129,7 @@ OC.L10N.register( "Card not found" : "Karta nebola nájdená", "Path is already shared with this card" : "Cesta je už zdieľaná s touto kartou", "Invalid date, date format must be YYYY-MM-DD" : "Neplatný dátum, formát musí byť v tvare YYYY-MM-DD", + "All boards owned by you including stacks, cards, labels, assignments, and comments" : "Všetky nástenky, ktoré vlastníte, vrátane zoznamov, kariet, štítkov, priradení a komentárov", "Personal planning and team project organization" : "Osobné plánovanie a organizácia tímových projektov", "Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deck je organizačný nástroj typu kanban zameraný na osobné plánovanie a organizáciu projektov pre tímy integrované s Nextcloud.\n\n\n- 📥 Pridajte svoje úlohy na karty a usporiadajte ich\n- 📄 Zapíšte si ďalšie poznámky v Markdown\n- 🔖 Priraďte štítky pre ešte lepšiu organizáciu\n- 👥 Zdieľajte so svojím tímom, priateľmi alebo rodinou\n- 📎 Pripojte súbory a vložte ich do popisu Markdown\n- 💬 Diskutujte so svojím tímom pomocou komentárov\n- ⚡ Sledujte zmeny v prúde aktivít\n- 🚀 Zorganizujte si svoj projekt", "Add board" : "Pridať nástenku", @@ -176,6 +177,8 @@ OC.L10N.register( "Clear filter" : "Vyčistiť filter", "View Modes" : "Režimy zobrazenia", "Toggle View Modes" : "Prepnúť režimy zobrazenia", + "Kanban view" : "Kanbanové zobrazenie", + "Gantt view" : "Ganttovo zobrazenie", "Hide archived cards" : "Skryť archivované karty", "Show archived cards" : "Zobraziť archivované karty", "Toggle compact mode" : "Vyp/zap. kompaktný režim", @@ -186,6 +189,7 @@ OC.L10N.register( "Deck settings" : "Nastavenia paluby", "General" : "Všeobecné", "Use bigger card view" : "Použiť väčšie zobrazenie karty", + "Add new cards at the top of a list" : "Pridávať nové karty na začiatok zoznamu", "Appearance" : "Vzhľad", "Show card ID badge" : "Ukázať ID karty", "Show boards in calendar/tasks" : "Zobrazovať nástenky v kalendári/úlohách", @@ -209,6 +213,8 @@ OC.L10N.register( "Mark card as completed/not completed" : "Označiť kartu ako dokončenú/nedokončenú", "Open card menu" : "Otvoriť menu karty", "Currently present people" : "Momentálne prítomný ľudia", + "Supported prefixes: {prefixes}. Wrap phrases in double quotes." : "Podporované prefixy: {prefixes}. Frázy uzatvárajte do dvojitých úvodzoviek.", + "Search cards" : "Vyhľadávať karty", "Loading board" : "Načítanie nástenky", "Board not found" : "Nástenka nebola nájdená", "Create a new list to add cards to this board" : "Pre pridanie kariet na túto tabuľu vytvorte nový zoznam", @@ -224,6 +230,8 @@ OC.L10N.register( "Weeks" : "Týždňov", "Months" : "Mesiacov", "No cards yet" : "Zatiaľ žiadne karty", + "Set a start date and due date on your cards to see them on the Gantt chart" : "Nastavte na kartách dátum začiatku a termín dokončenia, aby sa zobrazili v Ganttovom grafe", + "Cards without dates ({count})" : "Karty bez dátumov ({count})", "Failed to create share with {displayName}" : "Nepodarilo sa vytvoriť zdieľanie pre {displayName}", "Are you sure you want to transfer the board {title} to {user}?" : "Naozaj chcete preniesť nástenku {title} na užívateľa {user}?", "Transfer the board." : "Prenos nástenky.", @@ -253,6 +261,7 @@ OC.L10N.register( "title and color value must be provided" : "je potrebné zadať nadpis a vybrať farbu", "Edit" : "Upraviť", "Add a new tag" : "Pridať nový štítok", + "Search boards" : "Vyhľadávať nástenky", "Board name" : "Názov nástenky", "Members" : "Členovia", "Assign to users/groups/team" : "Priradiť k užívateľom/skupinám/tímom", @@ -269,6 +278,9 @@ OC.L10N.register( "Remove attachment" : "Odstrániť prílohu", "Delete Attachment" : "Odstrániť prílohu", "Restore Attachment" : "Obnoviť prílohu", + "Modified: {modifiedDate} ⸱ Created: {createdDate}" : "Upravené: {modifiedDate} ⸱ Vytvorené: {createdDate}", + "Modified: {modifiedDate}\nCreated: {createdDate}\nCreated by: {owner}" : "Upravené: {modifiedDate}\nVytvorené: {createdDate}\nVytvoril: {owner}", + "Modified: {modifiedDate}\nCreated: {createdDate}" : "Upravené: {modifiedDate}\nVytvorené: {createdDate}", "The title cannot be empty." : "Nadpis nemôže byť prázdny.", "Cannot close unsaved card!" : "Nie je možné zatvoriť neuloženú kartu!", "Open in sidebar view" : "Otvoriť v bočnom paneli", @@ -284,8 +296,13 @@ OC.L10N.register( "Cancel reply" : "Zrušiť odpoveď", "Reply" : "Odpoveď", "Update" : "Aktualizovať", + "Assign dependent cards" : "Priradiť závislé karty", "Mark as done" : "Označiť ako dokončené", "Mark as not done" : "Označiť ako nedokončené", + "Remove dependency" : "Odstrániť závislosť", + "Add dependent card" : "Pridať závislú kartu", + "Assign a dependent card…" : "Priradiť závislú kartu…", + "Select a dependent card…" : "Vybrať závislú kartu…", "Write a description …" : "Napíšte popis...", "The description has been changed by another user." : "Popis bol zmenený iným používateľom.", "Could not save description" : "Nepodarilo sa uložiť popis", @@ -328,6 +345,7 @@ OC.L10N.register( "Edit card title" : "Upraviť názov karty", "Open link" : "Otvoriť odkaz", "Card deleted" : "Karta bola vymazaná", + "Change card color" : "Zmeniť farbu karty", "Edit title" : "Premenovať", "Assign to me" : "Priradiť mne", "Unassign myself" : "Zrušiť priradenie mne", diff --git a/l10n/sk.json b/l10n/sk.json index 93ba00847c..5bbfc5ec22 100644 --- a/l10n/sk.json +++ b/l10n/sk.json @@ -127,6 +127,7 @@ "Card not found" : "Karta nebola nájdená", "Path is already shared with this card" : "Cesta je už zdieľaná s touto kartou", "Invalid date, date format must be YYYY-MM-DD" : "Neplatný dátum, formát musí byť v tvare YYYY-MM-DD", + "All boards owned by you including stacks, cards, labels, assignments, and comments" : "Všetky nástenky, ktoré vlastníte, vrátane zoznamov, kariet, štítkov, priradení a komentárov", "Personal planning and team project organization" : "Osobné plánovanie a organizácia tímových projektov", "Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deck je organizačný nástroj typu kanban zameraný na osobné plánovanie a organizáciu projektov pre tímy integrované s Nextcloud.\n\n\n- 📥 Pridajte svoje úlohy na karty a usporiadajte ich\n- 📄 Zapíšte si ďalšie poznámky v Markdown\n- 🔖 Priraďte štítky pre ešte lepšiu organizáciu\n- 👥 Zdieľajte so svojím tímom, priateľmi alebo rodinou\n- 📎 Pripojte súbory a vložte ich do popisu Markdown\n- 💬 Diskutujte so svojím tímom pomocou komentárov\n- ⚡ Sledujte zmeny v prúde aktivít\n- 🚀 Zorganizujte si svoj projekt", "Add board" : "Pridať nástenku", @@ -174,6 +175,8 @@ "Clear filter" : "Vyčistiť filter", "View Modes" : "Režimy zobrazenia", "Toggle View Modes" : "Prepnúť režimy zobrazenia", + "Kanban view" : "Kanbanové zobrazenie", + "Gantt view" : "Ganttovo zobrazenie", "Hide archived cards" : "Skryť archivované karty", "Show archived cards" : "Zobraziť archivované karty", "Toggle compact mode" : "Vyp/zap. kompaktný režim", @@ -184,6 +187,7 @@ "Deck settings" : "Nastavenia paluby", "General" : "Všeobecné", "Use bigger card view" : "Použiť väčšie zobrazenie karty", + "Add new cards at the top of a list" : "Pridávať nové karty na začiatok zoznamu", "Appearance" : "Vzhľad", "Show card ID badge" : "Ukázať ID karty", "Show boards in calendar/tasks" : "Zobrazovať nástenky v kalendári/úlohách", @@ -207,6 +211,8 @@ "Mark card as completed/not completed" : "Označiť kartu ako dokončenú/nedokončenú", "Open card menu" : "Otvoriť menu karty", "Currently present people" : "Momentálne prítomný ľudia", + "Supported prefixes: {prefixes}. Wrap phrases in double quotes." : "Podporované prefixy: {prefixes}. Frázy uzatvárajte do dvojitých úvodzoviek.", + "Search cards" : "Vyhľadávať karty", "Loading board" : "Načítanie nástenky", "Board not found" : "Nástenka nebola nájdená", "Create a new list to add cards to this board" : "Pre pridanie kariet na túto tabuľu vytvorte nový zoznam", @@ -222,6 +228,8 @@ "Weeks" : "Týždňov", "Months" : "Mesiacov", "No cards yet" : "Zatiaľ žiadne karty", + "Set a start date and due date on your cards to see them on the Gantt chart" : "Nastavte na kartách dátum začiatku a termín dokončenia, aby sa zobrazili v Ganttovom grafe", + "Cards without dates ({count})" : "Karty bez dátumov ({count})", "Failed to create share with {displayName}" : "Nepodarilo sa vytvoriť zdieľanie pre {displayName}", "Are you sure you want to transfer the board {title} to {user}?" : "Naozaj chcete preniesť nástenku {title} na užívateľa {user}?", "Transfer the board." : "Prenos nástenky.", @@ -251,6 +259,7 @@ "title and color value must be provided" : "je potrebné zadať nadpis a vybrať farbu", "Edit" : "Upraviť", "Add a new tag" : "Pridať nový štítok", + "Search boards" : "Vyhľadávať nástenky", "Board name" : "Názov nástenky", "Members" : "Členovia", "Assign to users/groups/team" : "Priradiť k užívateľom/skupinám/tímom", @@ -267,6 +276,9 @@ "Remove attachment" : "Odstrániť prílohu", "Delete Attachment" : "Odstrániť prílohu", "Restore Attachment" : "Obnoviť prílohu", + "Modified: {modifiedDate} ⸱ Created: {createdDate}" : "Upravené: {modifiedDate} ⸱ Vytvorené: {createdDate}", + "Modified: {modifiedDate}\nCreated: {createdDate}\nCreated by: {owner}" : "Upravené: {modifiedDate}\nVytvorené: {createdDate}\nVytvoril: {owner}", + "Modified: {modifiedDate}\nCreated: {createdDate}" : "Upravené: {modifiedDate}\nVytvorené: {createdDate}", "The title cannot be empty." : "Nadpis nemôže byť prázdny.", "Cannot close unsaved card!" : "Nie je možné zatvoriť neuloženú kartu!", "Open in sidebar view" : "Otvoriť v bočnom paneli", @@ -282,8 +294,13 @@ "Cancel reply" : "Zrušiť odpoveď", "Reply" : "Odpoveď", "Update" : "Aktualizovať", + "Assign dependent cards" : "Priradiť závislé karty", "Mark as done" : "Označiť ako dokončené", "Mark as not done" : "Označiť ako nedokončené", + "Remove dependency" : "Odstrániť závislosť", + "Add dependent card" : "Pridať závislú kartu", + "Assign a dependent card…" : "Priradiť závislú kartu…", + "Select a dependent card…" : "Vybrať závislú kartu…", "Write a description …" : "Napíšte popis...", "The description has been changed by another user." : "Popis bol zmenený iným používateľom.", "Could not save description" : "Nepodarilo sa uložiť popis", @@ -326,6 +343,7 @@ "Edit card title" : "Upraviť názov karty", "Open link" : "Otvoriť odkaz", "Card deleted" : "Karta bola vymazaná", + "Change card color" : "Zmeniť farbu karty", "Edit title" : "Premenovať", "Assign to me" : "Priradiť mne", "Unassign myself" : "Zrušiť priradenie mne", From 0bc25178b3928f8f13255cbae69969039b10938a Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Sat, 5 Sep 2026 00:55:59 +0000 Subject: [PATCH 15/31] fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- l10n/en_GB.js | 1 + l10n/en_GB.json | 1 + l10n/zh_HK.js | 1 + l10n/zh_HK.json | 1 + 4 files changed, 4 insertions(+) diff --git a/l10n/en_GB.js b/l10n/en_GB.js index e76026bad0..e03bad61a5 100644 --- a/l10n/en_GB.js +++ b/l10n/en_GB.js @@ -189,6 +189,7 @@ OC.L10N.register( "Deck settings" : "Deck settings", "General" : "General", "Use bigger card view" : "Use bigger card view", + "Add new cards at the top of a list" : "Add new cards at the top of a list", "Appearance" : "Appearance", "Show card ID badge" : "Show card ID badge", "Show boards in calendar/tasks" : "Show boards in calendar/tasks", diff --git a/l10n/en_GB.json b/l10n/en_GB.json index 8116a41cb5..6b6afe5cd8 100644 --- a/l10n/en_GB.json +++ b/l10n/en_GB.json @@ -187,6 +187,7 @@ "Deck settings" : "Deck settings", "General" : "General", "Use bigger card view" : "Use bigger card view", + "Add new cards at the top of a list" : "Add new cards at the top of a list", "Appearance" : "Appearance", "Show card ID badge" : "Show card ID badge", "Show boards in calendar/tasks" : "Show boards in calendar/tasks", diff --git a/l10n/zh_HK.js b/l10n/zh_HK.js index 468ca44ae5..8e6fe0b990 100644 --- a/l10n/zh_HK.js +++ b/l10n/zh_HK.js @@ -189,6 +189,7 @@ OC.L10N.register( "Deck settings" : "看板設定", "General" : "一般", "Use bigger card view" : "使用較大的卡片視圖", + "Add new cards at the top of a list" : "將新卡片新增至清單頂部", "Appearance" : "外觀", "Show card ID badge" : "顯示卡片 ID 徽章", "Show boards in calendar/tasks" : "在日曆/任務中顯示面板", diff --git a/l10n/zh_HK.json b/l10n/zh_HK.json index 12e33339c6..805ee469fc 100644 --- a/l10n/zh_HK.json +++ b/l10n/zh_HK.json @@ -187,6 +187,7 @@ "Deck settings" : "看板設定", "General" : "一般", "Use bigger card view" : "使用較大的卡片視圖", + "Add new cards at the top of a list" : "將新卡片新增至清單頂部", "Appearance" : "外觀", "Show card ID badge" : "顯示卡片 ID 徽章", "Show boards in calendar/tasks" : "在日曆/任務中顯示面板", From 130c1b0713b28d78d7261098b60064c7d6ab552a Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Sun, 6 Sep 2026 00:55:00 +0000 Subject: [PATCH 16/31] fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- l10n/ga.js | 1 + l10n/ga.json | 1 + l10n/is.js | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++- l10n/is.json | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 106 insertions(+), 2 deletions(-) diff --git a/l10n/ga.js b/l10n/ga.js index 0750777874..058909cc12 100644 --- a/l10n/ga.js +++ b/l10n/ga.js @@ -189,6 +189,7 @@ OC.L10N.register( "Deck settings" : "Socruithe deic", "General" : "Ginearálta", "Use bigger card view" : "Úsáid radharc cárta níos mó", + "Add new cards at the top of a list" : "Cuir cártaí nua ag barr liosta", "Appearance" : "Dealramh", "Show card ID badge" : "Taispeáin suaitheantas aitheantais an chárta", "Show boards in calendar/tasks" : "Taispeáin cláir san fhéilire/tascanna", diff --git a/l10n/ga.json b/l10n/ga.json index 9b5afa239b..48775d6a7f 100644 --- a/l10n/ga.json +++ b/l10n/ga.json @@ -187,6 +187,7 @@ "Deck settings" : "Socruithe deic", "General" : "Ginearálta", "Use bigger card view" : "Úsáid radharc cárta níos mó", + "Add new cards at the top of a list" : "Cuir cártaí nua ag barr liosta", "Appearance" : "Dealramh", "Show card ID badge" : "Taispeáin suaitheantas aitheantais an chárta", "Show boards in calendar/tasks" : "Taispeáin cláir san fhéilire/tascanna", diff --git a/l10n/is.js b/l10n/is.js index fb3fc499bb..60b970a939 100644 --- a/l10n/is.js +++ b/l10n/is.js @@ -81,6 +81,9 @@ OC.L10N.register( "Could not write file to disk" : "Tókst ekki að skrifa skrá á disk.", "A PHP extension stopped the file upload" : "PHP-viðbót stöðvaði innsendingu skráar", "No file uploaded or file size exceeds maximum of %s" : "Engin innsend skrá eða að skráarstærð fór fram úr hámarksstæðinni %s", + "Invalid file type. Only JSON files are allowed." : "Ógild skráategund. Einungis er tekið við JSON-skrám.", + "Invalid JSON data" : "Ógild JSON-gögn", + "Failed to import board" : "Mistókst að flytja inn borð", "Cards due today" : "Spjöld sem á að ljúka í dag", "Cards due tomorrow" : "Spjöld sem á að ljúka á morgun", "Upcoming cards" : "Spjöld á næstunni", @@ -88,11 +91,13 @@ OC.L10N.register( "Welcome to Nextcloud Deck!" : "Velkomin í Nextcloud Deck!", "The card \"%s\" on \"%s\" has been assigned to you by %s." : "Spjaldinu \"%s\" á \"%s\" hefur verið úthlutað til þín af %s.", "{user} has assigned the card {deck-card} on {deck-board} to you." : "{user} hefur úthlutað spjaldinu {deck-card} á {deck-board} til þín.", + "The card \"%1$s\" on \"%2$s\" has reached its due date." : "Spjaldið \"%1$s\" á \"%2$s\" er komið fram yfir lokadagsetningu.", "The card {deck-card} on {deck-board} has reached its due date." : "Spjaldið {deck-card} á {deck-board} er komið fram yfir lokadagsetningu.", "%s has mentioned you in a comment on \"%s\"." : "%s minntist á þig í athugasemd við \"%s\".", "{user} has mentioned you in a comment on {deck-card}." : "{user} minntist á þig í athugasemd við {deck-card}.", "The board \"%s\" has been shared with you by %s." : "Borðinu \"%s\" hefur verið deilt með þér af %s.", "{user} has shared {deck-board} with you." : "{user} deildi {deck-board} með þér.", + "The remote board %1$s has been shared with you by %2$s" : "Fjartengda borðinu %1$s hefur verið deilt með þér af %2$s", "Deck board" : "Deck-borð", "Owned by %1$s" : "Í eigu notandans %1$s", "Deck boards, cards and comments" : "Deck-borð, spjöld og athugasemdir", @@ -120,11 +125,13 @@ OC.L10N.register( "This comment has more than %s characters.\nAdded as an attachment to the card with name %s.\nAccessible on URL: %s." : "Þessi athugasemd er lengri en %s stafir.\nBætt við sem viðhengi á spjald með heitinu %s.\nAðgengileg á slóðinni: %s.", "Attachments" : "Viðhengi", "File" : "Skrá", + "date" : "dagsetning", "Card not found" : "Spjald fannst ekki", "Path is already shared with this card" : "Slóðinni er þegar deilt með þessu spjaldi", "Invalid date, date format must be YYYY-MM-DD" : "Ógild dagsetning, dagsetningasniðið verður að vera ÁÁÁÁ-MM-DD", + "All boards owned by you including stacks, cards, labels, assignments, and comments" : "Öll borð í þinni eigu að meðtöldum listum, spjöldum, merkjum, úthlutunum og athugasemdum", "Personal planning and team project organization" : "Persónuleg áætlanagerð og skipulag verkefnisvinnu", - "Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Dekk (e. Deck) er skipulagningartól í kanban-stíl sem ætlað er fyrir verkefna- og persónuupplýsingastjórnun hópvinnuteyma innan Nextcloud.\n\n\n- 📥 Settu verkefnin þín á spjöld of raðaðu þeim á ýmsa vegu\n- 📄 Skrifaðu niður minnispunkta í Markdown-kóða\n- 🔖 Úthlutaðu merkjum/skýringum til að bæta skipulagninguna\n- 👥 Deildu með vinnuhópnum, vinum eða fjölskyldu\n- 📎 Hengdu við skrár og ívefðu þær í lýsinguna með Markdown-kóða\n- 💬 Ræddu málin við hópinn þinn með athugasemdum\n- ⚡ Haltu utan um breytingar í virknistreyminu\n- 🚀 Haltu verkefnunum þínum skipulögðum", + "Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Dekk (e. Deck) er skipulagningartól í kanban-stíl sem ætlað er fyrir verkefna- og persónuupplýsingastjórnun hópvinnuteyma innan Nextcloud.\n\n\n- 📥 Settu verkefnin þín á spjöld gf raðaðu þeim á ýmsa vegu\n- 📄 Skrifaðu niður minnispunkta í Markdown-kóða\n- 🔖 Úthlutaðu merkjum/skýringum til að bæta skipulagninguna\n- 👥 Deildu með vinnuhópnum, vinum eða fjölskyldu\n- 📎 Hengdu við skrár og ívefðu þær í lýsinguna með Markdown-kóða\n- 💬 Ræddu málin við hópinn þinn með athugasemdum\n- ⚡ Haltu utan um breytingar í virknistreyminu\n- 🚀 Haltu verkefnunum þínum skipulögðum", "Add board" : "Bæta við borði", "Card details" : "Nánar um spjald", "Select the board to link to a project" : "Veldu borðið sem á að tengja við verkefnið", @@ -170,6 +177,8 @@ OC.L10N.register( "Clear filter" : "Hreinsa síu", "View Modes" : "Skoðunarhamir", "Toggle View Modes" : "Víxla milli skoðunarhama", + "Kanban view" : "Kanban-sýn", + "Gantt view" : "Gantt-sýn", "Hide archived cards" : "Fela spjöld í geymslu", "Show archived cards" : "Sýna spjöld í geymslu", "Toggle compact mode" : "Víxla þjöppuðum ham af/á", @@ -180,9 +189,11 @@ OC.L10N.register( "Deck settings" : "Stillingar Deck", "General" : "Almennt", "Use bigger card view" : "Nota stærri spjaldasýn", + "Add new cards at the top of a list" : "Bæta nýjum spjöldum efst á lista", "Appearance" : "Útlit", "Show card ID badge" : "Sýna auðkennismerki spjalds", "Show boards in calendar/tasks" : "Birta borð í dagatali/verkefnum", + "Admin settings" : "Stjórnunarstillingar", "Limit board creation to some groups" : "Takmarka gerð borða við suma hópa", "Users outside of those groups will not be able to create their own boards, but will still be able to work on boards that have been shared with them." : "Notendur sem tilheyra ekki þessum hópum eru útilokaðir frá því að útbúa sín eigin borð, en munu samt geta áfram unnið með borð sem hefur verið deilt til þeirra.", "Enable federation" : "Virkja skýjasamband", @@ -202,6 +213,8 @@ OC.L10N.register( "Mark card as completed/not completed" : "Merkja spjaldið sem frágengið/ólokið", "Open card menu" : "Opna valmynd spjalds", "Currently present people" : "Viðstatt fólk", + "Supported prefixes: {prefixes}. Wrap phrases in double quotes." : "Studd forskeyti: {prefixes}. Umlykja setningar í tvöföldum gæsalöppum.", + "Search cards" : "Leita að spjöldum", "Loading board" : "Hleð inn borði", "Board not found" : "Borð fannst ekki", "Create a new list to add cards to this board" : "Búðu til nýjan lista til að bæta spjöldum á þetta borð", @@ -217,6 +230,8 @@ OC.L10N.register( "Weeks" : "Vikur", "Months" : "Mánuðir", "No cards yet" : "Engin spjöld ennþá", + "Set a start date and due date on your cards to see them on the Gantt chart" : "Veldu upphafsdagsetningu og lokadagsetningu á spjöldunum þínum til að sjá þau á Gantt-kortinu", + "Cards without dates ({count})" : "Spjöld á dagsetninga ({count})", "Failed to create share with {displayName}" : "Gat ekki búið til sameign með {displayName}", "Are you sure you want to transfer the board {title} to {user}?" : "Ertu viss um að þú viljir yfirfæra borðið {title} til {user}?", "Transfer the board." : "Flytja borðið.", @@ -236,6 +251,8 @@ OC.L10N.register( "Edit list title" : "Breyta titli lista", "Archive all cards" : "Setja öll spjöld í geymslu", "Unarchive all cards" : "Taka öll spjöld úr geymslu", + "Do not set cards as \"done\"" : "Ekki merkja spjöld sem \"lokið\"", + "Set cards as \"done\"" : "Merkja spjöld sem \"lokið\"", "Delete list" : "Eyða lista", "Archive all cards in this list" : "Setja öll spjöld á þessum lista í geymslu", "Unarchive all cards in this list" : "Taka öll spjöld á þessum lista úr geymslu", @@ -244,6 +261,7 @@ OC.L10N.register( "title and color value must be provided" : "titill og litgildi verða að vera til staðar", "Edit" : "Breyta", "Add a new tag" : "Bæta við nýju merki", + "Search boards" : "Leita að borðum", "Board name" : "Heiti borðs", "Members" : "Meðlimir", "Assign to users/groups/team" : "Úthluta á notendur/hópa/teymi", @@ -260,7 +278,11 @@ OC.L10N.register( "Remove attachment" : "Fjarlægja viðhengi", "Delete Attachment" : "Eyða viðhengi", "Restore Attachment" : "Endurheimta viðhengi", + "Modified: {modifiedDate} ⸱ Created: {createdDate}" : "Breytt: {modifiedDate} ⸱ Útbúið: {createdDate}", + "Modified: {modifiedDate}\nCreated: {createdDate}\nCreated by: {owner}" : "Breytt: {modifiedDate}\nÚtbúið: {createdDate}\nÚtbúið af: {owner}", + "Modified: {modifiedDate}\nCreated: {createdDate}" : "Breytt: {modifiedDate}\nÚtbúið: {createdDate}", "The title cannot be empty." : "Titill getur ekki verið auður.", + "Cannot close unsaved card!" : "Get ekki lokað óvistuðu spjaldi!", "Open in sidebar view" : "Opna í hliðarspjaldssýn", "Open in bigger view" : "Opna í stærri sýn", "Comments" : "Athugasemdir", @@ -274,9 +296,16 @@ OC.L10N.register( "Cancel reply" : "Hætta við svar", "Reply" : "Svara", "Update" : "Uppfæra", + "Assign dependent cards" : "Úthluta háðum spjöldum", "Mark as done" : "Merkja sem lokið", "Mark as not done" : "Merkja sem ólokið", + "Remove dependency" : "Fjarlægja hæði", + "Add dependent card" : "Bæta við háðu spjaldi", + "Assign a dependent card…" : "Úthluta háðu spjaldi…", + "Select a dependent card…" : "Veldu háð spjald…", "Write a description …" : "Skrifaðu lýsingu …", + "The description has been changed by another user." : "Lýsingunni hefur verið breytt af öðrum notanda.", + "Could not save description" : "Tókst ekki að vista lýsingu", "Description" : "Lýsing", "(Unsaved)" : "(Óvistað)", "(Saving…)" : "(Vista…)", @@ -303,6 +332,10 @@ OC.L10N.register( "Not done" : "Ekki lokið", "Unarchive card" : "Taka spjald úr geymslu", "Archive card" : "Setja spjald í geymslu", + "Assign a start date to this card…" : "Úthluta upphafsdagsetningu á þetta spjald…", + "Set a start date" : "Veldu upphafsdagsetningu", + "Add start date" : "Bæta við upphafsdagsetningu", + "Remove start date" : "Fjarlægja upphafsdagsetningu", "Assign a tag to this card…" : "Úthluta merki á þetta spjald", "Select or create a tag…" : "Veldu eða búðu til merki…", "Create a new tag:" : "Búa til nýtt merki:", @@ -312,6 +345,7 @@ OC.L10N.register( "Edit card title" : "Breyta titli spjalds", "Open link" : "Opna tengil", "Card deleted" : "Spjaldi eytt", + "Change card color" : "Breyta lit spjalds", "Edit title" : "Breyta titli", "Assign to me" : "Úthluta mér", "Unassign myself" : "Aftengja úthlutun sjálfs mín", @@ -327,6 +361,11 @@ OC.L10N.register( "No reminder" : "Engin áminning", "Are you sure you want to delete the board {title}? This will delete all the data of this board including archived cards." : "Ertu viss um að þú viljir eyða borðinu {title}?. Þetta mun eyða öllum gögnum í þessu borði, meðal annars spjöldum í geymslu.", "Delete the board?" : "Eyða borðinu?", + "Are you sure you want to leave the board {title}?" : "Ertu viss um að þú viljir yfirgefa {title} borðið?", + "Leave the board?" : "Yfirgefa borðið?", + "Leave" : "Fara", + "Failed to leave the board" : "Tókst ekki að yfirgefa borðið", + "Exporting board..." : "Flyt út borð…", "An error occurred" : "Villa kom upp", "Board details" : "Nánar um borð", "Edit board" : "Breyta borði", @@ -336,10 +375,16 @@ OC.L10N.register( "Export board" : "Flytja út borð", "Turn on due date reminders" : "Kveikja á áminningum um skiladagsetningar", "Turn off due date reminders" : "Slökkva á áminningum um skiladagsetningar", + "Remove as default board" : "Fjarlægja sem sjálfgefið borð", + "Set as default board" : "Setja sem sjálfgefið borð", "Due date reminders" : "Áminningar um skiladagsetningar", "Assigned cards" : "Úthlutuð spjöld", "No notifications" : "Engar tilkynningar", "Delete board" : "Eyða borði", + "Leave board" : "Yfirgefa borð", + "Importing board..." : "Flyt inn borð…", + "Board imported successfully" : "Tókst að flytja inn borð", + "Import board" : "Flytja inn borð", "Clone {boardTitle}" : "Klóna {boardTitle}", "Clone cards" : "Klóna spjöld", "Clone assignments" : "Klóna úthlutanir", @@ -349,8 +394,13 @@ OC.L10N.register( "Move all cards to the first list" : "Færa öll spjöld á fyrsta listann", "Restore archived cards" : "Endurheimta spjöld úr geymslu", "Clone" : "Klóna", + "Export {boardTitle}" : "Flytja út {boardTitle}", + "Export as JSON" : "Flytja út sem JSON", + "Export as CSV" : "Flytja út sem CSV", + "Note: Only the JSON format is supported for importing back into the Deck app." : "Athugaðu: Aðeins er hægt að nota JSON-snið til að flytja aftur inn í Deck-forritið.", "Export" : "Flytja út", "Loading filtered view" : "Hleð inn síaðri sýn", + "Search for {searchQuery} in other boards" : "Leita að {searchQuery} í öðrum borðum", "Search for {searchQuery} in all boards" : "Leita að {searchQuery} í öllum borðum", "No results found" : "Engar niðurstöður fundust", "Deck board {name}\n* Last modified on {lastMod}" : "Deck-borð {name}\n* Síðast breytt {lastMod}", @@ -379,6 +429,7 @@ OC.L10N.register( "Something went wrong" : "Eitthvað fór úrskeiðis", "Failed to upload {name}" : "Mistókst að senda inn {name}", "Maximum file size of {size} exceeded" : "Fór yfir hámarks skráarstærð {size}", + "Assigned users" : "Tilnefndir notendur", "Due date" : "Skiladagur", "Created" : "Búið til þann", "Modified" : "Breytt", diff --git a/l10n/is.json b/l10n/is.json index bbaab6c8ae..1c7b5d48c1 100644 --- a/l10n/is.json +++ b/l10n/is.json @@ -79,6 +79,9 @@ "Could not write file to disk" : "Tókst ekki að skrifa skrá á disk.", "A PHP extension stopped the file upload" : "PHP-viðbót stöðvaði innsendingu skráar", "No file uploaded or file size exceeds maximum of %s" : "Engin innsend skrá eða að skráarstærð fór fram úr hámarksstæðinni %s", + "Invalid file type. Only JSON files are allowed." : "Ógild skráategund. Einungis er tekið við JSON-skrám.", + "Invalid JSON data" : "Ógild JSON-gögn", + "Failed to import board" : "Mistókst að flytja inn borð", "Cards due today" : "Spjöld sem á að ljúka í dag", "Cards due tomorrow" : "Spjöld sem á að ljúka á morgun", "Upcoming cards" : "Spjöld á næstunni", @@ -86,11 +89,13 @@ "Welcome to Nextcloud Deck!" : "Velkomin í Nextcloud Deck!", "The card \"%s\" on \"%s\" has been assigned to you by %s." : "Spjaldinu \"%s\" á \"%s\" hefur verið úthlutað til þín af %s.", "{user} has assigned the card {deck-card} on {deck-board} to you." : "{user} hefur úthlutað spjaldinu {deck-card} á {deck-board} til þín.", + "The card \"%1$s\" on \"%2$s\" has reached its due date." : "Spjaldið \"%1$s\" á \"%2$s\" er komið fram yfir lokadagsetningu.", "The card {deck-card} on {deck-board} has reached its due date." : "Spjaldið {deck-card} á {deck-board} er komið fram yfir lokadagsetningu.", "%s has mentioned you in a comment on \"%s\"." : "%s minntist á þig í athugasemd við \"%s\".", "{user} has mentioned you in a comment on {deck-card}." : "{user} minntist á þig í athugasemd við {deck-card}.", "The board \"%s\" has been shared with you by %s." : "Borðinu \"%s\" hefur verið deilt með þér af %s.", "{user} has shared {deck-board} with you." : "{user} deildi {deck-board} með þér.", + "The remote board %1$s has been shared with you by %2$s" : "Fjartengda borðinu %1$s hefur verið deilt með þér af %2$s", "Deck board" : "Deck-borð", "Owned by %1$s" : "Í eigu notandans %1$s", "Deck boards, cards and comments" : "Deck-borð, spjöld og athugasemdir", @@ -118,11 +123,13 @@ "This comment has more than %s characters.\nAdded as an attachment to the card with name %s.\nAccessible on URL: %s." : "Þessi athugasemd er lengri en %s stafir.\nBætt við sem viðhengi á spjald með heitinu %s.\nAðgengileg á slóðinni: %s.", "Attachments" : "Viðhengi", "File" : "Skrá", + "date" : "dagsetning", "Card not found" : "Spjald fannst ekki", "Path is already shared with this card" : "Slóðinni er þegar deilt með þessu spjaldi", "Invalid date, date format must be YYYY-MM-DD" : "Ógild dagsetning, dagsetningasniðið verður að vera ÁÁÁÁ-MM-DD", + "All boards owned by you including stacks, cards, labels, assignments, and comments" : "Öll borð í þinni eigu að meðtöldum listum, spjöldum, merkjum, úthlutunum og athugasemdum", "Personal planning and team project organization" : "Persónuleg áætlanagerð og skipulag verkefnisvinnu", - "Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Dekk (e. Deck) er skipulagningartól í kanban-stíl sem ætlað er fyrir verkefna- og persónuupplýsingastjórnun hópvinnuteyma innan Nextcloud.\n\n\n- 📥 Settu verkefnin þín á spjöld of raðaðu þeim á ýmsa vegu\n- 📄 Skrifaðu niður minnispunkta í Markdown-kóða\n- 🔖 Úthlutaðu merkjum/skýringum til að bæta skipulagninguna\n- 👥 Deildu með vinnuhópnum, vinum eða fjölskyldu\n- 📎 Hengdu við skrár og ívefðu þær í lýsinguna með Markdown-kóða\n- 💬 Ræddu málin við hópinn þinn með athugasemdum\n- ⚡ Haltu utan um breytingar í virknistreyminu\n- 🚀 Haltu verkefnunum þínum skipulögðum", + "Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Dekk (e. Deck) er skipulagningartól í kanban-stíl sem ætlað er fyrir verkefna- og persónuupplýsingastjórnun hópvinnuteyma innan Nextcloud.\n\n\n- 📥 Settu verkefnin þín á spjöld gf raðaðu þeim á ýmsa vegu\n- 📄 Skrifaðu niður minnispunkta í Markdown-kóða\n- 🔖 Úthlutaðu merkjum/skýringum til að bæta skipulagninguna\n- 👥 Deildu með vinnuhópnum, vinum eða fjölskyldu\n- 📎 Hengdu við skrár og ívefðu þær í lýsinguna með Markdown-kóða\n- 💬 Ræddu málin við hópinn þinn með athugasemdum\n- ⚡ Haltu utan um breytingar í virknistreyminu\n- 🚀 Haltu verkefnunum þínum skipulögðum", "Add board" : "Bæta við borði", "Card details" : "Nánar um spjald", "Select the board to link to a project" : "Veldu borðið sem á að tengja við verkefnið", @@ -168,6 +175,8 @@ "Clear filter" : "Hreinsa síu", "View Modes" : "Skoðunarhamir", "Toggle View Modes" : "Víxla milli skoðunarhama", + "Kanban view" : "Kanban-sýn", + "Gantt view" : "Gantt-sýn", "Hide archived cards" : "Fela spjöld í geymslu", "Show archived cards" : "Sýna spjöld í geymslu", "Toggle compact mode" : "Víxla þjöppuðum ham af/á", @@ -178,9 +187,11 @@ "Deck settings" : "Stillingar Deck", "General" : "Almennt", "Use bigger card view" : "Nota stærri spjaldasýn", + "Add new cards at the top of a list" : "Bæta nýjum spjöldum efst á lista", "Appearance" : "Útlit", "Show card ID badge" : "Sýna auðkennismerki spjalds", "Show boards in calendar/tasks" : "Birta borð í dagatali/verkefnum", + "Admin settings" : "Stjórnunarstillingar", "Limit board creation to some groups" : "Takmarka gerð borða við suma hópa", "Users outside of those groups will not be able to create their own boards, but will still be able to work on boards that have been shared with them." : "Notendur sem tilheyra ekki þessum hópum eru útilokaðir frá því að útbúa sín eigin borð, en munu samt geta áfram unnið með borð sem hefur verið deilt til þeirra.", "Enable federation" : "Virkja skýjasamband", @@ -200,6 +211,8 @@ "Mark card as completed/not completed" : "Merkja spjaldið sem frágengið/ólokið", "Open card menu" : "Opna valmynd spjalds", "Currently present people" : "Viðstatt fólk", + "Supported prefixes: {prefixes}. Wrap phrases in double quotes." : "Studd forskeyti: {prefixes}. Umlykja setningar í tvöföldum gæsalöppum.", + "Search cards" : "Leita að spjöldum", "Loading board" : "Hleð inn borði", "Board not found" : "Borð fannst ekki", "Create a new list to add cards to this board" : "Búðu til nýjan lista til að bæta spjöldum á þetta borð", @@ -215,6 +228,8 @@ "Weeks" : "Vikur", "Months" : "Mánuðir", "No cards yet" : "Engin spjöld ennþá", + "Set a start date and due date on your cards to see them on the Gantt chart" : "Veldu upphafsdagsetningu og lokadagsetningu á spjöldunum þínum til að sjá þau á Gantt-kortinu", + "Cards without dates ({count})" : "Spjöld á dagsetninga ({count})", "Failed to create share with {displayName}" : "Gat ekki búið til sameign með {displayName}", "Are you sure you want to transfer the board {title} to {user}?" : "Ertu viss um að þú viljir yfirfæra borðið {title} til {user}?", "Transfer the board." : "Flytja borðið.", @@ -234,6 +249,8 @@ "Edit list title" : "Breyta titli lista", "Archive all cards" : "Setja öll spjöld í geymslu", "Unarchive all cards" : "Taka öll spjöld úr geymslu", + "Do not set cards as \"done\"" : "Ekki merkja spjöld sem \"lokið\"", + "Set cards as \"done\"" : "Merkja spjöld sem \"lokið\"", "Delete list" : "Eyða lista", "Archive all cards in this list" : "Setja öll spjöld á þessum lista í geymslu", "Unarchive all cards in this list" : "Taka öll spjöld á þessum lista úr geymslu", @@ -242,6 +259,7 @@ "title and color value must be provided" : "titill og litgildi verða að vera til staðar", "Edit" : "Breyta", "Add a new tag" : "Bæta við nýju merki", + "Search boards" : "Leita að borðum", "Board name" : "Heiti borðs", "Members" : "Meðlimir", "Assign to users/groups/team" : "Úthluta á notendur/hópa/teymi", @@ -258,7 +276,11 @@ "Remove attachment" : "Fjarlægja viðhengi", "Delete Attachment" : "Eyða viðhengi", "Restore Attachment" : "Endurheimta viðhengi", + "Modified: {modifiedDate} ⸱ Created: {createdDate}" : "Breytt: {modifiedDate} ⸱ Útbúið: {createdDate}", + "Modified: {modifiedDate}\nCreated: {createdDate}\nCreated by: {owner}" : "Breytt: {modifiedDate}\nÚtbúið: {createdDate}\nÚtbúið af: {owner}", + "Modified: {modifiedDate}\nCreated: {createdDate}" : "Breytt: {modifiedDate}\nÚtbúið: {createdDate}", "The title cannot be empty." : "Titill getur ekki verið auður.", + "Cannot close unsaved card!" : "Get ekki lokað óvistuðu spjaldi!", "Open in sidebar view" : "Opna í hliðarspjaldssýn", "Open in bigger view" : "Opna í stærri sýn", "Comments" : "Athugasemdir", @@ -272,9 +294,16 @@ "Cancel reply" : "Hætta við svar", "Reply" : "Svara", "Update" : "Uppfæra", + "Assign dependent cards" : "Úthluta háðum spjöldum", "Mark as done" : "Merkja sem lokið", "Mark as not done" : "Merkja sem ólokið", + "Remove dependency" : "Fjarlægja hæði", + "Add dependent card" : "Bæta við háðu spjaldi", + "Assign a dependent card…" : "Úthluta háðu spjaldi…", + "Select a dependent card…" : "Veldu háð spjald…", "Write a description …" : "Skrifaðu lýsingu …", + "The description has been changed by another user." : "Lýsingunni hefur verið breytt af öðrum notanda.", + "Could not save description" : "Tókst ekki að vista lýsingu", "Description" : "Lýsing", "(Unsaved)" : "(Óvistað)", "(Saving…)" : "(Vista…)", @@ -301,6 +330,10 @@ "Not done" : "Ekki lokið", "Unarchive card" : "Taka spjald úr geymslu", "Archive card" : "Setja spjald í geymslu", + "Assign a start date to this card…" : "Úthluta upphafsdagsetningu á þetta spjald…", + "Set a start date" : "Veldu upphafsdagsetningu", + "Add start date" : "Bæta við upphafsdagsetningu", + "Remove start date" : "Fjarlægja upphafsdagsetningu", "Assign a tag to this card…" : "Úthluta merki á þetta spjald", "Select or create a tag…" : "Veldu eða búðu til merki…", "Create a new tag:" : "Búa til nýtt merki:", @@ -310,6 +343,7 @@ "Edit card title" : "Breyta titli spjalds", "Open link" : "Opna tengil", "Card deleted" : "Spjaldi eytt", + "Change card color" : "Breyta lit spjalds", "Edit title" : "Breyta titli", "Assign to me" : "Úthluta mér", "Unassign myself" : "Aftengja úthlutun sjálfs mín", @@ -325,6 +359,11 @@ "No reminder" : "Engin áminning", "Are you sure you want to delete the board {title}? This will delete all the data of this board including archived cards." : "Ertu viss um að þú viljir eyða borðinu {title}?. Þetta mun eyða öllum gögnum í þessu borði, meðal annars spjöldum í geymslu.", "Delete the board?" : "Eyða borðinu?", + "Are you sure you want to leave the board {title}?" : "Ertu viss um að þú viljir yfirgefa {title} borðið?", + "Leave the board?" : "Yfirgefa borðið?", + "Leave" : "Fara", + "Failed to leave the board" : "Tókst ekki að yfirgefa borðið", + "Exporting board..." : "Flyt út borð…", "An error occurred" : "Villa kom upp", "Board details" : "Nánar um borð", "Edit board" : "Breyta borði", @@ -334,10 +373,16 @@ "Export board" : "Flytja út borð", "Turn on due date reminders" : "Kveikja á áminningum um skiladagsetningar", "Turn off due date reminders" : "Slökkva á áminningum um skiladagsetningar", + "Remove as default board" : "Fjarlægja sem sjálfgefið borð", + "Set as default board" : "Setja sem sjálfgefið borð", "Due date reminders" : "Áminningar um skiladagsetningar", "Assigned cards" : "Úthlutuð spjöld", "No notifications" : "Engar tilkynningar", "Delete board" : "Eyða borði", + "Leave board" : "Yfirgefa borð", + "Importing board..." : "Flyt inn borð…", + "Board imported successfully" : "Tókst að flytja inn borð", + "Import board" : "Flytja inn borð", "Clone {boardTitle}" : "Klóna {boardTitle}", "Clone cards" : "Klóna spjöld", "Clone assignments" : "Klóna úthlutanir", @@ -347,8 +392,13 @@ "Move all cards to the first list" : "Færa öll spjöld á fyrsta listann", "Restore archived cards" : "Endurheimta spjöld úr geymslu", "Clone" : "Klóna", + "Export {boardTitle}" : "Flytja út {boardTitle}", + "Export as JSON" : "Flytja út sem JSON", + "Export as CSV" : "Flytja út sem CSV", + "Note: Only the JSON format is supported for importing back into the Deck app." : "Athugaðu: Aðeins er hægt að nota JSON-snið til að flytja aftur inn í Deck-forritið.", "Export" : "Flytja út", "Loading filtered view" : "Hleð inn síaðri sýn", + "Search for {searchQuery} in other boards" : "Leita að {searchQuery} í öðrum borðum", "Search for {searchQuery} in all boards" : "Leita að {searchQuery} í öllum borðum", "No results found" : "Engar niðurstöður fundust", "Deck board {name}\n* Last modified on {lastMod}" : "Deck-borð {name}\n* Síðast breytt {lastMod}", @@ -377,6 +427,7 @@ "Something went wrong" : "Eitthvað fór úrskeiðis", "Failed to upload {name}" : "Mistókst að senda inn {name}", "Maximum file size of {size} exceeded" : "Fór yfir hámarks skráarstærð {size}", + "Assigned users" : "Tilnefndir notendur", "Due date" : "Skiladagur", "Created" : "Búið til þann", "Modified" : "Breytt", From 0620640e1875ca5755c8d9851e8e69bcdf055690 Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Tue, 8 Sep 2026 01:02:59 +0000 Subject: [PATCH 17/31] fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- l10n/id.js | 1 + l10n/id.json | 1 + 2 files changed, 2 insertions(+) diff --git a/l10n/id.js b/l10n/id.js index 0348cd5ce6..23145251c8 100644 --- a/l10n/id.js +++ b/l10n/id.js @@ -191,6 +191,7 @@ OC.L10N.register( "Admin settings" : "Pengaturan admin", "Limit board creation to some groups" : "Batasi pembuatan papan untuk beberapa grup", "Users outside of those groups will not be able to create their own boards, but will still be able to work on boards that have been shared with them." : "Pengguna di luar grup tersebut tidak akan dapat membuat papan mereka sendiri, tetapi masih dapat bekerja di papan yang telah dibagikan dengan mereka.", + "Enable federation" : "Aktifkan federasi", "Board actions" : "Aksi papan", "Scroll sideways" : "Gulir ke samping", "Navigate between cards" : "Navigasi antar kartu", diff --git a/l10n/id.json b/l10n/id.json index 9c16cb85c5..12f03c7c9d 100644 --- a/l10n/id.json +++ b/l10n/id.json @@ -189,6 +189,7 @@ "Admin settings" : "Pengaturan admin", "Limit board creation to some groups" : "Batasi pembuatan papan untuk beberapa grup", "Users outside of those groups will not be able to create their own boards, but will still be able to work on boards that have been shared with them." : "Pengguna di luar grup tersebut tidak akan dapat membuat papan mereka sendiri, tetapi masih dapat bekerja di papan yang telah dibagikan dengan mereka.", + "Enable federation" : "Aktifkan federasi", "Board actions" : "Aksi papan", "Scroll sideways" : "Gulir ke samping", "Navigate between cards" : "Navigasi antar kartu", From 899db4e26219c8a4cc540b74039acf86132a2460 Mon Sep 17 00:00:00 2001 From: Luka Trovic Date: Thu, 10 Sep 2026 18:49:41 +0200 Subject: [PATCH 18/31] chore(CI): adjust testing matrix for Nextcloud 35 on stable35 Signed-off-by: Luka Trovic --- .github/workflows/cypress-e2e.yml | 2 +- .github/workflows/integration-federation.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cypress-e2e.yml b/.github/workflows/cypress-e2e.yml index 5b2929ee9b..9221f035c6 100644 --- a/.github/workflows/cypress-e2e.yml +++ b/.github/workflows/cypress-e2e.yml @@ -25,7 +25,7 @@ jobs: node-version: [20.x] containers: [1, 2, 3] php-versions: [ '8.3' ] - server-versions: [ 'master' ] + server-versions: [ 'stable35' ] name: runner ${{ matrix.containers }} diff --git a/.github/workflows/integration-federation.yml b/.github/workflows/integration-federation.yml index 374460fd94..0b9708268d 100644 --- a/.github/workflows/integration-federation.yml +++ b/.github/workflows/integration-federation.yml @@ -30,7 +30,7 @@ jobs: fail-fast: false matrix: php-versions: ['8.4'] - server-versions: ['master'] + server-versions: ['stable35'] name: php${{ matrix.php-versions }}-${{ matrix.server-versions }} From 0d4f060153faf3d5ee07fb8b788b1fde94f46a44 Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Fri, 11 Sep 2026 00:57:23 +0000 Subject: [PATCH 19/31] fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- l10n/cs.js | 2 + l10n/cs.json | 2 + l10n/fr.js | 254 +++++++++++++++++++++++++-------------------------- l10n/fr.json | 254 +++++++++++++++++++++++++-------------------------- 4 files changed, 258 insertions(+), 254 deletions(-) diff --git a/l10n/cs.js b/l10n/cs.js index 8d4de49f76..7f8bc03311 100644 --- a/l10n/cs.js +++ b/l10n/cs.js @@ -176,6 +176,8 @@ OC.L10N.register( "Clear filter" : "Vyčistit filtr", "View Modes" : "Zobrazit režimy", "Toggle View Modes" : "Přepnout mezi režimy zobrazení", + "Kanban view" : "Zobrazení jako kanban", + "Gantt view" : "Zobrazení jako Ganttovy grafy", "Hide archived cards" : "Skrýt archivované karty", "Show archived cards" : "Zobrazit archivované karty", "Toggle compact mode" : "Vyp/zap. kompaktní režim", diff --git a/l10n/cs.json b/l10n/cs.json index 7240179bb8..4fd0462eb5 100644 --- a/l10n/cs.json +++ b/l10n/cs.json @@ -174,6 +174,8 @@ "Clear filter" : "Vyčistit filtr", "View Modes" : "Zobrazit režimy", "Toggle View Modes" : "Přepnout mezi režimy zobrazení", + "Kanban view" : "Zobrazení jako kanban", + "Gantt view" : "Zobrazení jako Ganttovy grafy", "Hide archived cards" : "Skrýt archivované karty", "Show archived cards" : "Zobrazit archivované karty", "Toggle compact mode" : "Vyp/zap. kompaktní režim", diff --git a/l10n/fr.js b/l10n/fr.js index b5631903df..13d9b8f792 100644 --- a/l10n/fr.js +++ b/l10n/fr.js @@ -8,7 +8,7 @@ OC.L10N.register( "You have restored the board {board}" : "Vous avez restauré le tableau {board}", "{user} has restored the board {board}" : "{user} a restauré le tableau {board}", "You have shared the board {board} with {acl}" : "Vous avez partagé le tableau {board} avec {acl}", - "{user} has shared the board {board} with {acl}" : "{user} a partagé le tableau {board} en {acl}", + "{user} has shared the board {board} with {acl}" : "{user} a partagé le tableau {board} avec {acl}", "You have removed {acl} from the board {board}" : "Vous avez supprimé {acl} du tableau {board}", "{user} has removed {acl} from the board {board}" : "{user} a supprimé {acl} du tableau {board}", "You have renamed the board {before} to {board}" : "Vous avez renommé le tableau {before} en {board}", @@ -37,16 +37,16 @@ OC.L10N.register( "{user} has archived card {card} in list {stack} on board {board}" : "{user} a archivé la carte {card} de la liste {stack} du tableau {board}", "You have unarchived card {card} in list {stack} on board {board}" : "Vous avez désarchivé la carte {card} de la liste {stack} du tableau {board}", "{user} has unarchived card {card} in list {stack} on board {board}" : "{user} a désarchivé la carte {card} de la liste {stack} du tableau {board}", - "You have marked the card {card} as done in list {stack} on board {board}" : "Vous avez marqué la carte {card} comme faite dans la liste {stack} sur le tableau {board}", - "{user} has marked card {card} as done in list {stack} on board {board}" : "{user} a marqué la carte {card} comme faite dans la liste {stack} sur le tableau {board}", - "You have marked the card {card} as undone in list {stack} on board {board}" : "Vous avez marqué la carte {card} comme non faite dans la liste {stack} sur le tableau {board}", - "{user} has marked the card {card} as undone in list {stack} on board {board}" : "{user} a marqué la carte {card} comme non faite dans la liste {stack} sur le tableau {board}", + "You have marked the card {card} as done in list {stack} on board {board}" : "Vous avez marqué la carte {card} comme terminée dans la liste {stack} sur le tableau {board}", + "{user} has marked card {card} as done in list {stack} on board {board}" : "{user} a marqué la carte {card} comme terminée dans la liste {stack} sur le tableau {board}", + "You have marked the card {card} as undone in list {stack} on board {board}" : "Vous avez marqué la carte {card} comme non terminée dans la liste {stack} sur le tableau {board}", + "{user} has marked the card {card} as undone in list {stack} on board {board}" : "{user} a marqué la carte {card} comme non terminée dans la liste {stack} sur le tableau {board}", "You have removed the due date of card {card}" : "Vous avez supprimé la date d'échéance de la carte {card}", "{user} has removed the due date of card {card}" : "{user} a supprimé la date d'échéance de la carte {card}", - "You have set the due date of card {card} to {after}" : "Vous avez établi la date d'échéance de la carte {card} au {after}", - "{user} has set the due date of card {card} to {after}" : "{user} a établi la date d'échéance de la carte {card} à {after}", - "You have updated the due date of card {card} to {after}" : "Vous avez mis à jour la date d'échéance de la carte {card} au {after}", - "{user} has updated the due date of card {card} to {after}" : "{user} a mis à jour la date d'échéance de la carte {card} à {after}", + "You have set the due date of card {card} to {after}" : "Vous avez fixé la date d’échéance de la carte {card} au {after}", + "{user} has set the due date of card {card} to {after}" : "{user} a fixé la date d’échéance de la carte {card} au {after}", + "You have updated the due date of card {card} to {after}" : "Vous avez modifié la date d’échéance de la carte {card} au {after}", + "{user} has updated the due date of card {card} to {after}" : "{user} a modifié la date d’échéance de la carte {card} au {after}", "You have added the tag {label} to card {card} in list {stack} on board {board}" : "Vous avez ajouté l'étiquette {label} à la carte {card} de la liste {stack} du tableau {board}", "{user} has added the tag {label} to card {card} in list {stack} on board {board}" : "{user} a ajouté l'étiquette {label} à la carte {card} de la liste {stack} du tableau {board}", "You have removed the tag {label} from card {card} in list {stack} on board {board}" : "Vous avez supprimé l'étiquette {label} de la carte {card} de la liste {stack} du tableau {board}", @@ -68,40 +68,40 @@ OC.L10N.register( "You have commented on card {card}" : "Vous avez commenté la carte {card}", "{user} has commented on card {card}" : "{user} a commenté la carte {card}", "Deck" : "Deck", - "Changes in the Deck app" : "Modifications dans Deck app", - "A board, list or card was changed" : "Un(e) tableau, liste ou carte a été modifié(e)", - "A comment was created on a card" : "Un commentaire a été créé sur une carte", + "Changes in the Deck app" : "Modifications dans Deck", + "A board, list or card was changed" : "Un tableau, une liste ou une carte a fait l’objet d’une modification", + "A comment was created on a card" : "Un commentaire a été ajouté à une carte", "A card description has been changed" : "La description de la carte a été modifiée", "The file was uploaded" : "Le fichier a été envoyé", - "The uploaded file exceeds the upload_max_filesize directive in php.ini" : "Le fichier envoyé dépasse la valeur upload_max_filesize spécifiée dans php.ini", - "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Le fichier envoyé dépasse la valeur MAX_FILE_SIZE spécifiée dans le formulaire HTML", - "The file was only partially uploaded" : "Le fichier n'a été que partiellement envoyé", - "No file was uploaded" : "Aucun fichier n'a été envoyé", + "The uploaded file exceeds the upload_max_filesize directive in php.ini" : "Le fichier envoyé dépasse la directive upload_max_filesize définie dans php.ini", + "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Le fichier envoyé dépasse la directive MAX_FILE_SIZE définie dans le formulaire HTML", + "The file was only partially uploaded" : "Le fichier n’a été que partiellement envoyé", + "No file was uploaded" : "Aucun fichier n’a été envoyé", "Missing a temporary folder" : "Absence de dossier temporaire", "Could not write file to disk" : "Impossible d'écrire le fichier sur le disque", - "A PHP extension stopped the file upload" : "Une extension PHP a arrêté l'envoi du fichier", - "No file uploaded or file size exceeds maximum of %s" : "Aucun fichier envoyé ou la taille du fichier dépasse le maximum de %s", + "A PHP extension stopped the file upload" : "Une extension PHP a interrompu l’envoi du fichier", + "No file uploaded or file size exceeds maximum of %s" : "Aucun fichier n’a été envoyé ou sa taille dépasse la limite maximale de %s", "Invalid file type. Only JSON files are allowed." : "Type de fichier non valide. Seuls les fichiers JSON sont autorisés.", "Invalid JSON data" : "Données JSON non valides", "Failed to import board" : "Échec de l'importation du tableau", - "Cards due today" : "Cartes pour aujourd'hui", - "Cards due tomorrow" : "Cartes pour demain", - "Upcoming cards" : "Prochaines cartes", + "Cards due today" : "Cartes à échéance aujourd’hui", + "Cards due tomorrow" : "Cartes à échéance demain", + "Upcoming cards" : "Cartes à venir", "Load more" : "Charger davantage", - "Welcome to Nextcloud Deck!" : "Bienvenue dans Nextcloud Deck !", - "The card \"%s\" on \"%s\" has been assigned to you by %s." : "La carte \"%s\" de \"%s\" vous a été assignée par %s.", + "Welcome to Nextcloud Deck!" : "Bienvenue dans Nextcloud Deck !", + "The card \"%s\" on \"%s\" has been assigned to you by %s." : "La carte « %s » du tableau « %s » vous a été attribuée par %s.", "{user} has assigned the card {deck-card} on {deck-board} to you." : "{user} vous a attribué la carte {deck-card} du tableau {deck-board}.", - "The card \"%1$s\" on \"%2$s\" has reached its due date." : "La carte \"%1$s\" sur \"%2$s\" est arrivée à échéance.", - "The card {deck-card} on {deck-board} has reached its due date." : "La carte {deck-card} sur {deck-board} a atteint sa date d'échéance.", - "%s has mentioned you in a comment on \"%s\"." : "%s vous a mentionné dans un commentaire sur \"%s\".", - "{user} has mentioned you in a comment on {deck-card}." : "{user} vous a cité dans un commentaire sur {deck-card}.", - "The board \"%s\" has been shared with you by %s." : "Le tableau \"%s\" a été partagé avec vous par %s.", - "{user} has shared {deck-board} with you." : "{user} vous a partagé le tableau {deck-board}.", + "The card \"%1$s\" on \"%2$s\" has reached its due date." : "La carte « %1$s » du tableau « %2$s » est arrivée à échéance.", + "The card {deck-card} on {deck-board} has reached its due date." : "La carte {deck-card} du tableau {deck-board} est arrivée à échéance.", + "%s has mentioned you in a comment on \"%s\"." : "%s vous a mentionné dans un commentaire sur « %s ».", + "{user} has mentioned you in a comment on {deck-card}." : "{user} vous a mentionné dans un commentaire sur {deck-card}.", + "The board \"%s\" has been shared with you by %s." : "Le tableau « %s » a été partagé avec vous par %s.", + "{user} has shared {deck-board} with you." : "{user} a partagé le tableau {deck-board} avec vous.", "The remote board %1$s has been shared with you by %2$s" : "Le tableau distant %1$s a été partagé avec vous par %2$s", "Deck board" : "Tableau Deck", - "Owned by %1$s" : "Assignée à %1$s", + "Owned by %1$s" : "Propriété de %1$s", "Deck boards, cards and comments" : "Tableaux, cartes et commentaires de Deck", - "From %1$s, in %2$s/%3$s, owned by %4$s" : "De %1$s, dans %2$s / %3$s, appartenant à %4$s", + "From %1$s, in %2$s/%3$s, owned by %4$s" : "Par %1$s, dans %2$s/%3$s, tableau de %4$s", "Create a new deck card" : "Créer une nouvelle carte Deck", "Card comments" : "Commentaires des cartes", "%s on %s" : "%s sur %s", @@ -112,29 +112,29 @@ OC.L10N.register( "Action needed" : "Action requise", "Later" : "Plus tard", "copy" : "copie", - "Read more inside" : "Lire la suite à l'intérieur", - "Custom lists - click to rename!" : "Listes personnalisées - cliquez pour renommer !", + "Read more inside" : "En savoir plus dans la carte", + "Custom lists - click to rename!" : "Listes personnalisées — cliquez pour renommer !", "To Do" : "À faire", "In Progress" : "En cours", - "Done" : "Fait", + "Done" : "Terminé", "1. Open to learn more about boards and cards" : "1. Ouvrez pour en apprendre davantage sur les tableaux et les cartes", "2. Drag cards left and right, up and down" : "2. Faites glisser les cartes vers la gauche et la droite, vers le haut et le bas", - "3. Apply rich formatting and link content" : "3. Appliquer un formatage riche et lier le contenu", - "4. Share, comment and collaborate!" : "4. Partagez, commentez et collaborez !", - "Create your first card!" : "Créez votre première carte !", - "This comment has more than %s characters.\nAdded as an attachment to the card with name %s.\nAccessible on URL: %s." : "Ce commentaire comporte plus de %s caractères.\nAjouté en pièce jointe à la carte intitulée %s.\nAccessible depuis l'URL: %s.", + "3. Apply rich formatting and link content" : "3. Appliquez une mise en forme enrichie et ajoutez des liens au contenu", + "4. Share, comment and collaborate!" : "4. Partagez, commentez et collaborez !", + "Create your first card!" : "Créez votre première carte !", + "This comment has more than %s characters.\nAdded as an attachment to the card with name %s.\nAccessible on URL: %s." : "Ce commentaire comporte plus de %s caractères.\nAjouté en pièce jointe à la carte intitulée %s.\nAccessible à l’URL : %s.", "Attachments" : "Pièces jointes", "File" : "Fichier", "date" : "date", "Card not found" : "Carte introuvable", "Path is already shared with this card" : "Le chemin est déjà partagé avec cette carte", - "Invalid date, date format must be YYYY-MM-DD" : "Date non valable, le format de la date doit être AAAA-MM-JJ", - "All boards owned by you including stacks, cards, labels, assignments, and comments" : "Tous vos tableaux, incluant les colonnes, les cartes, les étiquettes, les attributions aux utilisateurs et les commentaires", - "Personal planning and team project organization" : "Agenda personnel et organisation projet", - "Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deck est un outil d'organisation de style kanban destiné à la planification personnelle et à l'organisation de projets pour les équipes intégrées à Nextcloud.\n\n\n- 📥 Ajoutez vos tâches à des cartes et organisez-les\n- 📄 Écrivez des notes supplémentaires en Markdown\n- 🔖 Affectez des étiquettes pour une organisation encore meilleure\n- 👥 Partagez avec votre équipe, vos amis ou votre famille\n- 📎 Joignez des fichiers et utilisez-les dans vos descriptions en Markdown\n- 💬 Échangez avec votre équipe grâce aux commentaires\n- ⚡ Gardez un œil sur les modifications dans le flux d'activité\n- 🚀 Organisez vos projets", + "Invalid date, date format must be YYYY-MM-DD" : "Date non valide, le format de la date doit être AAAA-MM-JJ", + "All boards owned by you including stacks, cards, labels, assignments, and comments" : "Tous vos tableaux, y compris les listes, les cartes, les étiquettes, les affectations et les commentaires", + "Personal planning and team project organization" : "Planification personnelle et organisation de projets en équipe", + "Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deck est un outil d’organisation de type kanban intégré à Nextcloud, conçu pour la planification personnelle et l’organisation de projets en équipe.\n\n\n- 📥 Ajoutez vos tâches à des cartes et organisez-les\n- 📄 Ajoutez des notes en Markdown\n- 🔖 Ajoutez des étiquettes pour mieux vous organiser\n- 👥 Partagez avec votre équipe, vos amis ou votre famille\n- 📎 Joignez des fichiers et intégrez-les à votre description en Markdown\n- 💬 Échangez avec votre équipe grâce aux commentaires\n- ⚡ Suivez les modifications dans le flux d’activité\n- 🚀 Organisez votre projet", "Add board" : "Ajouter un tableau", "Card details" : "Détails de la carte", - "Select the board to link to a project" : "Sélection le tableau pour faire le lien avec un projet.", + "Select the board to link to a project" : "Sélectionner le tableau à relier à un projet", "Search by board title" : "Rechercher par titre du tableau", "Select board" : "Sélectionner le tableau", "Move/copy card" : "Déplacer/copier la carte", @@ -145,13 +145,13 @@ OC.L10N.register( "Copy card" : "Copier la carte", "Select the card to link to a project" : "Sélectionner la carte à relier à un projet", "Link to card" : "Relier à une carte", - "Select a card" : "Sélectionnez une carte", + "Select a card" : "Sélectionner une carte", "Cancel" : "Annuler", "This board is read only" : "Ce tableau est en lecture seule", "Drop your files to upload" : "Glissez vos fichiers pour les téléverser", "File already exists" : "Le fichier existe déjà", "A file with the name {filename} already exists." : "Un fichier avec le nom {filename} existe déjà.", - "Do you want to overwrite it?" : "Souhaitez-vous l'écraser ?", + "Do you want to overwrite it?" : "Souhaitez-vous l’écraser ?", "Overwrite file" : "Remplacer le fichier", "Keep existing file" : "Conserver le fichier existant", "Add card" : "Ajouter une carte", @@ -165,25 +165,25 @@ OC.L10N.register( "Filter by assigned user" : "Filtrer par utilisateur", "Unassigned" : "Non attribué", "Filter by status" : "Filtrer par statut", - "Open and completed" : "Ouvert et terminé", - "Open" : "Ouvert", - "Completed" : "Terminé", + "Open and completed" : "Ouvertes et terminées", + "Open" : "Ouvertes", + "Completed" : "Terminées", "Filter by due date" : "Filtrer par échéance", "Overdue" : "En retard", - "Next 24 hours" : "prochaines 24 heures", + "Next 24 hours" : "Prochaines 24 heures", "Next 7 days" : "7 prochains jours", "Next 30 days" : "30 prochains jours", "No due date" : "Sans échéance", - "Clear filter" : "Supprimer le filtre", + "Clear filter" : "Effacer les filtres", "View Modes" : "Modes d'affichage", - "Toggle View Modes" : "Basculer les modes d'affichage", + "Toggle View Modes" : "Changer de mode d’affichage", "Kanban view" : "Vue Kanban", "Gantt view" : "Vue Gantt", "Hide archived cards" : "Masquer les cartes archivées", "Show archived cards" : "Afficher les cartes archivées", - "Toggle compact mode" : "Activer/Désactiver l'affichage compact", - "Hide card cover images" : "Masquer les images de couverture de la carte", - "Show card cover images" : "Afficher les images de couverture de la carte", + "Toggle compact mode" : "Activer/Désactiver le mode compact", + "Hide card cover images" : "Masquer les images de couverture des cartes", + "Show card cover images" : "Afficher les images de couverture des cartes", "Open details" : "Ouvrir les détails", "Details" : "Détails", "Deck settings" : "Paramètres de Deck", @@ -192,25 +192,25 @@ OC.L10N.register( "Add new cards at the top of a list" : "Ajouter de nouvelles cartes en haut d'une liste", "Appearance" : "Apparence", "Show card ID badge" : "Afficher l'ID de la carte", - "Show boards in calendar/tasks" : "Afficher les tableaux dans les agendas/tâches", + "Show boards in calendar/tasks" : "Afficher les tableaux dans Agenda et Tâches", "Admin settings" : "Paramètres d'administration", "Limit board creation to some groups" : "Limiter la création de tableaux à certains groupes", "Users outside of those groups will not be able to create their own boards, but will still be able to work on boards that have been shared with them." : "Les utilisateurs qui ne font pas partie de ces groupes ne pourront pas créer leurs propres tableaux, mais pourront toujours travailler sur les tableaux qui ont été partagés avec eux.", "Enable federation" : "Activer la fédération", "Board actions" : "Actions sur le tableau", - "Scroll sideways" : "Défilement latéral", + "Scroll sideways" : "Faire défiler horizontalement", "Navigate between cards" : "Naviguer entre les cartes", "Close card details" : "Fermer les détails de la carte", - "Search" : "Rechercher", - "Show card filters" : "Montrer les filtres de carte", - "Clear card filters" : "Effacer les filtres de carte", - "Show those shortcuts" : "Montrer ces raccourcis", + "Search" : "Recherche", + "Show card filters" : "Afficher les filtres des cartes", + "Clear card filters" : "Effacer les filtres des cartes", + "Show those shortcuts" : "Afficher ces raccourcis", "Card actions" : "Actions sur les cartes", "Open card details" : "Ouvrir les détails de la carte", "Edit the card title" : "Modifier le titre de la carte", "Assign yourself to the current card" : "M’assigner à la carte active", - "Archive/unarchive the current card" : "(Dés)Archiver la carte active", - "Mark card as completed/not completed" : "Marquer la carte (non) terminée", + "Archive/unarchive the current card" : "Archiver/Désarchiver la carte active", + "Mark card as completed/not completed" : "Marquer la carte comme terminée/non terminée", "Open card menu" : "Ouvrir le menu de la carte", "Currently present people" : "Personnes actuellement présentes", "Supported prefixes: {prefixes}. Wrap phrases in double quotes." : "Préfixes pris en charge : {prefixes}. Placez les expressions entre guillemets doubles.", @@ -230,10 +230,10 @@ OC.L10N.register( "Weeks" : "Semaines", "Months" : "Mois", "No cards yet" : "Aucune carte pour l'instant", - "Set a start date and due date on your cards to see them on the Gantt chart" : "Définissez une date de départ et une date d'échéance sur vos cartes pour les voir dans le diagramme de Gantt", - "Cards without dates ({count})" : "Cartes sans dates ({count})", + "Set a start date and due date on your cards to see them on the Gantt chart" : "Définissez une date de début et une date d’échéance sur vos cartes pour les afficher dans le diagramme de Gantt", + "Cards without dates ({count})" : "Sans date : {count}", "Failed to create share with {displayName}" : "Échec de la création du partage avec {displayName}", - "Are you sure you want to transfer the board {title} to {user}?" : "Êtes-vous sûr de vouloir transférer le tableau {title} à {user} ?", + "Are you sure you want to transfer the board {title} to {user}?" : "Voulez-vous vraiment transférer le tableau {title} à {user} ?", "Transfer the board." : "Transférer le tableau", "Transfer" : "Transférer", "The board has been transferred to {user}" : "Le tableau a été transféré à {user}", @@ -251,8 +251,8 @@ OC.L10N.register( "Edit list title" : "Modifier le titre de la liste", "Archive all cards" : "Archiver toutes les cartes", "Unarchive all cards" : "Désarchiver toutes les cartes", - "Do not set cards as \"done\"" : "Ne pas définir les cartes comme étant « terminées »", - "Set cards as \"done\"" : "Définir les cartes comme étant « terminées »", + "Do not set cards as \"done\"" : "Ne pas marquer les cartes comme « terminées »", + "Set cards as \"done\"" : "Marquer les cartes comme « terminées »", "Delete list" : "Supprimer la liste", "Archive all cards in this list" : "Archiver toutes les cartes de cette liste", "Unarchive all cards in this list" : "Désarchiver toutes les cartes de cette liste", @@ -266,11 +266,11 @@ OC.L10N.register( "Members" : "Membres", "Assign to users/groups/team" : "Attribuer à des utilisateurs / groupes / équipes", "Assign a user to this card…" : "Affecter cette carte à un utilisateur…", - "Select a user to assign to this card…" : "Sélectionner un utilisateur auquel assigner la carte...", + "Select a user to assign to this card…" : "Sélectionner un utilisateur à qui attribuer cette carte…", "File to share" : "Fichier à partager", "Invalid path selected" : "Chemin sélectionné non valide", "Upload new files" : "Téléverser de nouveaux fichiers", - "Share from Files" : "Choisir depuis Fichiers", + "Share from Files" : "Partager depuis Fichiers", "Pending share" : "Partage en attente", "Add this attachment" : "Ajouter cette pièce jointe", "Show in Files" : "Afficher dans Fichiers", @@ -278,43 +278,43 @@ OC.L10N.register( "Remove attachment" : "Supprimer la pièce jointe", "Delete Attachment" : "Supprimer la pièce jointe", "Restore Attachment" : "Restaurer la pièce jointe", - "Modified: {modifiedDate} ⸱ Created: {createdDate}" : "Modifié : {modifiedDate} ⸱ Créé : {createdDate}", - "Modified: {modifiedDate}\nCreated: {createdDate}\nCreated by: {owner}" : "Modifié : {modifiedDate}\nCréé : {createdDate}\nCréé par : {owner}", - "Modified: {modifiedDate}\nCreated: {createdDate}" : "Modifié : {modifiedDate}\nCréé : {createdDate}", + "Modified: {modifiedDate} ⸱ Created: {createdDate}" : "Modifié : {modifiedDate} ⸱ Créé : {createdDate}", + "Modified: {modifiedDate}\nCreated: {createdDate}\nCreated by: {owner}" : "Modifié : {modifiedDate}\nCréé : {createdDate}\nCréé par : {owner}", + "Modified: {modifiedDate}\nCreated: {createdDate}" : "Modifié : {modifiedDate}\nCréé : {createdDate}", "The title cannot be empty." : "Le titre ne peut pas être vide.", - "Cannot close unsaved card!" : "Impossible de fermer une carte non enregistrée !", + "Cannot close unsaved card!" : "Impossible de fermer une carte non enregistrée !", "Open in sidebar view" : "Ouvrir dans le panneau latéral", "Open in bigger view" : "Ouvrir dans la vue large", "Comments" : "Commentaires", "Failed to load comments" : "Échec du chargement des commentaires", - "No comments yet. Begin the discussion!" : "Aucun commentaire pour l'instant. Commencez la discussion !", + "No comments yet. Begin the discussion!" : "Aucun commentaire pour l’instant. Commencez la discussion !", "The comment cannot be empty." : "Un commentaire ne peut pas être vide.", "The comment cannot be longer than 1000 characters." : "Un commentaire est limité à 1 000 caractères.", "Submit" : "Envoyer", - "Created:" : "Créée le :", + "Created:" : "Créé le :", "In reply to" : "En réponse à", "Cancel reply" : "Annuler la réponse", "Reply" : "Répondre", "Update" : "Mettre à jour", - "Assign dependent cards" : "Désigner des cartes dépendantes", - "Mark as done" : "Marquer comme fait", - "Mark as not done" : "Marquer comme non fait", + "Assign dependent cards" : "Associer des cartes dépendantes", + "Mark as done" : "Marquer comme terminée", + "Mark as not done" : "Marquer comme non terminée", "Remove dependency" : "Supprimer la dépendance", "Add dependent card" : "Ajouter une carte dépendante", - "Assign a dependent card…" : "Désigner une carte dépendante...", - "Select a dependent card…" : "Sélectionner une carte dépendante...", + "Assign a dependent card…" : "Associer une carte dépendante…", + "Select a dependent card…" : "Sélectionner une carte dépendante…", "Write a description …" : "Écrire une description…", "The description has been changed by another user." : "La description a été modifiée par un autre utilisateur.", "Could not save description" : "Impossible d'enregistrer la description", "Description" : "Description", - "(Unsaved)" : "(Non enregistré)", - "(Saving…)" : "(Enregistrement...)", + "(Unsaved)" : "(Non enregistrée)", + "(Saving…)" : "(Enregistrement…)", "Formatting help" : "Aide sur la mise en forme", "Edit description" : "Modifier la description", "View description" : "Afficher la description", "Add Attachment" : "Ajouter une pièce jointe", "Choose attachment" : "Choisir une pièce jointe", - "Select Date" : "Sélectionnez une date", + "Select Date" : "Sélectionner une date", "Later today – {timeLocale}" : "Plus tard aujourd'hui – {timeLocale}", "Set due date for later today" : "Définir une date d'échéance pour plus tard dans la journée", "Tomorrow – {timeLocale}" : "Demain – {timeLocale}", @@ -323,73 +323,73 @@ OC.L10N.register( "Set due date for this weekend" : "Définir une date d'échéance pour ce week-end", "Next week – {timeLocale}" : "Semaine prochaine – {timeLocale}", "Set due date for next week" : "Définir une date d'échéance pour la semaine prochaine", - "Assign a due date to this card…" : "Attribuez une date d'échéance à cette carte...", + "Assign a due date to this card…" : "Attribuer une date d’échéance à cette carte…", "Set a due date" : "Définir une date d'échéance", "Add due date" : "Ajouter une date d'échéance", "Choose a date" : "Sélectionner une date", "Remove due date" : "Retirer la date d'échéance", - "Due at:" : "Dû au :", - "Not done" : "Non fait", - "Unarchive card" : "Sortir la carte des archives", + "Due at:" : "Échéance :", + "Not done" : "Non terminée", + "Unarchive card" : "Désarchiver la carte", "Archive card" : "Archiver la carte", - "Assign a start date to this card…" : "Assigner une date de départ à cette carte...", - "Set a start date" : "Définir une date de départ", - "Add start date" : "Ajouter une date de départ", - "Remove start date" : "Supprimer la date de départ", + "Assign a start date to this card…" : "Attribuer une date de début à cette carte…", + "Set a start date" : "Définir une date de début", + "Add start date" : "Ajouter une date de début", + "Remove start date" : "Supprimer la date de début", "Assign a tag to this card…" : "Associer une étiquette à cette carte…", - "Select or create a tag…" : "Sélectionner ou créer une étiquette", - "Create a new tag:" : "Créer une nouvelle étiquette :", + "Select or create a tag…" : "Sélectionner ou créer une étiquette…", + "Create a new tag:" : "Créer une nouvelle étiquette :", "(group)" : "(groupe)", - "{count} comments, {unread} unread" : "{count} commentaires, {unread} non lus", + "{count} comments, {unread} unread" : "Commentaires : {count}, non lus : {unread}", "Todo items" : "À faire", "Edit card title" : "Modifier le titre de la carte", "Open link" : "Ouvrir le lien", "Card deleted" : "Carte supprimée", "Change card color" : "Changer la couleur de la carte", "Edit title" : "Modifier le titre", - "Assign to me" : "Me l'affecter", - "Unassign myself" : "Me désaffecter", + "Assign to me" : "M’attribuer la carte", + "Unassign myself" : "Me retirer de la carte", "Delete card" : "Supprimer la carte", "All boards" : "Tous les tableaux", "Archived boards" : "Tableaux archivés", "Shared with you" : "Partagés avec vous", "Cancel edit" : "Annuler les modifications", - "Save board" : "Sauvegarder le tableau", + "Save board" : "Enregistrer le tableau", "Board {0} deleted" : "Tableau {0} supprimé", "All cards" : "Toutes les cartes", "Only assigned cards" : "Uniquement les cartes assignées", "No reminder" : "Aucun rappel", - "Are you sure you want to delete the board {title}? This will delete all the data of this board including archived cards." : "Êtes-vous sûr de vouloir supprimer le tableau {title} ? Cela supprimera toutes les données de ce tableau, y compris les cartes archivées.", - "Delete the board?" : "Supprimer le tableau ?", - "Are you sure you want to leave the board {title}?" : "Êtes-vous sûr de vouloir quitter le tableau {title} ?", - "Leave the board?" : "Quitter le tableau ?", + "Are you sure you want to delete the board {title}? This will delete all the data of this board including archived cards." : "Voulez-vous vraiment supprimer le tableau {title} ? Cela supprimera toutes les données de ce tableau, y compris les cartes archivées.", + "Delete the board?" : "Supprimer le tableau ?", + "Are you sure you want to leave the board {title}?" : "Voulez-vous vraiment quitter le tableau {title} ?", + "Leave the board?" : "Quitter le tableau ?", "Leave" : "Quitter", "Failed to leave the board" : "Impossible de quitter le tableau", - "Exporting board..." : "Exportation de la carte...", + "Exporting board..." : "Exportation du tableau…", "An error occurred" : "Une erreur est survenue", "Board details" : "Détails du tableau", - "Edit board" : "Renommer le tableau", + "Edit board" : "Modifier le tableau", "Clone board" : "Dupliquer le tableau", "Unarchive board" : "Désarchiver le tableau", "Archive board" : "Archiver le tableau", "Export board" : "Exporter le tableau", - "Turn on due date reminders" : "Activer les rappels", - "Turn off due date reminders" : "Désactiver les rappels", - "Remove as default board" : "Retirer comme tableau par défaut", + "Turn on due date reminders" : "Activer les rappels d’échéance", + "Turn off due date reminders" : "Désactiver les rappels d’échéance", + "Remove as default board" : "Ne plus utiliser comme tableau par défaut", "Set as default board" : "Définir comme tableau par défaut", - "Due date reminders" : "Rappels", + "Due date reminders" : "Rappels d’échéance", "Assigned cards" : "Cartes assignées", "No notifications" : "Aucune notification", "Delete board" : "Supprimer le tableau", "Leave board" : "Quitter le tableau", - "Importing board..." : "Importation du tableau...", - "Board imported successfully" : "Carte importée avec succès", + "Importing board..." : "Importation du tableau…", + "Board imported successfully" : "Tableau importé avec succès", "Import board" : "Importer un tableau", - "Clone {boardTitle}" : "Cloner {boardTitle}", + "Clone {boardTitle}" : "Dupliquer {boardTitle}", "Clone cards" : "Dupliquer les cartes", - "Clone assignments" : "Cloner les affectations", - "Clone labels" : "Cloner les étiquettes", - "Clone due dates" : "Cloner les dates d'échéance", + "Clone assignments" : "Dupliquer les affectations", + "Clone labels" : "Dupliquer les étiquettes", + "Clone due dates" : "Dupliquer les dates d’échéance", "Advanced options" : "Options avancées", "Move all cards to the first list" : "Déplacer toutes les cartes vers la première liste", "Restore archived cards" : "Restaurer les cartes archivées", @@ -397,27 +397,27 @@ OC.L10N.register( "Export {boardTitle}" : "Exporter {boardTitle}", "Export as JSON" : "Exporter au format JSON", "Export as CSV" : "Exporter en CSV", - "Note: Only the JSON format is supported for importing back into the Deck app." : "Remarque : seul le format JSON est pris en charge pour la réimportation dans l'application Deck.", + "Note: Only the JSON format is supported for importing back into the Deck app." : "Remarque : seul le format JSON est pris en charge pour la réimportation dans Deck.", "Export" : "Exporter", "Loading filtered view" : "Chargement de la vue filtrée", "Search for {searchQuery} in other boards" : "Rechercher {searchQuery} dans les autres tableaux", - "Search for {searchQuery} in all boards" : "Recherche de {searchQuery} dans tous les tableaux", + "Search for {searchQuery} in all boards" : "Rechercher {searchQuery} dans tous les tableaux", "No results found" : "Aucun résultat", "Deck board {name}\n* Last modified on {lastMod}" : "Tableau Deck {name}\n* Dernière modification le {lastMod}", - "* Created on {created}\n* Last modified on {lastMod}\n* {nbAttachments} attachments\n* {nbComments} comments" : "* Créée le {created}\n* Dernière modification le {lastMod}\n* {nbAttachments} pièces jointes\n* {nbComments} commentaires", - "{nbCards} cards" : "{nbCards} cartes", + "* Created on {created}\n* Last modified on {lastMod}\n* {nbAttachments} attachments\n* {nbComments} comments" : "* Création : {created}\n* Dernière modification : {lastMod}\n* Pièces jointes : {nbAttachments}\n* Commentaires : {nbComments}", + "{nbCards} cards" : "Cartes : {nbCards}", "Due on {date}" : "Échéance le {date}", "{stack} in {board}" : "{stack} dans {board}", - "Click to expand description" : "Cliquer pour visualiser la description", - "Click to expand comment" : "Cliquer pour déplier le commentaire", + "Click to expand description" : "Cliquez pour développer la description", + "Click to expand comment" : "Cliquez pour développer le commentaire", "Create card" : "Créer la carte", "Create a new card" : "Créer une nouvelle carte", "Card title" : "Titre de la carte", "Creating the new card …" : "Création de la nouvelle carte…", - "Card \"{card}\" was added to \"{board}\"" : "La carte \"{card}\" a été ajoutée au tableau \"{board}\"", + "Card \"{card}\" was added to \"{board}\"" : "La carte « {card} » a été ajoutée au tableau « {board} »", "Open card" : "Ouvrir la carte", "Close" : "Fermer", - "No upcoming cards" : "Pas de cartes à venir", + "No upcoming cards" : "Aucune carte à venir", "upcoming cards today" : "cartes à venir aujourd'hui", "upcoming cards tomorrow" : "cartes à venir demain", "upcoming cards" : "cartes à venir", @@ -426,8 +426,8 @@ OC.L10N.register( "Link to a card" : "Relier à une carte", "Create a card" : "Créer une carte", "Message from {author} in {conversationName}" : "Message de {author} dans {conversationName}", - "Something went wrong" : "Quelque chose s'est mal passé", - "Failed to upload {name}" : "Échec d'envoi de {name}", + "Something went wrong" : "Une erreur est survenue", + "Failed to upload {name}" : "Échec du téléversement de {name}", "Maximum file size of {size} exceeded" : "Taille de fichier maximale de {size} dépassée", "Assigned users" : "Utilisateurs assignés", "Due date" : "Date d'échéance", @@ -435,11 +435,11 @@ OC.L10N.register( "Modified" : "Modifiée", "Error creating the share" : "Erreur lors de la création du partage", "Share with a Deck card" : "Partager avec une carte Deck", - "Share {file} with a Deck card" : "Partager {file} avec une carte Deck ", + "Share {file} with a Deck card" : "Partager {file} avec une carte Deck", "Share" : "Partager", - "The card \"%s\" on \"%s\" has reached its due date." : "La date d'échéance de la carte \"%s\" de \"%s\" a été atteinte.", - "Share board with a user, group or team …" : "Partager le tableau avec un utilisateur, un groupe ou une équipe...", - "Searching for users, groups and teams …" : "Recherche d'utilisateurs, de groupes et d'équipes...", + "The card \"%s\" on \"%s\" has reached its due date." : "La carte « %s » du tableau « %s » est arrivée à échéance.", + "Share board with a user, group or team …" : "Partager le tableau avec un utilisateur, un groupe ou une équipe…", + "Searching for users, groups and teams …" : "Recherche d’utilisateurs, de groupes et d’équipes…", "No participants found" : "Aucun participant trouvé", "Save" : "Enregistrer", "seconds ago" : "à l'instant", diff --git a/l10n/fr.json b/l10n/fr.json index 5d4ddf921f..04beae41e0 100644 --- a/l10n/fr.json +++ b/l10n/fr.json @@ -6,7 +6,7 @@ "You have restored the board {board}" : "Vous avez restauré le tableau {board}", "{user} has restored the board {board}" : "{user} a restauré le tableau {board}", "You have shared the board {board} with {acl}" : "Vous avez partagé le tableau {board} avec {acl}", - "{user} has shared the board {board} with {acl}" : "{user} a partagé le tableau {board} en {acl}", + "{user} has shared the board {board} with {acl}" : "{user} a partagé le tableau {board} avec {acl}", "You have removed {acl} from the board {board}" : "Vous avez supprimé {acl} du tableau {board}", "{user} has removed {acl} from the board {board}" : "{user} a supprimé {acl} du tableau {board}", "You have renamed the board {before} to {board}" : "Vous avez renommé le tableau {before} en {board}", @@ -35,16 +35,16 @@ "{user} has archived card {card} in list {stack} on board {board}" : "{user} a archivé la carte {card} de la liste {stack} du tableau {board}", "You have unarchived card {card} in list {stack} on board {board}" : "Vous avez désarchivé la carte {card} de la liste {stack} du tableau {board}", "{user} has unarchived card {card} in list {stack} on board {board}" : "{user} a désarchivé la carte {card} de la liste {stack} du tableau {board}", - "You have marked the card {card} as done in list {stack} on board {board}" : "Vous avez marqué la carte {card} comme faite dans la liste {stack} sur le tableau {board}", - "{user} has marked card {card} as done in list {stack} on board {board}" : "{user} a marqué la carte {card} comme faite dans la liste {stack} sur le tableau {board}", - "You have marked the card {card} as undone in list {stack} on board {board}" : "Vous avez marqué la carte {card} comme non faite dans la liste {stack} sur le tableau {board}", - "{user} has marked the card {card} as undone in list {stack} on board {board}" : "{user} a marqué la carte {card} comme non faite dans la liste {stack} sur le tableau {board}", + "You have marked the card {card} as done in list {stack} on board {board}" : "Vous avez marqué la carte {card} comme terminée dans la liste {stack} sur le tableau {board}", + "{user} has marked card {card} as done in list {stack} on board {board}" : "{user} a marqué la carte {card} comme terminée dans la liste {stack} sur le tableau {board}", + "You have marked the card {card} as undone in list {stack} on board {board}" : "Vous avez marqué la carte {card} comme non terminée dans la liste {stack} sur le tableau {board}", + "{user} has marked the card {card} as undone in list {stack} on board {board}" : "{user} a marqué la carte {card} comme non terminée dans la liste {stack} sur le tableau {board}", "You have removed the due date of card {card}" : "Vous avez supprimé la date d'échéance de la carte {card}", "{user} has removed the due date of card {card}" : "{user} a supprimé la date d'échéance de la carte {card}", - "You have set the due date of card {card} to {after}" : "Vous avez établi la date d'échéance de la carte {card} au {after}", - "{user} has set the due date of card {card} to {after}" : "{user} a établi la date d'échéance de la carte {card} à {after}", - "You have updated the due date of card {card} to {after}" : "Vous avez mis à jour la date d'échéance de la carte {card} au {after}", - "{user} has updated the due date of card {card} to {after}" : "{user} a mis à jour la date d'échéance de la carte {card} à {after}", + "You have set the due date of card {card} to {after}" : "Vous avez fixé la date d’échéance de la carte {card} au {after}", + "{user} has set the due date of card {card} to {after}" : "{user} a fixé la date d’échéance de la carte {card} au {after}", + "You have updated the due date of card {card} to {after}" : "Vous avez modifié la date d’échéance de la carte {card} au {after}", + "{user} has updated the due date of card {card} to {after}" : "{user} a modifié la date d’échéance de la carte {card} au {after}", "You have added the tag {label} to card {card} in list {stack} on board {board}" : "Vous avez ajouté l'étiquette {label} à la carte {card} de la liste {stack} du tableau {board}", "{user} has added the tag {label} to card {card} in list {stack} on board {board}" : "{user} a ajouté l'étiquette {label} à la carte {card} de la liste {stack} du tableau {board}", "You have removed the tag {label} from card {card} in list {stack} on board {board}" : "Vous avez supprimé l'étiquette {label} de la carte {card} de la liste {stack} du tableau {board}", @@ -66,40 +66,40 @@ "You have commented on card {card}" : "Vous avez commenté la carte {card}", "{user} has commented on card {card}" : "{user} a commenté la carte {card}", "Deck" : "Deck", - "Changes in the Deck app" : "Modifications dans Deck app", - "A board, list or card was changed" : "Un(e) tableau, liste ou carte a été modifié(e)", - "A comment was created on a card" : "Un commentaire a été créé sur une carte", + "Changes in the Deck app" : "Modifications dans Deck", + "A board, list or card was changed" : "Un tableau, une liste ou une carte a fait l’objet d’une modification", + "A comment was created on a card" : "Un commentaire a été ajouté à une carte", "A card description has been changed" : "La description de la carte a été modifiée", "The file was uploaded" : "Le fichier a été envoyé", - "The uploaded file exceeds the upload_max_filesize directive in php.ini" : "Le fichier envoyé dépasse la valeur upload_max_filesize spécifiée dans php.ini", - "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Le fichier envoyé dépasse la valeur MAX_FILE_SIZE spécifiée dans le formulaire HTML", - "The file was only partially uploaded" : "Le fichier n'a été que partiellement envoyé", - "No file was uploaded" : "Aucun fichier n'a été envoyé", + "The uploaded file exceeds the upload_max_filesize directive in php.ini" : "Le fichier envoyé dépasse la directive upload_max_filesize définie dans php.ini", + "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Le fichier envoyé dépasse la directive MAX_FILE_SIZE définie dans le formulaire HTML", + "The file was only partially uploaded" : "Le fichier n’a été que partiellement envoyé", + "No file was uploaded" : "Aucun fichier n’a été envoyé", "Missing a temporary folder" : "Absence de dossier temporaire", "Could not write file to disk" : "Impossible d'écrire le fichier sur le disque", - "A PHP extension stopped the file upload" : "Une extension PHP a arrêté l'envoi du fichier", - "No file uploaded or file size exceeds maximum of %s" : "Aucun fichier envoyé ou la taille du fichier dépasse le maximum de %s", + "A PHP extension stopped the file upload" : "Une extension PHP a interrompu l’envoi du fichier", + "No file uploaded or file size exceeds maximum of %s" : "Aucun fichier n’a été envoyé ou sa taille dépasse la limite maximale de %s", "Invalid file type. Only JSON files are allowed." : "Type de fichier non valide. Seuls les fichiers JSON sont autorisés.", "Invalid JSON data" : "Données JSON non valides", "Failed to import board" : "Échec de l'importation du tableau", - "Cards due today" : "Cartes pour aujourd'hui", - "Cards due tomorrow" : "Cartes pour demain", - "Upcoming cards" : "Prochaines cartes", + "Cards due today" : "Cartes à échéance aujourd’hui", + "Cards due tomorrow" : "Cartes à échéance demain", + "Upcoming cards" : "Cartes à venir", "Load more" : "Charger davantage", - "Welcome to Nextcloud Deck!" : "Bienvenue dans Nextcloud Deck !", - "The card \"%s\" on \"%s\" has been assigned to you by %s." : "La carte \"%s\" de \"%s\" vous a été assignée par %s.", + "Welcome to Nextcloud Deck!" : "Bienvenue dans Nextcloud Deck !", + "The card \"%s\" on \"%s\" has been assigned to you by %s." : "La carte « %s » du tableau « %s » vous a été attribuée par %s.", "{user} has assigned the card {deck-card} on {deck-board} to you." : "{user} vous a attribué la carte {deck-card} du tableau {deck-board}.", - "The card \"%1$s\" on \"%2$s\" has reached its due date." : "La carte \"%1$s\" sur \"%2$s\" est arrivée à échéance.", - "The card {deck-card} on {deck-board} has reached its due date." : "La carte {deck-card} sur {deck-board} a atteint sa date d'échéance.", - "%s has mentioned you in a comment on \"%s\"." : "%s vous a mentionné dans un commentaire sur \"%s\".", - "{user} has mentioned you in a comment on {deck-card}." : "{user} vous a cité dans un commentaire sur {deck-card}.", - "The board \"%s\" has been shared with you by %s." : "Le tableau \"%s\" a été partagé avec vous par %s.", - "{user} has shared {deck-board} with you." : "{user} vous a partagé le tableau {deck-board}.", + "The card \"%1$s\" on \"%2$s\" has reached its due date." : "La carte « %1$s » du tableau « %2$s » est arrivée à échéance.", + "The card {deck-card} on {deck-board} has reached its due date." : "La carte {deck-card} du tableau {deck-board} est arrivée à échéance.", + "%s has mentioned you in a comment on \"%s\"." : "%s vous a mentionné dans un commentaire sur « %s ».", + "{user} has mentioned you in a comment on {deck-card}." : "{user} vous a mentionné dans un commentaire sur {deck-card}.", + "The board \"%s\" has been shared with you by %s." : "Le tableau « %s » a été partagé avec vous par %s.", + "{user} has shared {deck-board} with you." : "{user} a partagé le tableau {deck-board} avec vous.", "The remote board %1$s has been shared with you by %2$s" : "Le tableau distant %1$s a été partagé avec vous par %2$s", "Deck board" : "Tableau Deck", - "Owned by %1$s" : "Assignée à %1$s", + "Owned by %1$s" : "Propriété de %1$s", "Deck boards, cards and comments" : "Tableaux, cartes et commentaires de Deck", - "From %1$s, in %2$s/%3$s, owned by %4$s" : "De %1$s, dans %2$s / %3$s, appartenant à %4$s", + "From %1$s, in %2$s/%3$s, owned by %4$s" : "Par %1$s, dans %2$s/%3$s, tableau de %4$s", "Create a new deck card" : "Créer une nouvelle carte Deck", "Card comments" : "Commentaires des cartes", "%s on %s" : "%s sur %s", @@ -110,29 +110,29 @@ "Action needed" : "Action requise", "Later" : "Plus tard", "copy" : "copie", - "Read more inside" : "Lire la suite à l'intérieur", - "Custom lists - click to rename!" : "Listes personnalisées - cliquez pour renommer !", + "Read more inside" : "En savoir plus dans la carte", + "Custom lists - click to rename!" : "Listes personnalisées — cliquez pour renommer !", "To Do" : "À faire", "In Progress" : "En cours", - "Done" : "Fait", + "Done" : "Terminé", "1. Open to learn more about boards and cards" : "1. Ouvrez pour en apprendre davantage sur les tableaux et les cartes", "2. Drag cards left and right, up and down" : "2. Faites glisser les cartes vers la gauche et la droite, vers le haut et le bas", - "3. Apply rich formatting and link content" : "3. Appliquer un formatage riche et lier le contenu", - "4. Share, comment and collaborate!" : "4. Partagez, commentez et collaborez !", - "Create your first card!" : "Créez votre première carte !", - "This comment has more than %s characters.\nAdded as an attachment to the card with name %s.\nAccessible on URL: %s." : "Ce commentaire comporte plus de %s caractères.\nAjouté en pièce jointe à la carte intitulée %s.\nAccessible depuis l'URL: %s.", + "3. Apply rich formatting and link content" : "3. Appliquez une mise en forme enrichie et ajoutez des liens au contenu", + "4. Share, comment and collaborate!" : "4. Partagez, commentez et collaborez !", + "Create your first card!" : "Créez votre première carte !", + "This comment has more than %s characters.\nAdded as an attachment to the card with name %s.\nAccessible on URL: %s." : "Ce commentaire comporte plus de %s caractères.\nAjouté en pièce jointe à la carte intitulée %s.\nAccessible à l’URL : %s.", "Attachments" : "Pièces jointes", "File" : "Fichier", "date" : "date", "Card not found" : "Carte introuvable", "Path is already shared with this card" : "Le chemin est déjà partagé avec cette carte", - "Invalid date, date format must be YYYY-MM-DD" : "Date non valable, le format de la date doit être AAAA-MM-JJ", - "All boards owned by you including stacks, cards, labels, assignments, and comments" : "Tous vos tableaux, incluant les colonnes, les cartes, les étiquettes, les attributions aux utilisateurs et les commentaires", - "Personal planning and team project organization" : "Agenda personnel et organisation projet", - "Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deck est un outil d'organisation de style kanban destiné à la planification personnelle et à l'organisation de projets pour les équipes intégrées à Nextcloud.\n\n\n- 📥 Ajoutez vos tâches à des cartes et organisez-les\n- 📄 Écrivez des notes supplémentaires en Markdown\n- 🔖 Affectez des étiquettes pour une organisation encore meilleure\n- 👥 Partagez avec votre équipe, vos amis ou votre famille\n- 📎 Joignez des fichiers et utilisez-les dans vos descriptions en Markdown\n- 💬 Échangez avec votre équipe grâce aux commentaires\n- ⚡ Gardez un œil sur les modifications dans le flux d'activité\n- 🚀 Organisez vos projets", + "Invalid date, date format must be YYYY-MM-DD" : "Date non valide, le format de la date doit être AAAA-MM-JJ", + "All boards owned by you including stacks, cards, labels, assignments, and comments" : "Tous vos tableaux, y compris les listes, les cartes, les étiquettes, les affectations et les commentaires", + "Personal planning and team project organization" : "Planification personnelle et organisation de projets en équipe", + "Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deck est un outil d’organisation de type kanban intégré à Nextcloud, conçu pour la planification personnelle et l’organisation de projets en équipe.\n\n\n- 📥 Ajoutez vos tâches à des cartes et organisez-les\n- 📄 Ajoutez des notes en Markdown\n- 🔖 Ajoutez des étiquettes pour mieux vous organiser\n- 👥 Partagez avec votre équipe, vos amis ou votre famille\n- 📎 Joignez des fichiers et intégrez-les à votre description en Markdown\n- 💬 Échangez avec votre équipe grâce aux commentaires\n- ⚡ Suivez les modifications dans le flux d’activité\n- 🚀 Organisez votre projet", "Add board" : "Ajouter un tableau", "Card details" : "Détails de la carte", - "Select the board to link to a project" : "Sélection le tableau pour faire le lien avec un projet.", + "Select the board to link to a project" : "Sélectionner le tableau à relier à un projet", "Search by board title" : "Rechercher par titre du tableau", "Select board" : "Sélectionner le tableau", "Move/copy card" : "Déplacer/copier la carte", @@ -143,13 +143,13 @@ "Copy card" : "Copier la carte", "Select the card to link to a project" : "Sélectionner la carte à relier à un projet", "Link to card" : "Relier à une carte", - "Select a card" : "Sélectionnez une carte", + "Select a card" : "Sélectionner une carte", "Cancel" : "Annuler", "This board is read only" : "Ce tableau est en lecture seule", "Drop your files to upload" : "Glissez vos fichiers pour les téléverser", "File already exists" : "Le fichier existe déjà", "A file with the name {filename} already exists." : "Un fichier avec le nom {filename} existe déjà.", - "Do you want to overwrite it?" : "Souhaitez-vous l'écraser ?", + "Do you want to overwrite it?" : "Souhaitez-vous l’écraser ?", "Overwrite file" : "Remplacer le fichier", "Keep existing file" : "Conserver le fichier existant", "Add card" : "Ajouter une carte", @@ -163,25 +163,25 @@ "Filter by assigned user" : "Filtrer par utilisateur", "Unassigned" : "Non attribué", "Filter by status" : "Filtrer par statut", - "Open and completed" : "Ouvert et terminé", - "Open" : "Ouvert", - "Completed" : "Terminé", + "Open and completed" : "Ouvertes et terminées", + "Open" : "Ouvertes", + "Completed" : "Terminées", "Filter by due date" : "Filtrer par échéance", "Overdue" : "En retard", - "Next 24 hours" : "prochaines 24 heures", + "Next 24 hours" : "Prochaines 24 heures", "Next 7 days" : "7 prochains jours", "Next 30 days" : "30 prochains jours", "No due date" : "Sans échéance", - "Clear filter" : "Supprimer le filtre", + "Clear filter" : "Effacer les filtres", "View Modes" : "Modes d'affichage", - "Toggle View Modes" : "Basculer les modes d'affichage", + "Toggle View Modes" : "Changer de mode d’affichage", "Kanban view" : "Vue Kanban", "Gantt view" : "Vue Gantt", "Hide archived cards" : "Masquer les cartes archivées", "Show archived cards" : "Afficher les cartes archivées", - "Toggle compact mode" : "Activer/Désactiver l'affichage compact", - "Hide card cover images" : "Masquer les images de couverture de la carte", - "Show card cover images" : "Afficher les images de couverture de la carte", + "Toggle compact mode" : "Activer/Désactiver le mode compact", + "Hide card cover images" : "Masquer les images de couverture des cartes", + "Show card cover images" : "Afficher les images de couverture des cartes", "Open details" : "Ouvrir les détails", "Details" : "Détails", "Deck settings" : "Paramètres de Deck", @@ -190,25 +190,25 @@ "Add new cards at the top of a list" : "Ajouter de nouvelles cartes en haut d'une liste", "Appearance" : "Apparence", "Show card ID badge" : "Afficher l'ID de la carte", - "Show boards in calendar/tasks" : "Afficher les tableaux dans les agendas/tâches", + "Show boards in calendar/tasks" : "Afficher les tableaux dans Agenda et Tâches", "Admin settings" : "Paramètres d'administration", "Limit board creation to some groups" : "Limiter la création de tableaux à certains groupes", "Users outside of those groups will not be able to create their own boards, but will still be able to work on boards that have been shared with them." : "Les utilisateurs qui ne font pas partie de ces groupes ne pourront pas créer leurs propres tableaux, mais pourront toujours travailler sur les tableaux qui ont été partagés avec eux.", "Enable federation" : "Activer la fédération", "Board actions" : "Actions sur le tableau", - "Scroll sideways" : "Défilement latéral", + "Scroll sideways" : "Faire défiler horizontalement", "Navigate between cards" : "Naviguer entre les cartes", "Close card details" : "Fermer les détails de la carte", - "Search" : "Rechercher", - "Show card filters" : "Montrer les filtres de carte", - "Clear card filters" : "Effacer les filtres de carte", - "Show those shortcuts" : "Montrer ces raccourcis", + "Search" : "Recherche", + "Show card filters" : "Afficher les filtres des cartes", + "Clear card filters" : "Effacer les filtres des cartes", + "Show those shortcuts" : "Afficher ces raccourcis", "Card actions" : "Actions sur les cartes", "Open card details" : "Ouvrir les détails de la carte", "Edit the card title" : "Modifier le titre de la carte", "Assign yourself to the current card" : "M’assigner à la carte active", - "Archive/unarchive the current card" : "(Dés)Archiver la carte active", - "Mark card as completed/not completed" : "Marquer la carte (non) terminée", + "Archive/unarchive the current card" : "Archiver/Désarchiver la carte active", + "Mark card as completed/not completed" : "Marquer la carte comme terminée/non terminée", "Open card menu" : "Ouvrir le menu de la carte", "Currently present people" : "Personnes actuellement présentes", "Supported prefixes: {prefixes}. Wrap phrases in double quotes." : "Préfixes pris en charge : {prefixes}. Placez les expressions entre guillemets doubles.", @@ -228,10 +228,10 @@ "Weeks" : "Semaines", "Months" : "Mois", "No cards yet" : "Aucune carte pour l'instant", - "Set a start date and due date on your cards to see them on the Gantt chart" : "Définissez une date de départ et une date d'échéance sur vos cartes pour les voir dans le diagramme de Gantt", - "Cards without dates ({count})" : "Cartes sans dates ({count})", + "Set a start date and due date on your cards to see them on the Gantt chart" : "Définissez une date de début et une date d’échéance sur vos cartes pour les afficher dans le diagramme de Gantt", + "Cards without dates ({count})" : "Sans date : {count}", "Failed to create share with {displayName}" : "Échec de la création du partage avec {displayName}", - "Are you sure you want to transfer the board {title} to {user}?" : "Êtes-vous sûr de vouloir transférer le tableau {title} à {user} ?", + "Are you sure you want to transfer the board {title} to {user}?" : "Voulez-vous vraiment transférer le tableau {title} à {user} ?", "Transfer the board." : "Transférer le tableau", "Transfer" : "Transférer", "The board has been transferred to {user}" : "Le tableau a été transféré à {user}", @@ -249,8 +249,8 @@ "Edit list title" : "Modifier le titre de la liste", "Archive all cards" : "Archiver toutes les cartes", "Unarchive all cards" : "Désarchiver toutes les cartes", - "Do not set cards as \"done\"" : "Ne pas définir les cartes comme étant « terminées »", - "Set cards as \"done\"" : "Définir les cartes comme étant « terminées »", + "Do not set cards as \"done\"" : "Ne pas marquer les cartes comme « terminées »", + "Set cards as \"done\"" : "Marquer les cartes comme « terminées »", "Delete list" : "Supprimer la liste", "Archive all cards in this list" : "Archiver toutes les cartes de cette liste", "Unarchive all cards in this list" : "Désarchiver toutes les cartes de cette liste", @@ -264,11 +264,11 @@ "Members" : "Membres", "Assign to users/groups/team" : "Attribuer à des utilisateurs / groupes / équipes", "Assign a user to this card…" : "Affecter cette carte à un utilisateur…", - "Select a user to assign to this card…" : "Sélectionner un utilisateur auquel assigner la carte...", + "Select a user to assign to this card…" : "Sélectionner un utilisateur à qui attribuer cette carte…", "File to share" : "Fichier à partager", "Invalid path selected" : "Chemin sélectionné non valide", "Upload new files" : "Téléverser de nouveaux fichiers", - "Share from Files" : "Choisir depuis Fichiers", + "Share from Files" : "Partager depuis Fichiers", "Pending share" : "Partage en attente", "Add this attachment" : "Ajouter cette pièce jointe", "Show in Files" : "Afficher dans Fichiers", @@ -276,43 +276,43 @@ "Remove attachment" : "Supprimer la pièce jointe", "Delete Attachment" : "Supprimer la pièce jointe", "Restore Attachment" : "Restaurer la pièce jointe", - "Modified: {modifiedDate} ⸱ Created: {createdDate}" : "Modifié : {modifiedDate} ⸱ Créé : {createdDate}", - "Modified: {modifiedDate}\nCreated: {createdDate}\nCreated by: {owner}" : "Modifié : {modifiedDate}\nCréé : {createdDate}\nCréé par : {owner}", - "Modified: {modifiedDate}\nCreated: {createdDate}" : "Modifié : {modifiedDate}\nCréé : {createdDate}", + "Modified: {modifiedDate} ⸱ Created: {createdDate}" : "Modifié : {modifiedDate} ⸱ Créé : {createdDate}", + "Modified: {modifiedDate}\nCreated: {createdDate}\nCreated by: {owner}" : "Modifié : {modifiedDate}\nCréé : {createdDate}\nCréé par : {owner}", + "Modified: {modifiedDate}\nCreated: {createdDate}" : "Modifié : {modifiedDate}\nCréé : {createdDate}", "The title cannot be empty." : "Le titre ne peut pas être vide.", - "Cannot close unsaved card!" : "Impossible de fermer une carte non enregistrée !", + "Cannot close unsaved card!" : "Impossible de fermer une carte non enregistrée !", "Open in sidebar view" : "Ouvrir dans le panneau latéral", "Open in bigger view" : "Ouvrir dans la vue large", "Comments" : "Commentaires", "Failed to load comments" : "Échec du chargement des commentaires", - "No comments yet. Begin the discussion!" : "Aucun commentaire pour l'instant. Commencez la discussion !", + "No comments yet. Begin the discussion!" : "Aucun commentaire pour l’instant. Commencez la discussion !", "The comment cannot be empty." : "Un commentaire ne peut pas être vide.", "The comment cannot be longer than 1000 characters." : "Un commentaire est limité à 1 000 caractères.", "Submit" : "Envoyer", - "Created:" : "Créée le :", + "Created:" : "Créé le :", "In reply to" : "En réponse à", "Cancel reply" : "Annuler la réponse", "Reply" : "Répondre", "Update" : "Mettre à jour", - "Assign dependent cards" : "Désigner des cartes dépendantes", - "Mark as done" : "Marquer comme fait", - "Mark as not done" : "Marquer comme non fait", + "Assign dependent cards" : "Associer des cartes dépendantes", + "Mark as done" : "Marquer comme terminée", + "Mark as not done" : "Marquer comme non terminée", "Remove dependency" : "Supprimer la dépendance", "Add dependent card" : "Ajouter une carte dépendante", - "Assign a dependent card…" : "Désigner une carte dépendante...", - "Select a dependent card…" : "Sélectionner une carte dépendante...", + "Assign a dependent card…" : "Associer une carte dépendante…", + "Select a dependent card…" : "Sélectionner une carte dépendante…", "Write a description …" : "Écrire une description…", "The description has been changed by another user." : "La description a été modifiée par un autre utilisateur.", "Could not save description" : "Impossible d'enregistrer la description", "Description" : "Description", - "(Unsaved)" : "(Non enregistré)", - "(Saving…)" : "(Enregistrement...)", + "(Unsaved)" : "(Non enregistrée)", + "(Saving…)" : "(Enregistrement…)", "Formatting help" : "Aide sur la mise en forme", "Edit description" : "Modifier la description", "View description" : "Afficher la description", "Add Attachment" : "Ajouter une pièce jointe", "Choose attachment" : "Choisir une pièce jointe", - "Select Date" : "Sélectionnez une date", + "Select Date" : "Sélectionner une date", "Later today – {timeLocale}" : "Plus tard aujourd'hui – {timeLocale}", "Set due date for later today" : "Définir une date d'échéance pour plus tard dans la journée", "Tomorrow – {timeLocale}" : "Demain – {timeLocale}", @@ -321,73 +321,73 @@ "Set due date for this weekend" : "Définir une date d'échéance pour ce week-end", "Next week – {timeLocale}" : "Semaine prochaine – {timeLocale}", "Set due date for next week" : "Définir une date d'échéance pour la semaine prochaine", - "Assign a due date to this card…" : "Attribuez une date d'échéance à cette carte...", + "Assign a due date to this card…" : "Attribuer une date d’échéance à cette carte…", "Set a due date" : "Définir une date d'échéance", "Add due date" : "Ajouter une date d'échéance", "Choose a date" : "Sélectionner une date", "Remove due date" : "Retirer la date d'échéance", - "Due at:" : "Dû au :", - "Not done" : "Non fait", - "Unarchive card" : "Sortir la carte des archives", + "Due at:" : "Échéance :", + "Not done" : "Non terminée", + "Unarchive card" : "Désarchiver la carte", "Archive card" : "Archiver la carte", - "Assign a start date to this card…" : "Assigner une date de départ à cette carte...", - "Set a start date" : "Définir une date de départ", - "Add start date" : "Ajouter une date de départ", - "Remove start date" : "Supprimer la date de départ", + "Assign a start date to this card…" : "Attribuer une date de début à cette carte…", + "Set a start date" : "Définir une date de début", + "Add start date" : "Ajouter une date de début", + "Remove start date" : "Supprimer la date de début", "Assign a tag to this card…" : "Associer une étiquette à cette carte…", - "Select or create a tag…" : "Sélectionner ou créer une étiquette", - "Create a new tag:" : "Créer une nouvelle étiquette :", + "Select or create a tag…" : "Sélectionner ou créer une étiquette…", + "Create a new tag:" : "Créer une nouvelle étiquette :", "(group)" : "(groupe)", - "{count} comments, {unread} unread" : "{count} commentaires, {unread} non lus", + "{count} comments, {unread} unread" : "Commentaires : {count}, non lus : {unread}", "Todo items" : "À faire", "Edit card title" : "Modifier le titre de la carte", "Open link" : "Ouvrir le lien", "Card deleted" : "Carte supprimée", "Change card color" : "Changer la couleur de la carte", "Edit title" : "Modifier le titre", - "Assign to me" : "Me l'affecter", - "Unassign myself" : "Me désaffecter", + "Assign to me" : "M’attribuer la carte", + "Unassign myself" : "Me retirer de la carte", "Delete card" : "Supprimer la carte", "All boards" : "Tous les tableaux", "Archived boards" : "Tableaux archivés", "Shared with you" : "Partagés avec vous", "Cancel edit" : "Annuler les modifications", - "Save board" : "Sauvegarder le tableau", + "Save board" : "Enregistrer le tableau", "Board {0} deleted" : "Tableau {0} supprimé", "All cards" : "Toutes les cartes", "Only assigned cards" : "Uniquement les cartes assignées", "No reminder" : "Aucun rappel", - "Are you sure you want to delete the board {title}? This will delete all the data of this board including archived cards." : "Êtes-vous sûr de vouloir supprimer le tableau {title} ? Cela supprimera toutes les données de ce tableau, y compris les cartes archivées.", - "Delete the board?" : "Supprimer le tableau ?", - "Are you sure you want to leave the board {title}?" : "Êtes-vous sûr de vouloir quitter le tableau {title} ?", - "Leave the board?" : "Quitter le tableau ?", + "Are you sure you want to delete the board {title}? This will delete all the data of this board including archived cards." : "Voulez-vous vraiment supprimer le tableau {title} ? Cela supprimera toutes les données de ce tableau, y compris les cartes archivées.", + "Delete the board?" : "Supprimer le tableau ?", + "Are you sure you want to leave the board {title}?" : "Voulez-vous vraiment quitter le tableau {title} ?", + "Leave the board?" : "Quitter le tableau ?", "Leave" : "Quitter", "Failed to leave the board" : "Impossible de quitter le tableau", - "Exporting board..." : "Exportation de la carte...", + "Exporting board..." : "Exportation du tableau…", "An error occurred" : "Une erreur est survenue", "Board details" : "Détails du tableau", - "Edit board" : "Renommer le tableau", + "Edit board" : "Modifier le tableau", "Clone board" : "Dupliquer le tableau", "Unarchive board" : "Désarchiver le tableau", "Archive board" : "Archiver le tableau", "Export board" : "Exporter le tableau", - "Turn on due date reminders" : "Activer les rappels", - "Turn off due date reminders" : "Désactiver les rappels", - "Remove as default board" : "Retirer comme tableau par défaut", + "Turn on due date reminders" : "Activer les rappels d’échéance", + "Turn off due date reminders" : "Désactiver les rappels d’échéance", + "Remove as default board" : "Ne plus utiliser comme tableau par défaut", "Set as default board" : "Définir comme tableau par défaut", - "Due date reminders" : "Rappels", + "Due date reminders" : "Rappels d’échéance", "Assigned cards" : "Cartes assignées", "No notifications" : "Aucune notification", "Delete board" : "Supprimer le tableau", "Leave board" : "Quitter le tableau", - "Importing board..." : "Importation du tableau...", - "Board imported successfully" : "Carte importée avec succès", + "Importing board..." : "Importation du tableau…", + "Board imported successfully" : "Tableau importé avec succès", "Import board" : "Importer un tableau", - "Clone {boardTitle}" : "Cloner {boardTitle}", + "Clone {boardTitle}" : "Dupliquer {boardTitle}", "Clone cards" : "Dupliquer les cartes", - "Clone assignments" : "Cloner les affectations", - "Clone labels" : "Cloner les étiquettes", - "Clone due dates" : "Cloner les dates d'échéance", + "Clone assignments" : "Dupliquer les affectations", + "Clone labels" : "Dupliquer les étiquettes", + "Clone due dates" : "Dupliquer les dates d’échéance", "Advanced options" : "Options avancées", "Move all cards to the first list" : "Déplacer toutes les cartes vers la première liste", "Restore archived cards" : "Restaurer les cartes archivées", @@ -395,27 +395,27 @@ "Export {boardTitle}" : "Exporter {boardTitle}", "Export as JSON" : "Exporter au format JSON", "Export as CSV" : "Exporter en CSV", - "Note: Only the JSON format is supported for importing back into the Deck app." : "Remarque : seul le format JSON est pris en charge pour la réimportation dans l'application Deck.", + "Note: Only the JSON format is supported for importing back into the Deck app." : "Remarque : seul le format JSON est pris en charge pour la réimportation dans Deck.", "Export" : "Exporter", "Loading filtered view" : "Chargement de la vue filtrée", "Search for {searchQuery} in other boards" : "Rechercher {searchQuery} dans les autres tableaux", - "Search for {searchQuery} in all boards" : "Recherche de {searchQuery} dans tous les tableaux", + "Search for {searchQuery} in all boards" : "Rechercher {searchQuery} dans tous les tableaux", "No results found" : "Aucun résultat", "Deck board {name}\n* Last modified on {lastMod}" : "Tableau Deck {name}\n* Dernière modification le {lastMod}", - "* Created on {created}\n* Last modified on {lastMod}\n* {nbAttachments} attachments\n* {nbComments} comments" : "* Créée le {created}\n* Dernière modification le {lastMod}\n* {nbAttachments} pièces jointes\n* {nbComments} commentaires", - "{nbCards} cards" : "{nbCards} cartes", + "* Created on {created}\n* Last modified on {lastMod}\n* {nbAttachments} attachments\n* {nbComments} comments" : "* Création : {created}\n* Dernière modification : {lastMod}\n* Pièces jointes : {nbAttachments}\n* Commentaires : {nbComments}", + "{nbCards} cards" : "Cartes : {nbCards}", "Due on {date}" : "Échéance le {date}", "{stack} in {board}" : "{stack} dans {board}", - "Click to expand description" : "Cliquer pour visualiser la description", - "Click to expand comment" : "Cliquer pour déplier le commentaire", + "Click to expand description" : "Cliquez pour développer la description", + "Click to expand comment" : "Cliquez pour développer le commentaire", "Create card" : "Créer la carte", "Create a new card" : "Créer une nouvelle carte", "Card title" : "Titre de la carte", "Creating the new card …" : "Création de la nouvelle carte…", - "Card \"{card}\" was added to \"{board}\"" : "La carte \"{card}\" a été ajoutée au tableau \"{board}\"", + "Card \"{card}\" was added to \"{board}\"" : "La carte « {card} » a été ajoutée au tableau « {board} »", "Open card" : "Ouvrir la carte", "Close" : "Fermer", - "No upcoming cards" : "Pas de cartes à venir", + "No upcoming cards" : "Aucune carte à venir", "upcoming cards today" : "cartes à venir aujourd'hui", "upcoming cards tomorrow" : "cartes à venir demain", "upcoming cards" : "cartes à venir", @@ -424,8 +424,8 @@ "Link to a card" : "Relier à une carte", "Create a card" : "Créer une carte", "Message from {author} in {conversationName}" : "Message de {author} dans {conversationName}", - "Something went wrong" : "Quelque chose s'est mal passé", - "Failed to upload {name}" : "Échec d'envoi de {name}", + "Something went wrong" : "Une erreur est survenue", + "Failed to upload {name}" : "Échec du téléversement de {name}", "Maximum file size of {size} exceeded" : "Taille de fichier maximale de {size} dépassée", "Assigned users" : "Utilisateurs assignés", "Due date" : "Date d'échéance", @@ -433,11 +433,11 @@ "Modified" : "Modifiée", "Error creating the share" : "Erreur lors de la création du partage", "Share with a Deck card" : "Partager avec une carte Deck", - "Share {file} with a Deck card" : "Partager {file} avec une carte Deck ", + "Share {file} with a Deck card" : "Partager {file} avec une carte Deck", "Share" : "Partager", - "The card \"%s\" on \"%s\" has reached its due date." : "La date d'échéance de la carte \"%s\" de \"%s\" a été atteinte.", - "Share board with a user, group or team …" : "Partager le tableau avec un utilisateur, un groupe ou une équipe...", - "Searching for users, groups and teams …" : "Recherche d'utilisateurs, de groupes et d'équipes...", + "The card \"%s\" on \"%s\" has reached its due date." : "La carte « %s » du tableau « %s » est arrivée à échéance.", + "Share board with a user, group or team …" : "Partager le tableau avec un utilisateur, un groupe ou une équipe…", + "Searching for users, groups and teams …" : "Recherche d’utilisateurs, de groupes et d’équipes…", "No participants found" : "Aucun participant trouvé", "Save" : "Enregistrer", "seconds ago" : "à l'instant", From 089f1d7f214f475705fd9c23145f32beb43b5f00 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 5 Sep 2026 01:36:53 +0000 Subject: [PATCH 20/31] Chore(deps): Bump dompurify from 3.4.13 to 3.4.14 Bumps [dompurify](https://github.com/cure53/DOMPurify) from 3.4.13 to 3.4.14. - [Release notes](https://github.com/cure53/DOMPurify/releases) - [Commits](https://github.com/cure53/DOMPurify/compare/3.4.13...3.4.14) --- updated-dependencies: - dependency-name: dompurify dependency-version: 3.4.14 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 140 +--------------------------------------------- 1 file changed, 3 insertions(+), 137 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8e0a0498c2..4fd48cb515 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5110,34 +5110,6 @@ "@vue/shared": "3.5.30" } }, - "node_modules/@nextcloud/password-confirmation/node_modules/@vue/devtools-kit": { - "version": "7.7.9", - "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.9.tgz", - "integrity": "sha512-PyQ6odHSgiDVd4hnTP+aDk2X4gl2HmLDfiyEnn3/oV+ckFDuswRs4IbBT7vacMuGdwY/XemxBoh302ctbsptuA==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "@vue/devtools-shared": "^7.7.9", - "birpc": "^2.3.0", - "hookable": "^5.5.3", - "mitt": "^3.0.1", - "perfect-debounce": "^1.0.0", - "speakingurl": "^14.0.1", - "superjson": "^2.2.2" - } - }, - "node_modules/@nextcloud/password-confirmation/node_modules/@vue/devtools-shared": { - "version": "7.7.9", - "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.9.tgz", - "integrity": "sha512-iWAb0v2WYf0QWmxCGy0seZNDPdO3Sp5+u78ORnyeonS6MT4PC7VPrryX2BpMJrwlDeaZ6BD4vP4XKjK0SZqaeA==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "rfdc": "^1.4.1" - } - }, "node_modules/@nextcloud/password-confirmation/node_modules/@vue/server-renderer": { "version": "3.5.30", "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.30.tgz", @@ -5284,14 +5256,6 @@ "tabbable": "^6.4.0" } }, - "node_modules/@nextcloud/password-confirmation/node_modules/perfect-debounce": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", - "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", - "license": "MIT", - "optional": true, - "peer": true - }, "node_modules/@nextcloud/password-confirmation/node_modules/picomatch": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", @@ -5304,40 +5268,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/@nextcloud/password-confirmation/node_modules/pinia": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/pinia/-/pinia-3.0.4.tgz", - "integrity": "sha512-l7pqLUFTI/+ESXn6k3nu30ZIzW5E2WZF/LaHJEpoq6ElcLD+wduZoB2kBN19du6K/4FDpPMazY2wJr+IndBtQw==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "@vue/devtools-api": "^7.7.7" - }, - "funding": { - "url": "https://github.com/sponsors/posva" - }, - "peerDependencies": { - "typescript": ">=4.5.0", - "vue": "^3.5.11" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@nextcloud/password-confirmation/node_modules/pinia/node_modules/@vue/devtools-api": { - "version": "7.7.9", - "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.7.9.tgz", - "integrity": "sha512-kIE8wvwlcZ6TJTbNeU2HQNtaxLx3a84aotTITUuL/4bzfPxzajGBOoqjMhwZJ8L9qFYDU/lAYMEEm11dnZOD6g==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "@vue/devtools-kit": "^7.7.9" - } - }, "node_modules/@nextcloud/password-confirmation/node_modules/rehype-react": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/rehype-react/-/rehype-react-8.0.0.tgz", @@ -10450,23 +10380,6 @@ "node": ">=6.6.0" } }, - "node_modules/copy-anything": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-4.0.5.tgz", - "integrity": "sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "is-what": "^5.2.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/mesqueeb" - } - }, "node_modules/core-js": { "version": "2.6.9", "hasInstallScript": true, @@ -11946,9 +11859,9 @@ } }, "node_modules/dompurify": { - "version": "3.4.13", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.13.tgz", - "integrity": "sha512-2vmYIoqjze2d+kakP8S/nS5shfsl587kzwEjcGlTdiksUVgFHnFCsLYDVj/JNqJVOQZGSYBTmuycv0PodwmnMQ==", + "version": "3.4.14", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.14.tgz", + "integrity": "sha512-dVoH9z+MY+C9IilgGCk3YfFqjLi3fChm2OiKJMzh6axrJ5qwxqWaZamgmHrpv22CN/KdbZJuGEGgfQoL00LTdg==", "license": "(MPL-2.0 OR Apache-2.0)", "optionalDependencies": { "@types/trusted-types": "^2.0.7" @@ -16026,20 +15939,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-what": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/is-what/-/is-what-5.5.0.tgz", - "integrity": "sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==", - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/mesqueeb" - } - }, "node_modules/is-whitespace": { "version": "0.3.0", "dev": true, @@ -19797,14 +19696,6 @@ "node": ">=16 || 14 >=14.17" } }, - "node_modules/mitt": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", - "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", - "license": "MIT", - "optional": true, - "peer": true - }, "node_modules/mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", @@ -23417,17 +23308,6 @@ "license": "CC0-1.0", "peer": true }, - "node_modules/speakingurl": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz", - "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==", - "license": "BSD-3-Clause", - "optional": true, - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/spec-change": { "version": "1.11.21", "resolved": "https://registry.npmjs.org/spec-change/-/spec-change-1.11.21.tgz", @@ -24616,20 +24496,6 @@ "node": ">=18" } }, - "node_modules/superjson": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.6.tgz", - "integrity": "sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "copy-anything": "^4" - }, - "engines": { - "node": ">=16" - } - }, "node_modules/superstruct": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-2.0.2.tgz", From 3fba8cebe0a672c500b7e49c24271c9e41468fec Mon Sep 17 00:00:00 2001 From: nextcloud-command Date: Sun, 6 Sep 2026 07:08:10 +0000 Subject: [PATCH 21/31] chore(dev-deps): Bump nextcloud/ocp package Signed-off-by: GitHub --- composer.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index c2f2c3292b..11f4165c68 100644 --- a/composer.lock +++ b/composer.lock @@ -446,12 +446,12 @@ "source": { "type": "git", "url": "https://github.com/nextcloud-deps/ocp.git", - "reference": "75e04c37b52633c6601b63af3a33a71e0f48967e" + "reference": "94d85a0ba6b3b3911c25b2eddb0ca0fe5691acbf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nextcloud-deps/ocp/zipball/75e04c37b52633c6601b63af3a33a71e0f48967e", - "reference": "75e04c37b52633c6601b63af3a33a71e0f48967e", + "url": "https://api.github.com/repos/nextcloud-deps/ocp/zipball/94d85a0ba6b3b3911c25b2eddb0ca0fe5691acbf", + "reference": "94d85a0ba6b3b3911c25b2eddb0ca0fe5691acbf", "shasum": "" }, "require": { @@ -469,7 +469,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "35.0.0-dev" + "dev-stable35": "35.0.0-dev" } }, "notification-url": "https://packagist.org/downloads/", @@ -489,9 +489,9 @@ "description": "Composer package containing Nextcloud's public OCP API and the unstable NCU API", "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/stable35" }, - "time": "2026-08-24T17:09:03+00:00" + "time": "2026-09-04T01:52:36+00:00" }, { "name": "nikic/php-parser", From dc31a9248aacb876a2102179797de4d22c075cdb Mon Sep 17 00:00:00 2001 From: Luka Trovic Date: Fri, 11 Sep 2026 18:39:56 +0200 Subject: [PATCH 22/31] fix: package-lock mismatch Signed-off-by: Luka Trovic --- package-lock.json | 119 +++++++++++++++++++++++++++++++++++++++++++++- package.json | 2 +- 2 files changed, 119 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4fd48cb515..b5500d8324 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,7 +26,7 @@ "@nextcloud/vue": "^8.39.0", "blueimp-md5": "^2.19.0", "chroma-js": "^3.2.0", - "dompurify": "^3.4.13", + "dompurify": "^3.4.14", "frappe-gantt": "^1.2.2", "lodash": "^4.18.1", "markdown-it": "^15.0.0", @@ -5110,6 +5110,34 @@ "@vue/shared": "3.5.30" } }, + "node_modules/@nextcloud/password-confirmation/node_modules/@vue/devtools-kit": { + "version": "7.7.10", + "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.10.tgz", + "integrity": "sha512-3WNi2Kq4tbpVbmhml7RiphmAt0279oh3fKNeWMQIrltfX8Q91b4i5PL8DtyNKdwmcsGrV4fg+erwWOmD05CLIw==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@vue/devtools-shared": "^7.7.10", + "birpc": "^2.3.0", + "hookable": "^5.5.3", + "mitt": "^3.0.1", + "perfect-debounce": "^1.0.0", + "speakingurl": "^14.0.1", + "superjson": "^2.2.2" + } + }, + "node_modules/@nextcloud/password-confirmation/node_modules/@vue/devtools-shared": { + "version": "7.7.10", + "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.10.tgz", + "integrity": "sha512-wOPslzB8vTvpxwdaOcR2qAbwmuSP0L+rhpoC6Cf56V3Jip+HWb7PQQXOUPgBNQARpXsbQX/+mvi8kKucmBGRwQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "rfdc": "^1.4.1" + } + }, "node_modules/@nextcloud/password-confirmation/node_modules/@vue/server-renderer": { "version": "3.5.30", "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.30.tgz", @@ -5256,6 +5284,14 @@ "tabbable": "^6.4.0" } }, + "node_modules/@nextcloud/password-confirmation/node_modules/perfect-debounce": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", + "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", + "license": "MIT", + "optional": true, + "peer": true + }, "node_modules/@nextcloud/password-confirmation/node_modules/picomatch": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", @@ -5268,6 +5304,40 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/@nextcloud/password-confirmation/node_modules/pinia": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pinia/-/pinia-3.0.4.tgz", + "integrity": "sha512-l7pqLUFTI/+ESXn6k3nu30ZIzW5E2WZF/LaHJEpoq6ElcLD+wduZoB2kBN19du6K/4FDpPMazY2wJr+IndBtQw==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@vue/devtools-api": "^7.7.7" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "typescript": ">=4.5.0", + "vue": "^3.5.11" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@nextcloud/password-confirmation/node_modules/pinia/node_modules/@vue/devtools-api": { + "version": "7.7.10", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.7.10.tgz", + "integrity": "sha512-KxtEpUOOpFz/qOGRrAwA36QF7DqIA+FXgCYit9mk9wjbaZt0sXOFz81ElOZtKA4HbWHUdwNjZHBFsFFyp5BZiA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@vue/devtools-kit": "^7.7.10" + } + }, "node_modules/@nextcloud/password-confirmation/node_modules/rehype-react": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/rehype-react/-/rehype-react-8.0.0.tgz", @@ -10380,6 +10450,20 @@ "node": ">=6.6.0" } }, + "node_modules/copy-anything": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-4.1.0.tgz", + "integrity": "sha512-ufbM3smX/Jbnpk5wcQjzd1MgBpzmqfNETUAyZNrGwU9foRlyHoGzMMBBCRzEhQLBjZfFDE1W2ufPXX2vdWkV8Q==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, "node_modules/core-js": { "version": "2.6.9", "hasInstallScript": true, @@ -19696,6 +19780,14 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", + "license": "MIT", + "optional": true, + "peer": true + }, "node_modules/mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", @@ -23308,6 +23400,17 @@ "license": "CC0-1.0", "peer": true }, + "node_modules/speakingurl": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz", + "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==", + "license": "BSD-3-Clause", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/spec-change": { "version": "1.11.21", "resolved": "https://registry.npmjs.org/spec-change/-/spec-change-1.11.21.tgz", @@ -24496,6 +24599,20 @@ "node": ">=18" } }, + "node_modules/superjson": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.6.tgz", + "integrity": "sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "copy-anything": "^4" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/superstruct": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-2.0.2.tgz", diff --git a/package.json b/package.json index 8d15492cbd..7308a76fca 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "@nextcloud/vue": "^8.39.0", "blueimp-md5": "^2.19.0", "chroma-js": "^3.2.0", - "dompurify": "^3.4.13", + "dompurify": "^3.4.14", "frappe-gantt": "^1.2.2", "lodash": "^4.18.1", "markdown-it": "^15.0.0", From e554e241cde7423465ea9b1f095b9008f572c9cb Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Sat, 12 Sep 2026 00:51:21 +0000 Subject: [PATCH 23/31] fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- l10n/lv.js | 2 ++ l10n/lv.json | 2 ++ 2 files changed, 4 insertions(+) diff --git a/l10n/lv.js b/l10n/lv.js index 51474ca8a5..e88ccc8e0c 100644 --- a/l10n/lv.js +++ b/l10n/lv.js @@ -9,6 +9,8 @@ OC.L10N.register( "{user} has renamed the card {before} to {card}" : "{user} pārdēvēja kartīti {before} par {card}", "You have added a description to card {card} in list {stack} on board {board}" : "Tu pievienoji kartītes {card} aprakstu dēļa {board} sarakstā {stack}", "{user} has added a description to card {card} in list {stack} on board {board}" : "{user} pievienoja kartītes {card} aprakstu dēļa {board} sarakstā {stack}", + "You have added the tag {label} to card {card} in list {stack} on board {board}" : "Tu pievienoji birku {label} kartītei {card} dēļa {board} sarakstā {stack}", + "You have added the attachment {attachment} to card {card}" : "Tu pievienoji pielikumu {attachment} kartītei {card}", "The file was uploaded" : "Datne tika augšupielādēta", "The uploaded file exceeds the upload_max_filesize directive in php.ini" : "Augšupielādētā datne pārsniedz php.ini norādīto upload_max_filesize vērtību", "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Augšupielādētā datne pārsniedz MAX_FILE_SIZE norādi, kas ir norādīta HTML formā", diff --git a/l10n/lv.json b/l10n/lv.json index 8e0b7a0a73..1872d9639a 100644 --- a/l10n/lv.json +++ b/l10n/lv.json @@ -7,6 +7,8 @@ "{user} has renamed the card {before} to {card}" : "{user} pārdēvēja kartīti {before} par {card}", "You have added a description to card {card} in list {stack} on board {board}" : "Tu pievienoji kartītes {card} aprakstu dēļa {board} sarakstā {stack}", "{user} has added a description to card {card} in list {stack} on board {board}" : "{user} pievienoja kartītes {card} aprakstu dēļa {board} sarakstā {stack}", + "You have added the tag {label} to card {card} in list {stack} on board {board}" : "Tu pievienoji birku {label} kartītei {card} dēļa {board} sarakstā {stack}", + "You have added the attachment {attachment} to card {card}" : "Tu pievienoji pielikumu {attachment} kartītei {card}", "The file was uploaded" : "Datne tika augšupielādēta", "The uploaded file exceeds the upload_max_filesize directive in php.ini" : "Augšupielādētā datne pārsniedz php.ini norādīto upload_max_filesize vērtību", "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Augšupielādētā datne pārsniedz MAX_FILE_SIZE norādi, kas ir norādīta HTML formā", From ea852bf13574c92fbd9576264f0a28a24300c85c Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Sun, 13 Sep 2026 00:50:15 +0000 Subject: [PATCH 24/31] fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- l10n/hu.js | 6 +++++- l10n/hu.json | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/l10n/hu.js b/l10n/hu.js index 5aee8880bc..4409cd1238 100644 --- a/l10n/hu.js +++ b/l10n/hu.js @@ -189,6 +189,7 @@ OC.L10N.register( "Deck settings" : "Kártyák beállításai", "General" : "Általános", "Use bigger card view" : "Nagyobb kártyanézet használata", + "Add new cards at the top of a list" : "Új kártyák hozzáadása a lista tetejéhez", "Appearance" : "Megjelenés", "Show card ID badge" : "Kártyaazonosító jelvény megjelenítése", "Show boards in calendar/tasks" : "Táblák megjelenítése a naptárak/teendők között", @@ -212,6 +213,8 @@ OC.L10N.register( "Mark card as completed/not completed" : "Jelenlegi kártya késznek jelölése be/ki", "Open card menu" : "Kártyamenü megnyitása", "Currently present people" : "Jelenleg jelenlévő emberek", + "Supported prefixes: {prefixes}. Wrap phrases in double quotes." : "Támogatott előtagok: {prefixes}. A kifejezéseket tegye dupla idézőjelek közé.", + "Search cards" : "Kártyák keresése", "Loading board" : "Tábla betöltése", "Board not found" : "A tábla nem található", "Create a new list to add cards to this board" : "Hozzon létre egy új listát a kártyák ehhez a táblához való hozzáadásához", @@ -230,7 +233,7 @@ OC.L10N.register( "Set a start date and due date on your cards to see them on the Gantt chart" : "Állítson be kezdődátumot és határidőt a kártyákon, hogy lássa őket a Gantt-diagramon", "Cards without dates ({count})" : "Dátum nélküli kártyák ({count})", "Failed to create share with {displayName}" : "Nem lehet létrehozni a következő megosztást: {displayName}", - "Are you sure you want to transfer the board {title} to {user}?" : "Biztos, hogy átadja a(z) {board} tábla tulajdonjogát {user} számára?", + "Are you sure you want to transfer the board {title} to {user}?" : "Biztos, hogy átadja a(z) {title} tábla tulajdonjogát {user} számára?", "Transfer the board." : "A tábla átadása.", "Transfer" : "Átadás", "The board has been transferred to {user}" : "A tábla átadása {user} számára sikeres", @@ -258,6 +261,7 @@ OC.L10N.register( "title and color value must be provided" : "a cím és szín értékét meg kell adni", "Edit" : "Szerkesztés", "Add a new tag" : "Új címke hozzáadása", + "Search boards" : "Táblák keresése", "Board name" : "Tábla neve", "Members" : "Tagok", "Assign to users/groups/team" : "Felhasználóhoz/csoporthoz/csapathoz rendelés", diff --git a/l10n/hu.json b/l10n/hu.json index ee211a7f5e..380c992756 100644 --- a/l10n/hu.json +++ b/l10n/hu.json @@ -187,6 +187,7 @@ "Deck settings" : "Kártyák beállításai", "General" : "Általános", "Use bigger card view" : "Nagyobb kártyanézet használata", + "Add new cards at the top of a list" : "Új kártyák hozzáadása a lista tetejéhez", "Appearance" : "Megjelenés", "Show card ID badge" : "Kártyaazonosító jelvény megjelenítése", "Show boards in calendar/tasks" : "Táblák megjelenítése a naptárak/teendők között", @@ -210,6 +211,8 @@ "Mark card as completed/not completed" : "Jelenlegi kártya késznek jelölése be/ki", "Open card menu" : "Kártyamenü megnyitása", "Currently present people" : "Jelenleg jelenlévő emberek", + "Supported prefixes: {prefixes}. Wrap phrases in double quotes." : "Támogatott előtagok: {prefixes}. A kifejezéseket tegye dupla idézőjelek közé.", + "Search cards" : "Kártyák keresése", "Loading board" : "Tábla betöltése", "Board not found" : "A tábla nem található", "Create a new list to add cards to this board" : "Hozzon létre egy új listát a kártyák ehhez a táblához való hozzáadásához", @@ -228,7 +231,7 @@ "Set a start date and due date on your cards to see them on the Gantt chart" : "Állítson be kezdődátumot és határidőt a kártyákon, hogy lássa őket a Gantt-diagramon", "Cards without dates ({count})" : "Dátum nélküli kártyák ({count})", "Failed to create share with {displayName}" : "Nem lehet létrehozni a következő megosztást: {displayName}", - "Are you sure you want to transfer the board {title} to {user}?" : "Biztos, hogy átadja a(z) {board} tábla tulajdonjogát {user} számára?", + "Are you sure you want to transfer the board {title} to {user}?" : "Biztos, hogy átadja a(z) {title} tábla tulajdonjogát {user} számára?", "Transfer the board." : "A tábla átadása.", "Transfer" : "Átadás", "The board has been transferred to {user}" : "A tábla átadása {user} számára sikeres", @@ -256,6 +259,7 @@ "title and color value must be provided" : "a cím és szín értékét meg kell adni", "Edit" : "Szerkesztés", "Add a new tag" : "Új címke hozzáadása", + "Search boards" : "Táblák keresése", "Board name" : "Tábla neve", "Members" : "Tagok", "Assign to users/groups/team" : "Felhasználóhoz/csoporthoz/csapathoz rendelés", From 79687016e92ed0ee43d4d22c6366a9858b7f4a33 Mon Sep 17 00:00:00 2001 From: grnd-alt Date: Mon, 14 Sep 2026 16:18:53 +0200 Subject: [PATCH 25/31] fix(db): chunk queries for shared boards Signed-off-by: grnd-alt --- lib/Db/BoardMapper.php | 68 ++++++++++++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 23 deletions(-) diff --git a/lib/Db/BoardMapper.php b/lib/Db/BoardMapper.php index b334a03910..e35e9e5a63 100644 --- a/lib/Db/BoardMapper.php +++ b/lib/Db/BoardMapper.php @@ -9,7 +9,6 @@ use OCA\Deck\Service\CirclesService; use OCP\AppFramework\Db\DoesNotExistException; -use OCP\AppFramework\Db\QBMapper; use OCP\Cache\CappedMemoryCache; use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\Federation\ICloudIdManager; @@ -18,8 +17,8 @@ use OCP\IUserManager; use Psr\Log\LoggerInterface; -/** @template-extends QBMapper */ -class BoardMapper extends QBMapper implements IPermissionMapper { +/** @template-extends DeckMapper */ +class BoardMapper extends DeckMapper implements IPermissionMapper { /** @var CappedMemoryCache */ private CappedMemoryCache $userBoardCache; /** @var CappedMemoryCache */ @@ -92,16 +91,20 @@ public function findBoardIds(string $userId): array { }, $result->fetchAll(\PDO::FETCH_COLUMN)); $result->closeCursor(); + // Shared to the user $qb = $this->db->getQueryBuilder(); $qb->selectDistinct('b.id') ->from($this->getTableName(), 'b') - ->innerJoin('b', 'deck_board_acl', 'acl', $qb->expr()->eq('b.id', 'acl.board_id')); - - // Shared to the user - $qb->where($qb->expr()->andX( - $qb->expr()->eq('acl.type', $qb->createNamedParameter(Acl::PERMISSION_TYPE_USER, IQueryBuilder::PARAM_INT)), - $qb->expr()->eq('acl.participant', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)), - )); + ->innerJoin('b', 'deck_board_acl', 'acl', $qb->expr()->eq('b.id', 'acl.board_id')) + ->where($qb->expr()->andX( + $qb->expr()->eq('acl.type', $qb->createNamedParameter(Acl::PERMISSION_TYPE_USER, IQueryBuilder::PARAM_INT)), + $qb->expr()->eq('acl.participant', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)), + )); + $result = $qb->executeQuery(); + $sharedBoards = array_map(function (string $id) { + return (int)$id; + }, $result->fetchAll(\PDO::FETCH_COLUMN)); + $result->closeCursor(); // Shared to user groups of the user $user = $this->userManager->get($userId); @@ -110,26 +113,45 @@ public function findBoardIds(string $userId): array { $groupIds = $this->groupManager->getUserGroupIds($user); } if ($groupIds !== null && count($groupIds) !== 0) { - $qb->orWhere($qb->expr()->andX( - $qb->expr()->eq('acl.type', $qb->createNamedParameter(Acl::PERMISSION_TYPE_GROUP, IQueryBuilder::PARAM_INT)), - $qb->expr()->in('acl.participant', $qb->createNamedParameter($groupIds, IQueryBuilder::PARAM_STR_ARRAY)), - )); + $sharedBoards = array_merge($sharedBoards, iterator_to_array($this->chunkQuery($groupIds, function (array $groupIdsChunk): array { + $qb = $this->db->getQueryBuilder(); + $qb->selectDistinct('b.id') + ->from($this->getTableName(), 'b') + ->innerJoin('b', 'deck_board_acl', 'acl', $qb->expr()->eq('b.id', 'acl.board_id')) + ->where($qb->expr()->andX( + $qb->expr()->eq('acl.type', $qb->createNamedParameter(Acl::PERMISSION_TYPE_GROUP, IQueryBuilder::PARAM_INT)), + $qb->expr()->in('acl.participant', $qb->createNamedParameter($groupIdsChunk, IQueryBuilder::PARAM_STR_ARRAY)), + )); + $result = $qb->executeQuery(); + $boardIds = array_map(function (string $id) { + return (int)$id; + }, $result->fetchAll(\PDO::FETCH_COLUMN)); + $result->closeCursor(); + return $boardIds; + }), false)); } // Shared to circles of the user $circles = $this->circlesService->getUserCircles($userId); if (count($circles) !== 0) { - $qb->orWhere($qb->expr()->andX( - $qb->expr()->eq('acl.type', $qb->createNamedParameter(Acl::PERMISSION_TYPE_CIRCLE, IQueryBuilder::PARAM_INT)), - $qb->expr()->in('acl.participant', $qb->createNamedParameter($circles, IQueryBuilder::PARAM_STR_ARRAY)), - )); + $sharedBoards = array_merge($sharedBoards, iterator_to_array($this->chunkQuery($circles, function (array $circlesChunk): array { + $qb = $this->db->getQueryBuilder(); + $qb->selectDistinct('b.id') + ->from($this->getTableName(), 'b') + ->innerJoin('b', 'deck_board_acl', 'acl', $qb->expr()->eq('b.id', 'acl.board_id')) + ->where($qb->expr()->andX( + $qb->expr()->eq('acl.type', $qb->createNamedParameter(Acl::PERMISSION_TYPE_CIRCLE, IQueryBuilder::PARAM_INT)), + $qb->expr()->in('acl.participant', $qb->createNamedParameter($circlesChunk, IQueryBuilder::PARAM_STR_ARRAY)), + )); + $result = $qb->executeQuery(); + $boardIds = array_map(function (string $id) { + return (int)$id; + }, $result->fetchAll(\PDO::FETCH_COLUMN)); + $result->closeCursor(); + return $boardIds; + }), false)); } - $result = $qb->executeQuery(); - $sharedBoards = array_map(function (string $id) { - return (int)$id; - }, $result->fetchAll(\PDO::FETCH_COLUMN)); - $result->closeCursor(); return array_unique(array_merge($ownerBoards, $sharedBoards)); } /** From 5b26865a709b7cb103685462e8a9f18b44622347 Mon Sep 17 00:00:00 2001 From: grnd-alt Date: Mon, 14 Sep 2026 16:46:37 +0200 Subject: [PATCH 26/31] fix(ci): use ->get instead of ->query Signed-off-by: grnd-alt --- tests/integration/app/AppTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/app/AppTest.php b/tests/integration/app/AppTest.php index 7e062dd081..34b83f4fc8 100644 --- a/tests/integration/app/AppTest.php +++ b/tests/integration/app/AppTest.php @@ -40,7 +40,7 @@ public function setUp(): void { } public function testAppInstalled() { - $appManager = $this->container->query('OCP\App\IAppManager'); + $appManager = $this->container->get('OCP\App\IAppManager'); $this->assertTrue($appManager->isInstalled('deck')); } } From 418de6885bf310b6783982b1af581cc3ac0d3f28 Mon Sep 17 00:00:00 2001 From: grnd-alt Date: Wed, 9 Sep 2026 17:00:47 +0200 Subject: [PATCH 27/31] enh(performance): get deck share permissions in one query Signed-off-by: grnd-alt --- lib/Db/AclMapper.php | 27 ++++++++++++++++++++++++ lib/Service/PermissionService.php | 25 +++++++++++++++++++++++ lib/Sharing/DeckShareProvider.php | 34 +++++++++++++++---------------- 3 files changed, 69 insertions(+), 17 deletions(-) diff --git a/lib/Db/AclMapper.php b/lib/Db/AclMapper.php index defba19d12..e853bb4765 100644 --- a/lib/Db/AclMapper.php +++ b/lib/Db/AclMapper.php @@ -44,6 +44,33 @@ public function findAll(int $boardId, ?int $limit = null, ?int $offset = null) { return $this->findEntities($qb); } + /** + * @return array Acl entries grouped by card id + * @throws \OCP\DB\Exception + */ + public function findInCards(array $cardIds, ?int $limit = null, ?int $offset = null): array { + $qb = $this->db->getQueryBuilder(); + $qb->select('acl.id', 'acl.board_id', 'acl.type', 'acl.participant', 'acl.permission_edit', 'acl.permission_share', 'acl.permission_manage', 'acl.created_at', 'acl.last_modified_at', 'c.id AS card_id') + ->from('deck_board_acl', 'acl') + ->innerJoin('acl', 'deck_boards', 'b', 'acl.board_id = b.id') + ->innerJoin('b', 'deck_stacks', 's', 's.board_id = b.id') + ->innerJoin('s', 'deck_cards', 'c', 'c.stack_id = s.id') + ->where($qb->expr()->in('c.id', $qb->createParameter('cardIds'))) + ->setMaxResults($limit) + ->setFirstResult($offset); + + $aclsByCardId = []; + foreach ($this->chunkQuery($cardIds, function (array $ids) use ($qb) { + $qb->setParameter('cardIds', $ids, IQueryBuilder::PARAM_INT_ARRAY); + return $qb->executeQuery()->fetchAll(); + }) as $row) { + $cardId = (int)$row['card_id']; + unset($row['card_id']); + $aclsByCardId[$cardId][] = Acl::fromRow($row); + } + return $aclsByCardId; + } + public function findIn(array $boardIds, ?int $limit = null, ?int $offset = null): array { $qb = $this->db->getQueryBuilder(); $qb->select('id', 'board_id', 'type', 'participant', 'permission_edit', 'permission_share', 'permission_manage', 'created_at', 'last_modified_at') diff --git a/lib/Service/PermissionService.php b/lib/Service/PermissionService.php index 2f370fa457..a22c6e12b4 100644 --- a/lib/Service/PermissionService.php +++ b/lib/Service/PermissionService.php @@ -63,6 +63,31 @@ public function setAccessToken(string $token) { $this->accessToken = $token; } + /** + * Get permissions for all supplied card ids + * @param int[] $cardIds + * @param ?string $userId + * @param bool $allowDeleted + * @return array> + */ + public function getPermissionsForCards(array $cardIds, ?string $userId = null, bool $allowDeleted = false): array { + if ($userId === null) { + $userId = $this->userId; + } + $permissions = $this->aclMapper->findInCards($cardIds); + return array_map( + function (array $acls) use ($userId) { + return [ + Acl::PERMISSION_READ => $this->userCan($acls, Acl::PERMISSION_READ, $userId), + Acl::PERMISSION_EDIT => $this->userCan($acls, Acl::PERMISSION_EDIT, $userId), + Acl::PERMISSION_MANAGE => $this->userCan($acls, Acl::PERMISSION_MANAGE, $userId), + Acl::PERMISSION_SHARE => $this->userCan($acls, Acl::PERMISSION_SHARE, $userId), + ]; + }, + $permissions + ); + } + /** * Get current user permissions for a board by id * diff --git a/lib/Sharing/DeckShareProvider.php b/lib/Sharing/DeckShareProvider.php index 408f39d4da..ef41e4301e 100644 --- a/lib/Sharing/DeckShareProvider.php +++ b/lib/Sharing/DeckShareProvider.php @@ -269,22 +269,6 @@ private function createShareObject(array $data): IShare { return $share; } - private function applyBoardPermission($share, $permissions, $userId) { - try { - $this->permissionService->checkPermission($this->cardMapper, $share->getSharedWith(), Acl::PERMISSION_EDIT, $userId, true); - } catch (NoPermissionException $e) { - $permissions &= Constants::PERMISSION_ALL - Constants::PERMISSION_UPDATE; - $permissions &= Constants::PERMISSION_ALL - Constants::PERMISSION_CREATE; - $permissions &= Constants::PERMISSION_ALL - Constants::PERMISSION_DELETE; - } - - try { - $this->permissionService->checkPermission($this->cardMapper, $share->getSharedWith(), Acl::PERMISSION_SHARE, $userId, true); - } catch (NoPermissionException $e) { - $permissions &= Constants::PERMISSION_ALL - Constants::PERMISSION_SHARE; - } - $share->setPermissions($permissions); - } /** * @inheritDoc */ @@ -652,11 +636,13 @@ private function resolveSharesForRecipient(array $shares, string $userId): array /** @var int[] $ids */ $ids = []; + $cardIds = []; /** @var IShare[] $shareMap */ $shareMap = []; foreach ($shareSlice as $share) { $ids[] = (int)$share->getId(); + $cardIds[] = (int)$share->getSharedWith(); $shareMap[$share->getId()] = $share; } @@ -673,8 +659,22 @@ private function resolveSharesForRecipient(array $shares, string $userId): array $stmt = $query->executeQuery(); + $permissions = $this->permissionService->getPermissionsForCards($cardIds, $userId); + while ($data = $stmt->fetch()) { - $this->applyBoardPermission($shareMap[$data['parent']], (int)$data['permissions'], $userId); + $parent = $shareMap[$data['parent']]; + $sharePermissions = (int)$data['permissions']; + if (isset($permissions[(int)$parent->getSharedWith()])) { + if ($permissions[(int)$parent->getSharedWith()][Acl::PERMISSION_EDIT] === false) { + $sharePermissions &= Constants::PERMISSION_ALL - Constants::PERMISSION_UPDATE; + $sharePermissions &= Constants::PERMISSION_ALL - Constants::PERMISSION_CREATE; + $sharePermissions &= Constants::PERMISSION_ALL - Constants::PERMISSION_DELETE; + } + if ($permissions[(int)$parent->getSharedWith()][Acl::PERMISSION_SHARE] === false) { + $sharePermissions &= Constants::PERMISSION_ALL - Constants::PERMISSION_SHARE; + } + } + $shareMap[$data['parent']]->setPermissions($sharePermissions); $shareMap[$data['parent']]->setTarget($data['file_target']); } From e3113cb0f49c6730a83ebc54f6be3423403dcca4 Mon Sep 17 00:00:00 2001 From: samin-z Date: Fri, 4 Sep 2026 15:33:40 +0200 Subject: [PATCH 28/31] fix: write imported attachments to the importer's storage Signed-off-by: samin-z --- lib/Service/FilesAppService.php | 53 +++++++++++++------ .../Importer/Systems/DeckJsonService.php | 6 +-- 2 files changed, 37 insertions(+), 22 deletions(-) diff --git a/lib/Service/FilesAppService.php b/lib/Service/FilesAppService.php index 75788ecf1c..d6824c51b6 100644 --- a/lib/Service/FilesAppService.php +++ b/lib/Service/FilesAppService.php @@ -255,10 +255,20 @@ public function createFromImport(Attachment $attachment, string $content): Attac $fileName = $attachment->getData(); $this->validateFilename($fileName); - $ownerId = $attachment->getCreatedBy() ?: $this->userId; - if (!is_string($ownerId) || $ownerId === '') { - throw new StatusException('Could not resolve owner for imported attachment'); - } + $cardId = $attachment->getCardId(); + // Use the session user or the card owner for imports without a request user. + $ownerId = $this->resolveImportStorageOwner($attachment); + $this->permissionService->checkPermission( + $this->cardMapper, + $cardId, + Acl::PERMISSION_EDIT, + $ownerId, + true, + true + ); + // Import may run without request user context. + // Set the actor explicitly so DeckShareProvider permission checks evaluate correctly. + $this->permissionService->setUserId($ownerId); $userFolder = $this->rootFolder->getUserFolder($ownerId); $attachmentFolderName = $this->configService->getAttachmentFolder($ownerId); @@ -282,7 +292,6 @@ public function createFromImport(Attachment $attachment, string $content): Attac $target->putContent($content); } - $cardId = $attachment->getCardId(); foreach ($this->shareProvider->getSharesByPath($target) as $share) { if ((int)$share->getSharedWith() === $cardId) { $attachment->setId((int)$share->getId()); @@ -291,18 +300,6 @@ public function createFromImport(Attachment $attachment, string $content): Attac } } - $this->permissionService->checkPermission( - $this->cardMapper, - $cardId, - Acl::PERMISSION_EDIT, - $ownerId, - true, - true - ); - // Import usually runs in background jobs without request user context. - // Set the actor explicitly so DeckShareProvider permission checks evaluate correctly. - $this->permissionService->setUserId($ownerId); - $share = $this->shareManager->newShare(); $share->setNode($target); $share->setShareType(IShare::TYPE_DECK); @@ -331,6 +328,28 @@ public function createFromImport(Attachment $attachment, string $content): Attac return $attachment; } + /** + * Resolve which user Files storage may receive an imported attachment. + * + * @throws StatusException + */ + private function resolveImportStorageOwner(Attachment $attachment): string { + if (is_string($this->userId) && $this->userId !== '') { + return $this->userId; + } + + try { + $ownerId = $this->cardMapper->find($attachment->getCardId())->getOwner(); + } catch (\Throwable) { + $ownerId = null; + } + if (!is_string($ownerId) || $ownerId === '') { + throw new StatusException('Could not resolve owner for imported attachment'); + } + + return $ownerId; + } + /** * @return array|null * @throws StatusException diff --git a/lib/Service/Importer/Systems/DeckJsonService.php b/lib/Service/Importer/Systems/DeckJsonService.php index 99dcb36bac..2aa7071d0c 100644 --- a/lib/Service/Importer/Systems/DeckJsonService.php +++ b/lib/Service/Importer/Systems/DeckJsonService.php @@ -201,11 +201,7 @@ private function importAttachmentsForCard(object $sourceCard): void { continue; } - try { - $this->getImportService()->insertAttachment($attachment, $content); - } catch (\Throwable $e) { - continue; - } + $this->getImportService()->insertAttachment($attachment, $content); } } From 493d9cd6c86c7f415c76b9bec074400ba38aae4c Mon Sep 17 00:00:00 2001 From: grnd-alt Date: Wed, 16 Sep 2026 14:06:35 +0200 Subject: [PATCH 29/31] release/1.19.0 Signed-off-by: grnd-alt --- CHANGELOG.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ appinfo/info.xml | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 48 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4be848709e..31f6ab2f4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,50 @@ # Changelog All notable changes to this project will be documented in this file. +## 1.19.0 + +### Added +* feat(board): show card count next to the list title by @SadeqRouhani in https://github.com/nextcloud/deck/pull/8038 +* 🧾Add share metadata by @AndyScherzinger in https://github.com/nextcloud/deck/pull/8069 +* feat(deck): add board filter input to the board header by @pringelmann in https://github.com/nextcloud/deck/pull/8215 +* feat(OCM): Implement ISignedCloudFederationProvider for deck by @mickenordin in https://github.com/nextcloud/deck/pull/8261 +* feat(board): show owner label next to owner name by @xhon-pelushi in https://github.com/nextcloud/deck/pull/8265 +* feature: Allow a team (circle) to own a board by @backportbot[bot] in https://github.com/nextcloud/deck/pull/8320 +* import on file by @backportbot[bot] in https://github.com/nextcloud/deck/pull/8393 + +### Fixed +* fix: show avatars in selector by @grnd-alt in https://github.com/nextcloud/deck/pull/7921 +* fix: use automatic text direction for comment input by @grnd-alt in https://github.com/nextcloud/deck/pull/8044 +* fix(ui): remove moment usage from due date badge by @grnd-alt in https://github.com/nextcloud/deck/pull/8096 +* fix: improve card open performance on boards with many cards by @nemphys in https://github.com/nextcloud/deck/pull/8112 +* fix: do not clear card color when update omits the field by @Lightshadow02 in https://github.com/nextcloud/deck/pull/8151 +* fix: calendar delegation by @GVodyanov in https://github.com/nextcloud/deck/pull/8213 +* fix: broken upload of attachment via api by @Somebodyisnobody in https://github.com/nextcloud/deck/pull/8156 +* fix: expose the documented endpoint for cloning a board by @solracsf in https://github.com/nextcloud/deck/pull/8220 +* fix: avoid a TypeError when uploading an attachment via the API by @solracsf in https://github.com/nextcloud/deck/pull/8219 +* Deck cards attachment fix: Prevent TypeError crash on undefined attachment info by @aquananu in https://github.com/nextcloud/deck/pull/8224 +* Update Cardsidebar.vue fix: Prevent TypeError crash on undefined curr… by @aquananu in https://github.com/nextcloud/deck/pull/8225 +* fix: replace changeColumn with modifyColumn by @grnd-alt in https://github.com/nextcloud/deck/pull/8262 +* fix(navigation): drop active board icon fill override by @xhon-pelushi in https://github.com/nextcloud/deck/pull/8264 +* fix(migration): support the public OCP\DB\Schema API by @AndyScherzinger in https://github.com/nextcloud/deck/pull/8277 +* fix(db): chunk queries for shared boards by @backportbot[bot] in https://github.com/nextcloud/deck/pull/8386 +* enh(performance): get deck share permissions in one query by @backportbot[bot] in https://github.com/nextcloud/deck/pull/8390 + +### Other +* Migrate `comment.js` Vuex store to Pinia by @theoholl in https://github.com/nextcloud/deck/pull/7827 +* chore(php): bump php to 8.3 by @grnd-alt in https://github.com/nextcloud/deck/pull/8067 +* perf: Avoid fetching full group information by @CarlSchwan in https://github.com/nextcloud/deck/pull/8143 +* refactor(pinia): move attachmentStore to pinia by @grnd-alt in https://github.com/nextcloud/deck/pull/8142 +* refactor(pinia): move stackStore to pinia by @grnd-alt in https://github.com/nextcloud/deck/pull/8163 +* Refactor/pinia migration card store by @grnd-alt in https://github.com/nextcloud/deck/pull/8218 +* refactor(pinia): move board logic to boardStore by @grnd-alt in https://github.com/nextcloud/deck/pull/8234 +* refactor(pinia): migrate dashboard store by @grnd-alt in https://github.com/nextcloud/deck/pull/8128 +* refactor(pinia): refactor trashbin store to pinia by @grnd-alt in https://github.com/nextcloud/deck/pull/8130 +* refactor(pinia): move overview store to pinia by @grnd-alt in https://github.com/nextcloud/deck/pull/8141 +* chore: Port away from QueryException by @CarlSchwan in https://github.com/nextcloud/deck/pull/8236 + +**Full Changelog**: https://github.com/nextcloud/deck/compare/v1.18.4...v1.19.0 + ## 1.16.0-beta.1 ### Added diff --git a/appinfo/info.xml b/appinfo/info.xml index 3a6e81071a..4cc6a80627 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -20,7 +20,7 @@ - 🚀 Get your project organized - 1.19.0-beta.2 + 1.19.0 agpl Julius Härtl Deck diff --git a/package-lock.json b/package-lock.json index b5500d8324..b0f1197678 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "deck", - "version": "1.19.0-beta.2", + "version": "1.19.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "deck", - "version": "1.19.0-beta.2", + "version": "1.19.0", "license": "agpl", "dependencies": { "@babel/polyfill": "^7.12.1", diff --git a/package.json b/package.json index 7308a76fca..be6c301d20 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "deck", "description": "", - "version": "1.19.0-beta.2", + "version": "1.19.0", "authors": [ { "name": "Julius Härtl", From b0d9f40bc2fa9431dea3a3624e87ac85fe11052d Mon Sep 17 00:00:00 2001 From: Luka Trovic Date: Fri, 18 Sep 2026 18:33:02 +0200 Subject: [PATCH 30/31] fix: due date events in activity logging Signed-off-by: Luka Trovic --- lib/Activity/ActivityManager.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/Activity/ActivityManager.php b/lib/Activity/ActivityManager.php index 2c7c0c4c3e..5b86847385 100644 --- a/lib/Activity/ActivityManager.php +++ b/lib/Activity/ActivityManager.php @@ -269,6 +269,9 @@ public function triggerUpdateEvents($objectType, ChangeSet $changeSet, $subject) 'after' => $entity->$getter() ]; if ($changes['before'] !== $changes['after']) { + if ($field === 'duedate' && $changes['before']->format('c') === $changes['after']->format('c')) { + continue; + } try { $event = $this->createEvent($objectType, $entity, $subjectComplete, $changes, $this->userId); if ($event !== null) { From bd58899b636952aeabfe4b4d2c50e8e34543ff85 Mon Sep 17 00:00:00 2001 From: Luka Trovic Date: Tue, 22 Sep 2026 10:22:00 +0200 Subject: [PATCH 31/31] fix: duedate comparison in activity logging Signed-off-by: Luka Trovic --- lib/Activity/ActivityManager.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/Activity/ActivityManager.php b/lib/Activity/ActivityManager.php index 5b86847385..f8478cedff 100644 --- a/lib/Activity/ActivityManager.php +++ b/lib/Activity/ActivityManager.php @@ -268,10 +268,9 @@ public function triggerUpdateEvents($objectType, ChangeSet $changeSet, $subject) 'before' => $previousEntity->$getter(), 'after' => $entity->$getter() ]; - if ($changes['before'] !== $changes['after']) { - if ($field === 'duedate' && $changes['before']->format('c') === $changes['after']->format('c')) { - continue; - } + $beforeValue = $changes['before'] instanceof \DateTimeInterface ? $changes['before']->format('c') : $changes['before']; + $afterValue = $changes['after'] instanceof \DateTimeInterface ? $changes['after']->format('c') : $changes['after']; + if ($beforeValue !== $afterValue) { try { $event = $this->createEvent($objectType, $entity, $subjectComplete, $changes, $this->userId); if ($event !== null) {