Compare commits
76 Commits
vue3-remov
...
fix-duplic
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8ebeeaa755 | ||
|
|
ce81c89b03 | ||
|
|
1e59511d8d | ||
|
|
0ed8b21b3c | ||
|
|
6f4f59a976 | ||
|
|
f80d7a5e79 | ||
|
|
e3843f9808 | ||
|
|
1ec7f1a971 | ||
|
|
18eea3584e | ||
|
|
844d492c8d | ||
|
|
840e9f309f | ||
|
|
fe53440ee4 | ||
|
|
162dbf25dd | ||
|
|
17de153ec8 | ||
|
|
58027c8294 | ||
|
|
79eba77b49 | ||
|
|
0efdfab232 | ||
|
|
5744944957 | ||
|
|
1c1e3e944e | ||
|
|
85bb603103 | ||
|
|
90f10190ac | ||
|
|
ab3b2aa23c | ||
|
|
b9c0d454d5 | ||
|
|
438825530c | ||
|
|
c346c3cdf8 | ||
|
|
f1da8b30a4 | ||
|
|
8229d40981 | ||
|
|
244d61c783 | ||
|
|
879e59c003 | ||
|
|
4741817594 | ||
|
|
af99211d6b | ||
|
|
b120ce868d | ||
|
|
f0ea3f3ce5 | ||
|
|
2f0caac403 | ||
|
|
cc93386da6 | ||
|
|
5573a8bb1a | ||
|
|
c2e2e73b88 | ||
|
|
e509ac77d4 | ||
|
|
909af7e1bb | ||
|
|
6828144815 | ||
|
|
1d9382429e | ||
|
|
f68f7b54d6 | ||
|
|
dd4da2dd34 | ||
|
|
327bfff315 | ||
|
|
0b6c492c75 | ||
|
|
bbe1b37dfe | ||
|
|
3b5bf56049 | ||
|
|
97ab42ad5c | ||
|
|
42d3e54841 | ||
|
|
8dd62dd8d9 | ||
|
|
160900f2bb | ||
|
|
020107d3f4 | ||
|
|
68fb689df9 | ||
|
|
97d8018cd1 | ||
|
|
d666cba097 | ||
|
|
a8c337eb07 | ||
|
|
a3a46012a4 | ||
|
|
1aa7105ceb | ||
|
|
a042a4b076 | ||
|
|
d0f992ecbb | ||
|
|
fc245759a3 | ||
|
|
60bba3332b | ||
|
|
c93e07e0bd | ||
|
|
9e6975b22b | ||
|
|
979f9b2c53 | ||
|
|
307bdf5e68 | ||
|
|
4380533a66 | ||
|
|
3a1fbb90c3 | ||
|
|
dd64e0c73d | ||
|
|
8a9751ac6b | ||
|
|
c16f26d8d2 | ||
|
|
c7edec8f6e | ||
|
|
a6de59fe9c | ||
|
|
8c891c7f57 | ||
|
|
b73c2becda | ||
|
|
26861c890d |
2
.github/workflows/appstore-build-publish.yml
vendored
2
.github/workflows/appstore-build-publish.yml
vendored
@@ -173,7 +173,7 @@ jobs:
|
||||
tar -zcvf ${{ env.APP_NAME }}.tar.gz ${{ env.APP_NAME }}
|
||||
|
||||
- name: Attach tarball to github release
|
||||
uses: svenstaro/upload-release-action@04733e069f2d7f7f0b4aebc4fbdbce8613b03ccd # v2
|
||||
uses: svenstaro/upload-release-action@81c65b7cd4de9b2570615ce3aad67a41de5b1a13 # v2
|
||||
id: attach_to_release
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
2
.github/workflows/npm-audit-fix.yml
vendored
2
.github/workflows/npm-audit-fix.yml
vendored
@@ -24,7 +24,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
branches: ['main', 'master', 'stable31', 'stable30', 'stable29']
|
||||
branches: ['main', 'master', 'stable31', 'stable30']
|
||||
|
||||
name: npm-audit-fix-${{ matrix.branches }}
|
||||
|
||||
|
||||
2
.github/workflows/update-nextcloud-ocp.yml
vendored
2
.github/workflows/update-nextcloud-ocp.yml
vendored
@@ -23,7 +23,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
branches: ['main', 'master', 'stable31', 'stable30', 'stable29']
|
||||
branches: ['main', 'master', 'stable31', 'stable30']
|
||||
|
||||
name: update-nextcloud-ocp-${{ matrix.branches }}
|
||||
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
<command>OCA\Deck\Command\UserExport</command>
|
||||
<command>OCA\Deck\Command\BoardImport</command>
|
||||
<command>OCA\Deck\Command\TransferOwnership</command>
|
||||
<command>OCA\Deck\Command\CalendarToggle</command>
|
||||
</commands>
|
||||
<activity>
|
||||
<settings>
|
||||
|
||||
20
composer.lock
generated
20
composer.lock
generated
@@ -8,16 +8,16 @@
|
||||
"packages": [
|
||||
{
|
||||
"name": "justinrainbow/json-schema",
|
||||
"version": "6.4.1",
|
||||
"version": "6.4.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/jsonrainbow/json-schema.git",
|
||||
"reference": "35d262c94959571e8736db1e5c9bc36ab94ae900"
|
||||
"reference": "ce1fd2d47799bb60668643bc6220f6278a4c1d02"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/35d262c94959571e8736db1e5c9bc36ab94ae900",
|
||||
"reference": "35d262c94959571e8736db1e5c9bc36ab94ae900",
|
||||
"url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/ce1fd2d47799bb60668643bc6220f6278a4c1d02",
|
||||
"reference": "ce1fd2d47799bb60668643bc6220f6278a4c1d02",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -77,9 +77,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/jsonrainbow/json-schema/issues",
|
||||
"source": "https://github.com/jsonrainbow/json-schema/tree/6.4.1"
|
||||
"source": "https://github.com/jsonrainbow/json-schema/tree/6.4.2"
|
||||
},
|
||||
"time": "2025-04-04T13:08:07+00:00"
|
||||
"time": "2025-06-03T18:27:04+00:00"
|
||||
},
|
||||
{
|
||||
"name": "marc-mabe/php-enum",
|
||||
@@ -380,12 +380,12 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nextcloud-deps/ocp.git",
|
||||
"reference": "97d7aa6e535670437a178084eea91a42998fef5c"
|
||||
"reference": "c2c75ad8fdc54cbc6341764b5a2a8ecf860e6160"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nextcloud-deps/ocp/zipball/97d7aa6e535670437a178084eea91a42998fef5c",
|
||||
"reference": "97d7aa6e535670437a178084eea91a42998fef5c",
|
||||
"url": "https://api.github.com/repos/nextcloud-deps/ocp/zipball/c2c75ad8fdc54cbc6341764b5a2a8ecf860e6160",
|
||||
"reference": "c2c75ad8fdc54cbc6341764b5a2a8ecf860e6160",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -421,7 +421,7 @@
|
||||
"issues": "https://github.com/nextcloud-deps/ocp/issues",
|
||||
"source": "https://github.com/nextcloud-deps/ocp/tree/master"
|
||||
},
|
||||
"time": "2025-06-13T00:53:13+00:00"
|
||||
"time": "2025-08-10T01:01:23+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nikic/php-parser",
|
||||
|
||||
@@ -84,7 +84,7 @@ describe('Card', function () {
|
||||
cy.get('.modal-mask.card-selector .multiselect-list').should('be.visible').click()
|
||||
cy.get('.vs__dropdown-menu span[title="TestList"]').should('be.visible').click()
|
||||
|
||||
cy.get('.modal-mask.card-selector button.button-vue--primary').contains('Create card').should('be.visible').click()
|
||||
cy.get('.modal-mask.card-selector button.button-vue--vue-primary').should('be.visible').click()
|
||||
cy.wait('@save', { timeout: 7000 })
|
||||
|
||||
cy.reload()
|
||||
@@ -187,7 +187,7 @@ describe('Card', function () {
|
||||
cy.get('.file-picker__main').should('be.visible')
|
||||
cy.get('.file-picker__main [data-filename="welcome.txt"]', { timeout: 30000 }).should('be.visible')
|
||||
.click()
|
||||
cy.get('.dialog__actions button.button-vue--primary').click()
|
||||
cy.get('.dialog__actions button.button-vue--vue-primary').click()
|
||||
cy.get('.attachment-list .filename').contains('welcome')
|
||||
cy.get('.attachment-list .filename .extension').contains('txt')
|
||||
})
|
||||
@@ -302,10 +302,11 @@ describe('Card', function () {
|
||||
.first().click()
|
||||
cy.get(`.card:contains("${newCardTitle}")`).should('be.visible').click()
|
||||
|
||||
cy.get('#app-sidebar-vue [data-test="tag-selector"] .vs__dropdown-toggle .vs__actions').should('be.visible').click()
|
||||
// Add delay to ensure the events are bound
|
||||
cy.wait(1000)
|
||||
|
||||
cy.get('#app-sidebar-vue [data-test="tag-selector"] .vs__dropdown-toggle').should('be.visible').click()
|
||||
cy.get('.vs__dropdown-menu .tag:contains("Action needed")').should('be.visible').click()
|
||||
cy.get('.vs__dropdown-menu .tag:contains("Later")').should('not.exist')
|
||||
cy.get('#app-sidebar-vue [data-test="tag-selector"] .vs__dropdown-toggle .vs__actions').should('be.visible').click()
|
||||
cy.get('.vs__dropdown-menu .tag:contains("Later")').should('be.visible').click()
|
||||
|
||||
cy.get('.vs__selected .tag:contains("Action needed")').should('be.visible')
|
||||
|
||||
@@ -27,7 +27,7 @@ describe('Deck dashboard', function() {
|
||||
|
||||
const defaultBoard = 'Welcome to Nextcloud Deck!'
|
||||
|
||||
cy.get('#deck-navigation-all')
|
||||
cy.get('.app-navigation-entry-wrapper[icon=icon-deck]')
|
||||
.find('ul.app-navigation-entry__children .app-navigation-entry:contains(' + defaultBoard + ')')
|
||||
.first()
|
||||
.contains(defaultBoard)
|
||||
|
||||
@@ -93,7 +93,7 @@ Cypress.Commands.add('createExampleBoard', ({ user, board }) => {
|
||||
})
|
||||
|
||||
Cypress.Commands.add('getNavigationEntry', (boardTitle) => {
|
||||
return cy.get('#deck-navigation-all')
|
||||
return cy.get('.app-navigation-entry-wrapper[icon=icon-deck]')
|
||||
.find('ul.app-navigation-entry__children .app-navigation-entry:contains(' + boardTitle + ')')
|
||||
.find('a.app-navigation-entry-link')
|
||||
})
|
||||
@@ -102,7 +102,11 @@ Cypress.Commands.add('shareBoardWithUi', (query, userId=query) => {
|
||||
cy.intercept({ method: 'GET', url: `**/ocs/v2.php/apps/files_sharing/api/v1/sharees?search=${query}*` }).as('fetchRecipients')
|
||||
cy.get('[aria-label="Open details"]').click()
|
||||
cy.get('.app-sidebar').should('be.visible')
|
||||
cy.get('.select input').type(`${query}`)
|
||||
|
||||
// Add delay to ensure the events are bound
|
||||
cy.wait(1000)
|
||||
|
||||
cy.get('.select input').click().type(`${query}`)
|
||||
cy.wait('@fetchRecipients', { timeout: 7000 })
|
||||
|
||||
cy.get('.vs__dropdown-menu .option').first().contains(query)
|
||||
|
||||
40
l10n/be.js
Normal file
40
l10n/be.js
Normal file
@@ -0,0 +1,40 @@
|
||||
OC.L10N.register(
|
||||
"deck",
|
||||
{
|
||||
"Missing a temporary folder" : "Адсутнічае часовая папка",
|
||||
"Could not write file to disk" : "Не ўдалося запісаць файл на дыск",
|
||||
"A PHP extension stopped the file upload" : "Пашырэнне PHP спыніла запампоўванне файла",
|
||||
"copy" : "копія",
|
||||
"Done" : "Гатова",
|
||||
"File" : "Файл",
|
||||
"Cancel" : "Скасаваць",
|
||||
"Active filters" : "Актыўныя фільтры",
|
||||
"Apply filter" : "Ужыць фільтр",
|
||||
"Open" : "Адкрыць",
|
||||
"Clear filter" : "Ачысціць фільтр",
|
||||
"Tags" : "Тэгі",
|
||||
"Activity" : "Актыўнасць",
|
||||
"Can edit" : "Можа рэдагаваць",
|
||||
"Can share" : "Можа абагульваць",
|
||||
"Owner" : "Уладальнік",
|
||||
"Delete" : "Выдаліць",
|
||||
"Edit" : "Рэдагаваць",
|
||||
"Download" : "Спампаваць",
|
||||
"Modified" : "Зменены",
|
||||
"Save" : "Захаваць",
|
||||
"Created:" : "Створана:",
|
||||
"Reply" : "Адказаць",
|
||||
"Open link" : "Адкрыць спасылку",
|
||||
"seconds ago" : "с таму",
|
||||
"Keyboard shortcuts" : "Спалучэнні клавіш",
|
||||
"Keyboard shortcut" : "Спалучэнне клавіш",
|
||||
"Action" : "Дзеянне",
|
||||
"Search" : "Пошук",
|
||||
"Shared with you" : "Абагулена з вамі",
|
||||
"An error occurred" : "Узнікла памылка",
|
||||
"No notifications" : "Няма апавяшчэнняў",
|
||||
"Today" : "Сёння",
|
||||
"Close" : "Закрыць",
|
||||
"Share" : "Абагуліць"
|
||||
},
|
||||
"nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);");
|
||||
38
l10n/be.json
Normal file
38
l10n/be.json
Normal file
@@ -0,0 +1,38 @@
|
||||
{ "translations": {
|
||||
"Missing a temporary folder" : "Адсутнічае часовая папка",
|
||||
"Could not write file to disk" : "Не ўдалося запісаць файл на дыск",
|
||||
"A PHP extension stopped the file upload" : "Пашырэнне PHP спыніла запампоўванне файла",
|
||||
"copy" : "копія",
|
||||
"Done" : "Гатова",
|
||||
"File" : "Файл",
|
||||
"Cancel" : "Скасаваць",
|
||||
"Active filters" : "Актыўныя фільтры",
|
||||
"Apply filter" : "Ужыць фільтр",
|
||||
"Open" : "Адкрыць",
|
||||
"Clear filter" : "Ачысціць фільтр",
|
||||
"Tags" : "Тэгі",
|
||||
"Activity" : "Актыўнасць",
|
||||
"Can edit" : "Можа рэдагаваць",
|
||||
"Can share" : "Можа абагульваць",
|
||||
"Owner" : "Уладальнік",
|
||||
"Delete" : "Выдаліць",
|
||||
"Edit" : "Рэдагаваць",
|
||||
"Download" : "Спампаваць",
|
||||
"Modified" : "Зменены",
|
||||
"Save" : "Захаваць",
|
||||
"Created:" : "Створана:",
|
||||
"Reply" : "Адказаць",
|
||||
"Open link" : "Адкрыць спасылку",
|
||||
"seconds ago" : "с таму",
|
||||
"Keyboard shortcuts" : "Спалучэнні клавіш",
|
||||
"Keyboard shortcut" : "Спалучэнне клавіш",
|
||||
"Action" : "Дзеянне",
|
||||
"Search" : "Пошук",
|
||||
"Shared with you" : "Абагулена з вамі",
|
||||
"An error occurred" : "Узнікла памылка",
|
||||
"No notifications" : "Няма апавяшчэнняў",
|
||||
"Today" : "Сёння",
|
||||
"Close" : "Закрыць",
|
||||
"Share" : "Абагуліць"
|
||||
},"pluralForm" :"nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);"
|
||||
}
|
||||
66
l10n/es.js
66
l10n/es.js
@@ -37,9 +37,9 @@ OC.L10N.register(
|
||||
"{user} has archived card {card} in list {stack} on board {board}" : "{user} ha archivado la tarjeta {card} en la lista {stack} del tablero {board}",
|
||||
"You have unarchived card {card} in list {stack} on board {board}" : "Has desarchivado la tarjeta {card} en la lista {stack} del tablero {board}",
|
||||
"{user} has unarchived card {card} in list {stack} on board {board}" : "{user} ha desarchivado la tarjeta {card} en la lista {stack} del tablero {board}",
|
||||
"You have marked the card {card} as done in list {stack} on board {board}" : "Has marcado la tarjeta {card} como completada en la lista {stack} del tablero {board}",
|
||||
"You have marked the card {card} as done in list {stack} on board {board}" : "Ud. ha marcado la tarjeta {card} como completada en la lista {stack} del tablero {board}",
|
||||
"{user} has marked card {card} as done in list {stack} on board {board}" : "{user} ha marcado la tarjeta {card} como completada en la lista {stack} del tablero {board}",
|
||||
"You have marked the card {card} as undone in list {stack} on board {board}" : "Has marcado la tarjeta {card} como no completada en la lista {stack} del tablero {board}",
|
||||
"You have marked the card {card} as undone in list {stack} on board {board}" : "Ud. ha marcado la tarjeta {card} como no completada en la lista {stack} del tablero {board}",
|
||||
"{user} has marked the card {card} as undone in list {stack} on board {board}" : "{user} ha marcado la tarjeta {card} como no completada en la lista {stack} del tablero {board}",
|
||||
"You have removed the due date of card {card}" : "Has eliminado la fecha de vencimiento de {card}",
|
||||
"{user} has removed the due date of card {card}" : "{user} ha eliminado la fecha de vencimiento de {card}",
|
||||
@@ -81,10 +81,14 @@ OC.L10N.register(
|
||||
"Could not write file to disk" : "No se ha podido escribir el archivo al disco",
|
||||
"A PHP extension stopped the file upload" : "Una extensión de PHP ha detenido la subida del archivo",
|
||||
"No file uploaded or file size exceeds maximum of %s" : "No se ha subido ningún archivo, o el tamaño del archivo excede el máximo de %s",
|
||||
"Invalid file type. Only JSON files are allowed." : "Tipo de archivo inválido. Solo se permiten archivos JSON",
|
||||
"Invalid JSON data" : "Datos JSON inválidos",
|
||||
"Failed to import board" : "Fallo al importar tablero",
|
||||
"Cards due today" : "Tarjetas que vencen hoy",
|
||||
"Cards due tomorrow" : "Tarjetas que vencen mañana",
|
||||
"Upcoming cards" : "Próximas tarjetas",
|
||||
"Load more" : "Cargar más",
|
||||
"Welcome to Nextcloud Deck!" : "¡Bienvenido a Nextcloud Deck!",
|
||||
"The card \"%s\" on \"%s\" has been assigned to you by %s." : "La tarjeta \"%s\" en \"%s\" te ha sido asignada por %s.",
|
||||
"{user} has assigned the card {deck-card} on {deck-board} to you." : "{user} te ha asigando la tarjeta {deck-card} de {deck-board} a ti.",
|
||||
"The card \"%s\" on \"%s\" has reached its due date." : "La tarjeta \"%s\" en \"%s\" ha alcanzado su fecha límite.",
|
||||
@@ -94,7 +98,7 @@ OC.L10N.register(
|
||||
"The board \"%s\" has been shared with you by %s." : "El tablero \"%s\" ha sido compartido contigo por %s.",
|
||||
"{user} has shared {deck-board} with you." : "{user} ha compartido {deck-board} contigo.",
|
||||
"Deck board" : "Tablero Deck",
|
||||
"Owned by %1$s" : "Apropiado por %1$s",
|
||||
"Owned by %1$s" : "Propiedad de %1$s",
|
||||
"Deck boards, cards and comments" : "Tableros Deck, tarjetas y comentarios",
|
||||
"From %1$s, in %2$s/%3$s, owned by %4$s" : "De %1$s, en %2$s/%3$s, propiedad de %4$s",
|
||||
"Create a new deck card" : "Crear una nueva tarjeta de tablero",
|
||||
@@ -107,17 +111,25 @@ OC.L10N.register(
|
||||
"Action needed" : "Acción necesaria",
|
||||
"Later" : "Después",
|
||||
"copy" : "copiar",
|
||||
"Read more inside" : "Lea más, adentro",
|
||||
"Custom lists - click to rename!" : "Listas personalizadas - ¡Haga clic para renombrar!",
|
||||
"To Do" : "Por hacer",
|
||||
"In Progress" : "En progreso",
|
||||
"Done" : "Hecho",
|
||||
"This comment has more than %s characters.\nAdded as an attachment to the card with name %s.\nAccessible on URL: %s." : "Este comentario tiene más de %s caracteres.\nAñadido como adjunto a la tarjeta con el nombre %s.\nAccesible en la URL: %s.",
|
||||
"1. Open to learn more about boards and cards" : "1. Abra aquí para aprender más sobre los tableros y las tarjetas",
|
||||
"2. Drag cards left and right, up and down" : "2. Arrastre las tarjetas a la izquierda y derecha, arriba y abajo",
|
||||
"3. Apply rich formatting and link content" : "3. Aplique formato enriquecido y contenido a los enlaces",
|
||||
"4. Share, comment and collaborate!" : "4. ¡Comparta, comente y colabore!",
|
||||
"Create your first card!" : "¡Cree su primera tarjeta!",
|
||||
"This comment has more than %s characters.\nAdded as an attachment to the card with name %s.\nAccessible on URL: %s." : "Este comentario tiene más de %s caracteres.\nSe ha añadido como adjunto a la tarjeta con el nombre %s.\nAccesible en la URL: %s.",
|
||||
"Attachments" : "Adjuntos",
|
||||
"File" : "Archivo",
|
||||
"date" : "fecha",
|
||||
"Card not found" : "Tarjeta no encontrada",
|
||||
"Path is already shared with this card" : "La ruta ya se ha compartido con esta tarjeta",
|
||||
"Invalid date, date format must be YYYY-MM-DD" : "Fecha no válida, el formato de las fechas debe ser AAAA-MM-DD",
|
||||
"Personal planning and team project organization" : "Planificación personal y organización de proyecto de equipo",
|
||||
"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 es una herramienta de organización de estilo kanban dirigida a la planificación personal y la organización de proyectos para equipos integrados con Nextcloud.\n\n\n- 📥 Agrega tus tareas a las tarjetas y ordénalas.\n- 📄 Escriba notas adicionales\n- 🔖 Asignar etiquetas para una organización mejor\n- 👥 Comparte con tu equipo, amigos o familia.\n- 📎 Adjuntar archivos e incrustarlos en su descripción\n- 💬 Discuta con su equipo usando comentarios.\n- ⚡ Mantenga un registro de los cambios en el flujo de actividad\n- 🚀 Organiza tu proyecto",
|
||||
"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 es una herramienta de organización de estilo kanban dirigida a la planificación personal y la organización de proyectos para equipos, integrada a Nextcloud.\n\n\n- 📥 Agregue sus tareas a las tarjetas y póngalas en orden.\n- 📄 Escriba notas adicionales en Markdown\n- 🔖 Asigne etiquetas para una organización mejor\n- 👥 Comparta con su equipo, amigos o familia.\n- 📎 Adjunte archivos e incruste los mismos en su descripción Markdown\n- 💬 Discuta con su equipo usando comentarios.\n- ⚡ Mantenga un registro de los cambios en el flujo de actividad\n- 🚀 Organice su proyecto",
|
||||
"Add board" : "Añadir tablero",
|
||||
"Card details" : "Detalles de la tarjeta",
|
||||
"Select the board to link to a project" : "Selecciona el tablero que enlazar a un proyecto",
|
||||
@@ -165,8 +177,8 @@ OC.L10N.register(
|
||||
"Hide archived cards" : "Ocultar tarjetas archivadas",
|
||||
"Show archived cards" : "Mostrar tarjetas archivadas",
|
||||
"Toggle compact mode" : "Mostrar/ocultar modo compacto",
|
||||
"Hide card cover images" : "Ocultar la imagen principal de las tarjetas",
|
||||
"Show card cover images" : "Mostrar la imagen principal de las tarjetas",
|
||||
"Hide card cover images" : "Ocultar la imagen de portada de las tarjetas",
|
||||
"Show card cover images" : "Mostrar la imagen de portada de las tarjetas",
|
||||
"Open details" : "Abrir detalles",
|
||||
"Details" : "Detalles",
|
||||
"Currently present people" : "Personas presentes actualmente",
|
||||
@@ -181,11 +193,11 @@ OC.L10N.register(
|
||||
"Undo" : "Deshacer",
|
||||
"Deleted cards" : "Cartas eliminadas",
|
||||
"Failed to create share with {displayName}" : "Fallo al crear el recurso compartido denominado {displayName}",
|
||||
"Are you sure you want to transfer the board {title} to {user}?" : "¿Estás seguro de que quieres transferir el tablero {título} a {usuario}?",
|
||||
"Transfer the board." : "Transfiere el tablero.",
|
||||
"Are you sure you want to transfer the board {title} to {user}?" : "¿Está seguro de que quiere transferir el tablero {title} a {user}?",
|
||||
"Transfer the board." : "Transfiera el tablero.",
|
||||
"Transfer" : "Transferir",
|
||||
"The board has been transferred to {user}" : "El tablero ha sido transferido a {usuario}",
|
||||
"Failed to transfer the board to {user}" : "Failed to transfer the board to {user}",
|
||||
"The board has been transferred to {user}" : "El tablero ha sido transferido a {user}",
|
||||
"Failed to transfer the board to {user}" : "Fallo al transferir el tablero a {user}",
|
||||
"Share board with a user, group or team …" : "Compartir tablero con un usuario, grupo o equipo …",
|
||||
"Searching for users, groups and teams …" : "Buscando usuarios, grupos y equipos …",
|
||||
"No participants found" : "No se encontraron participantes",
|
||||
@@ -218,7 +230,7 @@ OC.L10N.register(
|
||||
"Invalid path selected" : "Ruta seleccionada no válida",
|
||||
"Upload new files" : "Subir nuevos archivos",
|
||||
"Share from Files" : "Compartir desde Archivos",
|
||||
"Pending share" : "Pendiente de compartir",
|
||||
"Pending share" : "Recurso compartido pendiente",
|
||||
"Add this attachment" : "Añadir este adjunto",
|
||||
"Show in Files" : "Mostrar en Archivos",
|
||||
"Download" : "Descargar",
|
||||
@@ -228,6 +240,7 @@ OC.L10N.register(
|
||||
"Modified" : "Modificado",
|
||||
"Created" : "Creado",
|
||||
"The title cannot be empty." : "El título no puede estar vacío.",
|
||||
"Cannot close unsaved card!" : "¡No se puede cerrar esta tarjeta no guardada!",
|
||||
"Open in sidebar view" : "Abrir en vista de barra lateral",
|
||||
"Open in bigger view" : "Abrir en vista más grande",
|
||||
"Comments" : "Comentarios",
|
||||
@@ -242,6 +255,7 @@ OC.L10N.register(
|
||||
"Reply" : "Responder",
|
||||
"Update" : "Actualizar",
|
||||
"Write a description …" : "Escribe una descripción...",
|
||||
"Could not save description" : "No se pudo guardar la descripción",
|
||||
"Description" : "Descripción",
|
||||
"(Unsaved)" : "(Sin salvar)",
|
||||
"(Saving…)" : "(Guardando...)",
|
||||
@@ -259,12 +273,12 @@ OC.L10N.register(
|
||||
"Set due date for this weekend" : "Establecer este fin de semana como fecha de vencimiento",
|
||||
"Next week – {timeLocale}" : "Próxima semana – {timeLocale}",
|
||||
"Set due date for next week" : "Establecer la próxima semana como fecha de vencimiento",
|
||||
"Assign a due date to this card…" : "Asignar una fecha de caducidad a esta tarjeta…",
|
||||
"Assign a due date to this card…" : "Asignar una fecha de vencimiento a esta tarjeta…",
|
||||
"Set a due date" : "Fijar una fecha límite",
|
||||
"Add due date" : "Añadir fecha de vencimiento",
|
||||
"Choose a date" : "Elija una fecha",
|
||||
"Remove due date" : "Eliminar fecha límite",
|
||||
"Mark as done" : "Marcar como hecho",
|
||||
"Mark as done" : "Marcar como completado",
|
||||
"Due at:" : "Vence el:",
|
||||
"Not done" : "No está finalizado",
|
||||
"Unarchive card" : "Desarchivar tarjeta",
|
||||
@@ -328,6 +342,7 @@ OC.L10N.register(
|
||||
"An error occurred" : "Ocurrió un error",
|
||||
"Are you sure you want to delete the board {title}? This will delete all the data of this board including archived cards." : "¿Está seguro de querer eliminar el tablero {title}? Esto eliminará todos los datos del tablero incluyendo las tarjetas archivadas.",
|
||||
"Delete the board?" : "¿Borrar el tablero?",
|
||||
"Exporting board..." : "Exportando tablero...",
|
||||
"Board details" : "Detalles del tablero",
|
||||
"Edit board" : "Editar tablero",
|
||||
"Clone board" : "Clonar tablero",
|
||||
@@ -340,16 +355,22 @@ OC.L10N.register(
|
||||
"Assigned cards" : "Tarjetas asignadas",
|
||||
"No notifications" : "No hay notificaciones",
|
||||
"Delete board" : "Eliminar tablero",
|
||||
"Importing board..." : "Importando tablero...",
|
||||
"Board imported successfully" : "Se importó el tablero exitosamente",
|
||||
"Import board" : "Importar tablero",
|
||||
"Clone {boardTitle}" : "Clonar {boardTitle}",
|
||||
"Clone cards" : "Clonar tarjetas",
|
||||
"Clone assignments" : "Clonar asignaciones",
|
||||
"Clone labels" : "Clonar etiquetas",
|
||||
"Clone due dates" : "Clonar fechas límite",
|
||||
"Clone due dates" : "Clonar fechas de vencimiento",
|
||||
"Advanced options" : "Opciones avanzadas",
|
||||
"Move all cards to the first list" : "Mover todas las tarjetas a la primera lista",
|
||||
"Restore archived cards" : "Restaurar tarjetas archivadas",
|
||||
"Clone" : "Clonar",
|
||||
"Export {boardTitle}" : "Exportar {boardTitle}",
|
||||
"Export as JSON" : "Exportar como JSON",
|
||||
"Export as CSV" : "Exportar como CSV",
|
||||
"Note: Only the JSON format is supported for importing back into the Deck app." : "Nota: Solo el formato JSON es soportar al importar de vuelta en la app Deck.",
|
||||
"Export" : "Exportar",
|
||||
"Loading filtered view" : "Cargando vista filtrada",
|
||||
"Today" : "Hoy",
|
||||
@@ -357,17 +378,17 @@ OC.L10N.register(
|
||||
"No due" : "Sin finalizar",
|
||||
"Search for {searchQuery} in all boards" : "Buscar {searchQuery} en todos los tableros",
|
||||
"No results found" : "No se encontraron resultados",
|
||||
"Deck board {name}\n* Last modified on {lastMod}" : "Tablero Deck {name}\n* Última modificación en {lastMod}",
|
||||
"* Created on {created}\n* Last modified on {lastMod}\n* {nbAttachments} attachments\n* {nbComments} comments" : "* Creada en {created}\n* Ultima moficiación en {lastMod}\n* {nbAttachments} adjuntos\n* {nbComments} comentarios",
|
||||
"Deck board {name}\n* Last modified on {lastMod}" : "Tablero Deck {name}\n* Se modificó por última vez el {lastMod}",
|
||||
"* Created on {created}\n* Last modified on {lastMod}\n* {nbAttachments} attachments\n* {nbComments} comments" : "* Creado en {created}\n* Se modificó por última vez el {lastMod}\n* {nbAttachments} adjuntos\n* {nbComments} comentarios",
|
||||
"{nbCards} cards" : "{nbCards} tarjetas",
|
||||
"Due on {date}" : "Vence en {date}",
|
||||
"{stack} in {board}" : "{stack} en {board}",
|
||||
"Click to expand description" : "Pulse para expandir la descripción",
|
||||
"Click to expand comment" : "Pulse para expandir el comentario",
|
||||
"Click to expand description" : "Haga clic para expandir la descripción",
|
||||
"Click to expand comment" : "Haga clic para expandir el comentario",
|
||||
"Create card" : "Crear tarjeta",
|
||||
"Create a new card" : "Crear una nueva tarjeta",
|
||||
"Create a new card" : "Crear una tarjeta nueva",
|
||||
"Card title" : "Título de la tarjeta",
|
||||
"Creating the new card …" : "Creando una nueva tarjeta …",
|
||||
"Creating the new card …" : "Creando una tarjeta nueva …",
|
||||
"Card \"{card}\" was added to \"{board}\"" : "La tarjeta \"{card}\" fue añadida a \"{board}\"",
|
||||
"Open card" : "Abrir tarjeta",
|
||||
"Close" : "Cerrar",
|
||||
@@ -383,7 +404,8 @@ OC.L10N.register(
|
||||
"Something went wrong" : "Algo ha ido mal",
|
||||
"Failed to upload {name}" : "Error al subir {name}",
|
||||
"Maximum file size of {size} exceeded" : "Tamaño máximo de archivo de {size} excedido",
|
||||
"Due date" : "Fecha de fin",
|
||||
"Assigned users" : "Usuarios asignados",
|
||||
"Due date" : "Fecha de vencimiento",
|
||||
"Error creating the share" : "Error creando el recurso compartido",
|
||||
"Share with a Deck card" : "Compartir con una tarjeta de Deck",
|
||||
"Share {file} with a Deck card" : "Compartir {file} con una tarjeta de Deck",
|
||||
|
||||
66
l10n/es.json
66
l10n/es.json
@@ -35,9 +35,9 @@
|
||||
"{user} has archived card {card} in list {stack} on board {board}" : "{user} ha archivado la tarjeta {card} en la lista {stack} del tablero {board}",
|
||||
"You have unarchived card {card} in list {stack} on board {board}" : "Has desarchivado la tarjeta {card} en la lista {stack} del tablero {board}",
|
||||
"{user} has unarchived card {card} in list {stack} on board {board}" : "{user} ha desarchivado la tarjeta {card} en la lista {stack} del tablero {board}",
|
||||
"You have marked the card {card} as done in list {stack} on board {board}" : "Has marcado la tarjeta {card} como completada en la lista {stack} del tablero {board}",
|
||||
"You have marked the card {card} as done in list {stack} on board {board}" : "Ud. ha marcado la tarjeta {card} como completada en la lista {stack} del tablero {board}",
|
||||
"{user} has marked card {card} as done in list {stack} on board {board}" : "{user} ha marcado la tarjeta {card} como completada en la lista {stack} del tablero {board}",
|
||||
"You have marked the card {card} as undone in list {stack} on board {board}" : "Has marcado la tarjeta {card} como no completada en la lista {stack} del tablero {board}",
|
||||
"You have marked the card {card} as undone in list {stack} on board {board}" : "Ud. ha marcado la tarjeta {card} como no completada en la lista {stack} del tablero {board}",
|
||||
"{user} has marked the card {card} as undone in list {stack} on board {board}" : "{user} ha marcado la tarjeta {card} como no completada en la lista {stack} del tablero {board}",
|
||||
"You have removed the due date of card {card}" : "Has eliminado la fecha de vencimiento de {card}",
|
||||
"{user} has removed the due date of card {card}" : "{user} ha eliminado la fecha de vencimiento de {card}",
|
||||
@@ -79,10 +79,14 @@
|
||||
"Could not write file to disk" : "No se ha podido escribir el archivo al disco",
|
||||
"A PHP extension stopped the file upload" : "Una extensión de PHP ha detenido la subida del archivo",
|
||||
"No file uploaded or file size exceeds maximum of %s" : "No se ha subido ningún archivo, o el tamaño del archivo excede el máximo de %s",
|
||||
"Invalid file type. Only JSON files are allowed." : "Tipo de archivo inválido. Solo se permiten archivos JSON",
|
||||
"Invalid JSON data" : "Datos JSON inválidos",
|
||||
"Failed to import board" : "Fallo al importar tablero",
|
||||
"Cards due today" : "Tarjetas que vencen hoy",
|
||||
"Cards due tomorrow" : "Tarjetas que vencen mañana",
|
||||
"Upcoming cards" : "Próximas tarjetas",
|
||||
"Load more" : "Cargar más",
|
||||
"Welcome to Nextcloud Deck!" : "¡Bienvenido a Nextcloud Deck!",
|
||||
"The card \"%s\" on \"%s\" has been assigned to you by %s." : "La tarjeta \"%s\" en \"%s\" te ha sido asignada por %s.",
|
||||
"{user} has assigned the card {deck-card} on {deck-board} to you." : "{user} te ha asigando la tarjeta {deck-card} de {deck-board} a ti.",
|
||||
"The card \"%s\" on \"%s\" has reached its due date." : "La tarjeta \"%s\" en \"%s\" ha alcanzado su fecha límite.",
|
||||
@@ -92,7 +96,7 @@
|
||||
"The board \"%s\" has been shared with you by %s." : "El tablero \"%s\" ha sido compartido contigo por %s.",
|
||||
"{user} has shared {deck-board} with you." : "{user} ha compartido {deck-board} contigo.",
|
||||
"Deck board" : "Tablero Deck",
|
||||
"Owned by %1$s" : "Apropiado por %1$s",
|
||||
"Owned by %1$s" : "Propiedad de %1$s",
|
||||
"Deck boards, cards and comments" : "Tableros Deck, tarjetas y comentarios",
|
||||
"From %1$s, in %2$s/%3$s, owned by %4$s" : "De %1$s, en %2$s/%3$s, propiedad de %4$s",
|
||||
"Create a new deck card" : "Crear una nueva tarjeta de tablero",
|
||||
@@ -105,17 +109,25 @@
|
||||
"Action needed" : "Acción necesaria",
|
||||
"Later" : "Después",
|
||||
"copy" : "copiar",
|
||||
"Read more inside" : "Lea más, adentro",
|
||||
"Custom lists - click to rename!" : "Listas personalizadas - ¡Haga clic para renombrar!",
|
||||
"To Do" : "Por hacer",
|
||||
"In Progress" : "En progreso",
|
||||
"Done" : "Hecho",
|
||||
"This comment has more than %s characters.\nAdded as an attachment to the card with name %s.\nAccessible on URL: %s." : "Este comentario tiene más de %s caracteres.\nAñadido como adjunto a la tarjeta con el nombre %s.\nAccesible en la URL: %s.",
|
||||
"1. Open to learn more about boards and cards" : "1. Abra aquí para aprender más sobre los tableros y las tarjetas",
|
||||
"2. Drag cards left and right, up and down" : "2. Arrastre las tarjetas a la izquierda y derecha, arriba y abajo",
|
||||
"3. Apply rich formatting and link content" : "3. Aplique formato enriquecido y contenido a los enlaces",
|
||||
"4. Share, comment and collaborate!" : "4. ¡Comparta, comente y colabore!",
|
||||
"Create your first card!" : "¡Cree su primera tarjeta!",
|
||||
"This comment has more than %s characters.\nAdded as an attachment to the card with name %s.\nAccessible on URL: %s." : "Este comentario tiene más de %s caracteres.\nSe ha añadido como adjunto a la tarjeta con el nombre %s.\nAccesible en la URL: %s.",
|
||||
"Attachments" : "Adjuntos",
|
||||
"File" : "Archivo",
|
||||
"date" : "fecha",
|
||||
"Card not found" : "Tarjeta no encontrada",
|
||||
"Path is already shared with this card" : "La ruta ya se ha compartido con esta tarjeta",
|
||||
"Invalid date, date format must be YYYY-MM-DD" : "Fecha no válida, el formato de las fechas debe ser AAAA-MM-DD",
|
||||
"Personal planning and team project organization" : "Planificación personal y organización de proyecto de equipo",
|
||||
"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 es una herramienta de organización de estilo kanban dirigida a la planificación personal y la organización de proyectos para equipos integrados con Nextcloud.\n\n\n- 📥 Agrega tus tareas a las tarjetas y ordénalas.\n- 📄 Escriba notas adicionales\n- 🔖 Asignar etiquetas para una organización mejor\n- 👥 Comparte con tu equipo, amigos o familia.\n- 📎 Adjuntar archivos e incrustarlos en su descripción\n- 💬 Discuta con su equipo usando comentarios.\n- ⚡ Mantenga un registro de los cambios en el flujo de actividad\n- 🚀 Organiza tu proyecto",
|
||||
"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 es una herramienta de organización de estilo kanban dirigida a la planificación personal y la organización de proyectos para equipos, integrada a Nextcloud.\n\n\n- 📥 Agregue sus tareas a las tarjetas y póngalas en orden.\n- 📄 Escriba notas adicionales en Markdown\n- 🔖 Asigne etiquetas para una organización mejor\n- 👥 Comparta con su equipo, amigos o familia.\n- 📎 Adjunte archivos e incruste los mismos en su descripción Markdown\n- 💬 Discuta con su equipo usando comentarios.\n- ⚡ Mantenga un registro de los cambios en el flujo de actividad\n- 🚀 Organice su proyecto",
|
||||
"Add board" : "Añadir tablero",
|
||||
"Card details" : "Detalles de la tarjeta",
|
||||
"Select the board to link to a project" : "Selecciona el tablero que enlazar a un proyecto",
|
||||
@@ -163,8 +175,8 @@
|
||||
"Hide archived cards" : "Ocultar tarjetas archivadas",
|
||||
"Show archived cards" : "Mostrar tarjetas archivadas",
|
||||
"Toggle compact mode" : "Mostrar/ocultar modo compacto",
|
||||
"Hide card cover images" : "Ocultar la imagen principal de las tarjetas",
|
||||
"Show card cover images" : "Mostrar la imagen principal de las tarjetas",
|
||||
"Hide card cover images" : "Ocultar la imagen de portada de las tarjetas",
|
||||
"Show card cover images" : "Mostrar la imagen de portada de las tarjetas",
|
||||
"Open details" : "Abrir detalles",
|
||||
"Details" : "Detalles",
|
||||
"Currently present people" : "Personas presentes actualmente",
|
||||
@@ -179,11 +191,11 @@
|
||||
"Undo" : "Deshacer",
|
||||
"Deleted cards" : "Cartas eliminadas",
|
||||
"Failed to create share with {displayName}" : "Fallo al crear el recurso compartido denominado {displayName}",
|
||||
"Are you sure you want to transfer the board {title} to {user}?" : "¿Estás seguro de que quieres transferir el tablero {título} a {usuario}?",
|
||||
"Transfer the board." : "Transfiere el tablero.",
|
||||
"Are you sure you want to transfer the board {title} to {user}?" : "¿Está seguro de que quiere transferir el tablero {title} a {user}?",
|
||||
"Transfer the board." : "Transfiera el tablero.",
|
||||
"Transfer" : "Transferir",
|
||||
"The board has been transferred to {user}" : "El tablero ha sido transferido a {usuario}",
|
||||
"Failed to transfer the board to {user}" : "Failed to transfer the board to {user}",
|
||||
"The board has been transferred to {user}" : "El tablero ha sido transferido a {user}",
|
||||
"Failed to transfer the board to {user}" : "Fallo al transferir el tablero a {user}",
|
||||
"Share board with a user, group or team …" : "Compartir tablero con un usuario, grupo o equipo …",
|
||||
"Searching for users, groups and teams …" : "Buscando usuarios, grupos y equipos …",
|
||||
"No participants found" : "No se encontraron participantes",
|
||||
@@ -216,7 +228,7 @@
|
||||
"Invalid path selected" : "Ruta seleccionada no válida",
|
||||
"Upload new files" : "Subir nuevos archivos",
|
||||
"Share from Files" : "Compartir desde Archivos",
|
||||
"Pending share" : "Pendiente de compartir",
|
||||
"Pending share" : "Recurso compartido pendiente",
|
||||
"Add this attachment" : "Añadir este adjunto",
|
||||
"Show in Files" : "Mostrar en Archivos",
|
||||
"Download" : "Descargar",
|
||||
@@ -226,6 +238,7 @@
|
||||
"Modified" : "Modificado",
|
||||
"Created" : "Creado",
|
||||
"The title cannot be empty." : "El título no puede estar vacío.",
|
||||
"Cannot close unsaved card!" : "¡No se puede cerrar esta tarjeta no guardada!",
|
||||
"Open in sidebar view" : "Abrir en vista de barra lateral",
|
||||
"Open in bigger view" : "Abrir en vista más grande",
|
||||
"Comments" : "Comentarios",
|
||||
@@ -240,6 +253,7 @@
|
||||
"Reply" : "Responder",
|
||||
"Update" : "Actualizar",
|
||||
"Write a description …" : "Escribe una descripción...",
|
||||
"Could not save description" : "No se pudo guardar la descripción",
|
||||
"Description" : "Descripción",
|
||||
"(Unsaved)" : "(Sin salvar)",
|
||||
"(Saving…)" : "(Guardando...)",
|
||||
@@ -257,12 +271,12 @@
|
||||
"Set due date for this weekend" : "Establecer este fin de semana como fecha de vencimiento",
|
||||
"Next week – {timeLocale}" : "Próxima semana – {timeLocale}",
|
||||
"Set due date for next week" : "Establecer la próxima semana como fecha de vencimiento",
|
||||
"Assign a due date to this card…" : "Asignar una fecha de caducidad a esta tarjeta…",
|
||||
"Assign a due date to this card…" : "Asignar una fecha de vencimiento a esta tarjeta…",
|
||||
"Set a due date" : "Fijar una fecha límite",
|
||||
"Add due date" : "Añadir fecha de vencimiento",
|
||||
"Choose a date" : "Elija una fecha",
|
||||
"Remove due date" : "Eliminar fecha límite",
|
||||
"Mark as done" : "Marcar como hecho",
|
||||
"Mark as done" : "Marcar como completado",
|
||||
"Due at:" : "Vence el:",
|
||||
"Not done" : "No está finalizado",
|
||||
"Unarchive card" : "Desarchivar tarjeta",
|
||||
@@ -326,6 +340,7 @@
|
||||
"An error occurred" : "Ocurrió un error",
|
||||
"Are you sure you want to delete the board {title}? This will delete all the data of this board including archived cards." : "¿Está seguro de querer eliminar el tablero {title}? Esto eliminará todos los datos del tablero incluyendo las tarjetas archivadas.",
|
||||
"Delete the board?" : "¿Borrar el tablero?",
|
||||
"Exporting board..." : "Exportando tablero...",
|
||||
"Board details" : "Detalles del tablero",
|
||||
"Edit board" : "Editar tablero",
|
||||
"Clone board" : "Clonar tablero",
|
||||
@@ -338,16 +353,22 @@
|
||||
"Assigned cards" : "Tarjetas asignadas",
|
||||
"No notifications" : "No hay notificaciones",
|
||||
"Delete board" : "Eliminar tablero",
|
||||
"Importing board..." : "Importando tablero...",
|
||||
"Board imported successfully" : "Se importó el tablero exitosamente",
|
||||
"Import board" : "Importar tablero",
|
||||
"Clone {boardTitle}" : "Clonar {boardTitle}",
|
||||
"Clone cards" : "Clonar tarjetas",
|
||||
"Clone assignments" : "Clonar asignaciones",
|
||||
"Clone labels" : "Clonar etiquetas",
|
||||
"Clone due dates" : "Clonar fechas límite",
|
||||
"Clone due dates" : "Clonar fechas de vencimiento",
|
||||
"Advanced options" : "Opciones avanzadas",
|
||||
"Move all cards to the first list" : "Mover todas las tarjetas a la primera lista",
|
||||
"Restore archived cards" : "Restaurar tarjetas archivadas",
|
||||
"Clone" : "Clonar",
|
||||
"Export {boardTitle}" : "Exportar {boardTitle}",
|
||||
"Export as JSON" : "Exportar como JSON",
|
||||
"Export as CSV" : "Exportar como CSV",
|
||||
"Note: Only the JSON format is supported for importing back into the Deck app." : "Nota: Solo el formato JSON es soportar al importar de vuelta en la app Deck.",
|
||||
"Export" : "Exportar",
|
||||
"Loading filtered view" : "Cargando vista filtrada",
|
||||
"Today" : "Hoy",
|
||||
@@ -355,17 +376,17 @@
|
||||
"No due" : "Sin finalizar",
|
||||
"Search for {searchQuery} in all boards" : "Buscar {searchQuery} en todos los tableros",
|
||||
"No results found" : "No se encontraron resultados",
|
||||
"Deck board {name}\n* Last modified on {lastMod}" : "Tablero Deck {name}\n* Última modificación en {lastMod}",
|
||||
"* Created on {created}\n* Last modified on {lastMod}\n* {nbAttachments} attachments\n* {nbComments} comments" : "* Creada en {created}\n* Ultima moficiación en {lastMod}\n* {nbAttachments} adjuntos\n* {nbComments} comentarios",
|
||||
"Deck board {name}\n* Last modified on {lastMod}" : "Tablero Deck {name}\n* Se modificó por última vez el {lastMod}",
|
||||
"* Created on {created}\n* Last modified on {lastMod}\n* {nbAttachments} attachments\n* {nbComments} comments" : "* Creado en {created}\n* Se modificó por última vez el {lastMod}\n* {nbAttachments} adjuntos\n* {nbComments} comentarios",
|
||||
"{nbCards} cards" : "{nbCards} tarjetas",
|
||||
"Due on {date}" : "Vence en {date}",
|
||||
"{stack} in {board}" : "{stack} en {board}",
|
||||
"Click to expand description" : "Pulse para expandir la descripción",
|
||||
"Click to expand comment" : "Pulse para expandir el comentario",
|
||||
"Click to expand description" : "Haga clic para expandir la descripción",
|
||||
"Click to expand comment" : "Haga clic para expandir el comentario",
|
||||
"Create card" : "Crear tarjeta",
|
||||
"Create a new card" : "Crear una nueva tarjeta",
|
||||
"Create a new card" : "Crear una tarjeta nueva",
|
||||
"Card title" : "Título de la tarjeta",
|
||||
"Creating the new card …" : "Creando una nueva tarjeta …",
|
||||
"Creating the new card …" : "Creando una tarjeta nueva …",
|
||||
"Card \"{card}\" was added to \"{board}\"" : "La tarjeta \"{card}\" fue añadida a \"{board}\"",
|
||||
"Open card" : "Abrir tarjeta",
|
||||
"Close" : "Cerrar",
|
||||
@@ -381,7 +402,8 @@
|
||||
"Something went wrong" : "Algo ha ido mal",
|
||||
"Failed to upload {name}" : "Error al subir {name}",
|
||||
"Maximum file size of {size} exceeded" : "Tamaño máximo de archivo de {size} excedido",
|
||||
"Due date" : "Fecha de fin",
|
||||
"Assigned users" : "Usuarios asignados",
|
||||
"Due date" : "Fecha de vencimiento",
|
||||
"Error creating the share" : "Error creando el recurso compartido",
|
||||
"Share with a Deck card" : "Compartir con una tarjeta de Deck",
|
||||
"Share {file} with a Deck card" : "Compartir {file} con una tarjeta de Deck",
|
||||
|
||||
@@ -33,6 +33,7 @@ OC.L10N.register(
|
||||
"Tags" : "Etiquetas",
|
||||
"Activity" : "Actividad",
|
||||
"Undo" : "Deshacer",
|
||||
"Transfer" : "Transferencia",
|
||||
"Can edit" : "Puede editar",
|
||||
"Can share" : "Puede compartir",
|
||||
"Owner" : "Dueño",
|
||||
@@ -58,6 +59,7 @@ OC.L10N.register(
|
||||
"Search" : "Buscar",
|
||||
"Archived boards" : "Tableros archivados",
|
||||
"Shared with you" : "Compartido con usted",
|
||||
"Cancel edit" : "Cancelar edición",
|
||||
"Board details" : "Detalles del tablero",
|
||||
"Edit board" : "Editar el tablero",
|
||||
"Unarchive board" : "Desarchivar tablero",
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
"Tags" : "Etiquetas",
|
||||
"Activity" : "Actividad",
|
||||
"Undo" : "Deshacer",
|
||||
"Transfer" : "Transferencia",
|
||||
"Can edit" : "Puede editar",
|
||||
"Can share" : "Puede compartir",
|
||||
"Owner" : "Dueño",
|
||||
@@ -56,6 +57,7 @@
|
||||
"Search" : "Buscar",
|
||||
"Archived boards" : "Tableros archivados",
|
||||
"Shared with you" : "Compartido con usted",
|
||||
"Cancel edit" : "Cancelar edición",
|
||||
"Board details" : "Detalles del tablero",
|
||||
"Edit board" : "Editar el tablero",
|
||||
"Unarchive board" : "Desarchivar tablero",
|
||||
|
||||
@@ -274,6 +274,7 @@ OC.L10N.register(
|
||||
"{count} comments, {unread} unread" : "コメント {count} 件あり、 {unread} 件未読",
|
||||
"Todo items" : "Todo項目",
|
||||
"Edit card title" : "カードタイトルを編集する",
|
||||
"Open link" : "リンクを開く",
|
||||
"Card deleted" : "カードが削除されました",
|
||||
"Edit title" : "タイトルを編集",
|
||||
"Assign to me" : "自分に割り当てる",
|
||||
|
||||
@@ -272,6 +272,7 @@
|
||||
"{count} comments, {unread} unread" : "コメント {count} 件あり、 {unread} 件未読",
|
||||
"Todo items" : "Todo項目",
|
||||
"Edit card title" : "カードタイトルを編集する",
|
||||
"Open link" : "リンクを開く",
|
||||
"Card deleted" : "カードが削除されました",
|
||||
"Edit title" : "タイトルを編集",
|
||||
"Assign to me" : "自分に割り当てる",
|
||||
|
||||
@@ -65,6 +65,7 @@ OC.L10N.register(
|
||||
"Description" : "Apraksts",
|
||||
"Select Date" : "Izvēlieties datumu",
|
||||
"Later today – {timeLocale}" : "Vēlāk šodien – {timeLocale}",
|
||||
"Set due date for later today" : "Iestatīt beigu datumu vēlāk šodienā",
|
||||
"(group)" : "(grupa)",
|
||||
"Open link" : "Atvērt saiti",
|
||||
"seconds ago" : "pirms vairākām sekundēm",
|
||||
@@ -80,6 +81,8 @@ OC.L10N.register(
|
||||
"Export" : "Izgūt",
|
||||
"Today" : "Šodien",
|
||||
"Tomorrow" : "Rīt",
|
||||
"Deck board {name}\n* Last modified on {lastMod}" : "Kavas dēlis {name}\n* Pēdējoreiz izmainīts {lastMod}",
|
||||
"* Created on {created}\n* Last modified on {lastMod}\n* {nbAttachments} attachments\n* {nbComments} comments" : "* Izveidots {created}\n* Pēdējoreiz izmainīts {lastMod}\n* {nbAttachments} pielikumi\n* {nbComments} piebildes",
|
||||
"Close" : "Aizvērt",
|
||||
"Due date" : "Izpildes datums",
|
||||
"Share" : "Koplietot",
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
"Description" : "Apraksts",
|
||||
"Select Date" : "Izvēlieties datumu",
|
||||
"Later today – {timeLocale}" : "Vēlāk šodien – {timeLocale}",
|
||||
"Set due date for later today" : "Iestatīt beigu datumu vēlāk šodienā",
|
||||
"(group)" : "(grupa)",
|
||||
"Open link" : "Atvērt saiti",
|
||||
"seconds ago" : "pirms vairākām sekundēm",
|
||||
@@ -78,6 +79,8 @@
|
||||
"Export" : "Izgūt",
|
||||
"Today" : "Šodien",
|
||||
"Tomorrow" : "Rīt",
|
||||
"Deck board {name}\n* Last modified on {lastMod}" : "Kavas dēlis {name}\n* Pēdējoreiz izmainīts {lastMod}",
|
||||
"* Created on {created}\n* Last modified on {lastMod}\n* {nbAttachments} attachments\n* {nbComments} comments" : "* Izveidots {created}\n* Pēdējoreiz izmainīts {lastMod}\n* {nbAttachments} pielikumi\n* {nbComments} piebildes",
|
||||
"Close" : "Aizvērt",
|
||||
"Due date" : "Izpildes datums",
|
||||
"Share" : "Koplietot",
|
||||
|
||||
@@ -266,6 +266,7 @@ OC.L10N.register(
|
||||
"{count} comments, {unread} unread" : "Komentarze: {count}, nieprzeczytane: {unread}",
|
||||
"Todo items" : "Do zrobienia",
|
||||
"Edit card title" : "Edytuj nazwę karty",
|
||||
"Open link" : "Otwórz link",
|
||||
"Card deleted" : "Karta usunięta",
|
||||
"Edit title" : "Edytuj tytuł",
|
||||
"Assign to me" : "Przydziel do mnie",
|
||||
@@ -312,6 +313,7 @@ OC.L10N.register(
|
||||
"Clone cards" : "Klonuj karty",
|
||||
"Advanced options" : "Opcje zaawansowane",
|
||||
"Clone" : "Klonuj",
|
||||
"Export {boardTitle}" : "Eksportuj {boardTitle}",
|
||||
"Export" : "Eksportuj",
|
||||
"Loading filtered view" : "Wczytywanie przefiltrowanego widoku",
|
||||
"Today" : "Dzisiaj",
|
||||
|
||||
@@ -264,6 +264,7 @@
|
||||
"{count} comments, {unread} unread" : "Komentarze: {count}, nieprzeczytane: {unread}",
|
||||
"Todo items" : "Do zrobienia",
|
||||
"Edit card title" : "Edytuj nazwę karty",
|
||||
"Open link" : "Otwórz link",
|
||||
"Card deleted" : "Karta usunięta",
|
||||
"Edit title" : "Edytuj tytuł",
|
||||
"Assign to me" : "Przydziel do mnie",
|
||||
@@ -310,6 +311,7 @@
|
||||
"Clone cards" : "Klonuj karty",
|
||||
"Advanced options" : "Opcje zaawansowane",
|
||||
"Clone" : "Klonuj",
|
||||
"Export {boardTitle}" : "Eksportuj {boardTitle}",
|
||||
"Export" : "Eksportuj",
|
||||
"Loading filtered view" : "Wczytywanie przefiltrowanego widoku",
|
||||
"Today" : "Dzisiaj",
|
||||
|
||||
@@ -274,6 +274,7 @@ OC.L10N.register(
|
||||
"{count} comments, {unread} unread" : "{count} комментариев, {unread} непрочитано",
|
||||
"Todo items" : "Элементы списка задач",
|
||||
"Edit card title" : "Изменить заголовок карточки",
|
||||
"Open link" : "Открыть ссылку",
|
||||
"Card deleted" : "Карточка удалена",
|
||||
"Edit title" : "Редактировать заголовок",
|
||||
"Assign to me" : "Назначить себе",
|
||||
|
||||
@@ -272,6 +272,7 @@
|
||||
"{count} comments, {unread} unread" : "{count} комментариев, {unread} непрочитано",
|
||||
"Todo items" : "Элементы списка задач",
|
||||
"Edit card title" : "Изменить заголовок карточки",
|
||||
"Open link" : "Открыть ссылку",
|
||||
"Card deleted" : "Карточка удалена",
|
||||
"Edit title" : "Редактировать заголовок",
|
||||
"Assign to me" : "Назначить себе",
|
||||
|
||||
@@ -124,6 +124,7 @@ OC.L10N.register(
|
||||
"This comment has more than %s characters.\nAdded as an attachment to the card with name %s.\nAccessible on URL: %s." : "Овај коментар има више од %s карактера.\nДодат је као прилог картици под именом %s.\nДоступно је на URL адреси: %s.",
|
||||
"Attachments" : "Прилози",
|
||||
"File" : "Фајл",
|
||||
"date" : "датум",
|
||||
"Card not found" : "Картица није нађена",
|
||||
"Path is already shared with this card" : "Путања се већ дели са овом картицом",
|
||||
"Invalid date, date format must be YYYY-MM-DD" : "Неисправан датум, формат датума мора бити ГГГГ-ММ-ДД",
|
||||
@@ -239,6 +240,7 @@ OC.L10N.register(
|
||||
"Modified" : "Измењен",
|
||||
"Created" : "Направљен",
|
||||
"The title cannot be empty." : "Наслов не може бити празан.",
|
||||
"Cannot close unsaved card!" : "Не може да се затвори несачувана картица!",
|
||||
"Open in sidebar view" : "Отвори у бочном прегледу",
|
||||
"Open in bigger view" : "Отвори на већем приказу",
|
||||
"Comments" : "Коментари",
|
||||
@@ -253,6 +255,7 @@ OC.L10N.register(
|
||||
"Reply" : "Одговори",
|
||||
"Update" : "Ажурирај",
|
||||
"Write a description …" : "Напишите опис ...",
|
||||
"Could not save description" : "Не може да се сачува опис",
|
||||
"Description" : "Опис",
|
||||
"(Unsaved)" : "(несачуван)",
|
||||
"(Saving…)" : "(чувам…)",
|
||||
|
||||
@@ -122,6 +122,7 @@
|
||||
"This comment has more than %s characters.\nAdded as an attachment to the card with name %s.\nAccessible on URL: %s." : "Овај коментар има више од %s карактера.\nДодат је као прилог картици под именом %s.\nДоступно је на URL адреси: %s.",
|
||||
"Attachments" : "Прилози",
|
||||
"File" : "Фајл",
|
||||
"date" : "датум",
|
||||
"Card not found" : "Картица није нађена",
|
||||
"Path is already shared with this card" : "Путања се већ дели са овом картицом",
|
||||
"Invalid date, date format must be YYYY-MM-DD" : "Неисправан датум, формат датума мора бити ГГГГ-ММ-ДД",
|
||||
@@ -237,6 +238,7 @@
|
||||
"Modified" : "Измењен",
|
||||
"Created" : "Направљен",
|
||||
"The title cannot be empty." : "Наслов не може бити празан.",
|
||||
"Cannot close unsaved card!" : "Не може да се затвори несачувана картица!",
|
||||
"Open in sidebar view" : "Отвори у бочном прегледу",
|
||||
"Open in bigger view" : "Отвори на већем приказу",
|
||||
"Comments" : "Коментари",
|
||||
@@ -251,6 +253,7 @@
|
||||
"Reply" : "Одговори",
|
||||
"Update" : "Ажурирај",
|
||||
"Write a description …" : "Напишите опис ...",
|
||||
"Could not save description" : "Не може да се сачува опис",
|
||||
"Description" : "Опис",
|
||||
"(Unsaved)" : "(несачуван)",
|
||||
"(Saving…)" : "(чувам…)",
|
||||
|
||||
@@ -240,6 +240,7 @@ OC.L10N.register(
|
||||
"Modified" : "Değiştirilme",
|
||||
"Created" : "Oluşturulma",
|
||||
"The title cannot be empty." : "Başlık boş olamaz.",
|
||||
"Cannot close unsaved card!" : "Kaydedilmemiş bir kart kapatılamaz!",
|
||||
"Open in sidebar view" : "Kenar çubuğu görünümünde aç",
|
||||
"Open in bigger view" : "Daha büyük görünümde aç",
|
||||
"Comments" : "Yorumlar",
|
||||
@@ -254,6 +255,7 @@ OC.L10N.register(
|
||||
"Reply" : "Yanıtla",
|
||||
"Update" : "Güncelle",
|
||||
"Write a description …" : "Bir açıklama yazın …",
|
||||
"Could not save description" : "Açıklama kaydedilemedi",
|
||||
"Description" : "Açıklama",
|
||||
"(Unsaved)" : "(Kaydedilmemiş)",
|
||||
"(Saving…)" : "(Kaydediliyor…)",
|
||||
|
||||
@@ -238,6 +238,7 @@
|
||||
"Modified" : "Değiştirilme",
|
||||
"Created" : "Oluşturulma",
|
||||
"The title cannot be empty." : "Başlık boş olamaz.",
|
||||
"Cannot close unsaved card!" : "Kaydedilmemiş bir kart kapatılamaz!",
|
||||
"Open in sidebar view" : "Kenar çubuğu görünümünde aç",
|
||||
"Open in bigger view" : "Daha büyük görünümde aç",
|
||||
"Comments" : "Yorumlar",
|
||||
@@ -252,6 +253,7 @@
|
||||
"Reply" : "Yanıtla",
|
||||
"Update" : "Güncelle",
|
||||
"Write a description …" : "Bir açıklama yazın …",
|
||||
"Could not save description" : "Açıklama kaydedilemedi",
|
||||
"Description" : "Açıklama",
|
||||
"(Unsaved)" : "(Kaydedilmemiş)",
|
||||
"(Saving…)" : "(Kaydediliyor…)",
|
||||
|
||||
171
l10n/uk.js
171
l10n/uk.js
@@ -48,8 +48,30 @@ OC.L10N.register(
|
||||
"You have updated the due date of card {card} to {after}" : "Ви оновили дату завершення картки {card} на {after}",
|
||||
"{user} has updated the due date of card {card} to {after}" : "{user} оновив(-ла) дату завершення картки {card} на {after}",
|
||||
"You have added the tag {label} to card {card} in list {stack} on board {board}" : "Ви додали мітку {label} до картки {card} в списку {board}",
|
||||
"{user} has added the tag {label} to card {card} in list {stack} on board {board}" : "{user} додав тег {label} до карти {card} у списку {stack} на борту {board}",
|
||||
"You have removed the tag {label} from card {card} in list {stack} on board {board}" : "Ви видалили тег {label} з карти {card} у списку {stack} на борту {board}",
|
||||
"{user} has removed the tag {label} from card {card} in list {stack} on board {board}" : "{user} видалив тег {label} з карти {card} у списку {stack} на борту {board}",
|
||||
"You have assigned {assigneduser} to card {card} on board {board}" : "Ви призначили {assigneduser} на картку {card} на борту {board}",
|
||||
"{user} has assigned {assigneduser} to card {card} on board {board}" : "{user} призначив {assigneduser} на картку {card} на дошці {board}",
|
||||
"You have unassigned {assigneduser} from card {card} on board {board}" : "Ви скасували призначення {assigneduser} з карти {card} на борту {board}",
|
||||
"{user} has unassigned {assigneduser} from card {card} on board {board}" : "{user} скасував призначення {assigneduser} з карти {card} на дошці {board}",
|
||||
"You have moved the card {card} from list {stackBefore} to {stack}" : "Ви перемістили картку {card} зі списку {stackBefore} до {stack}",
|
||||
"{user} has moved the card {card} from list {stackBefore} to {stack}" : "{user} перемістив картку {card} зі списку {stackBefore} до {stack}",
|
||||
"You have added the attachment {attachment} to card {card}" : "Ви додали вкладення {attachment} до картки {card}",
|
||||
"{user} has added the attachment {attachment} to card {card}" : "{user} додав вкладення {attachment} до картки {card}",
|
||||
"You have updated the attachment {attachment} on card {card}" : "Ви оновили вкладення {attachment} на картці {card}",
|
||||
"{user} has updated the attachment {attachment} on card {card}" : " {user}оновив вкладення {attachment} на картці {card}",
|
||||
"You have deleted the attachment {attachment} from card {card}" : "Ви видалили вкладення {attachment} з картки {card}",
|
||||
"{user} has deleted the attachment {attachment} from card {card}" : "{user} видалив вкладення {attachment} з картки {card}",
|
||||
"You have restored the attachment {attachment} to card {card}" : "Ви відновили вкладення {attachment} до картки {card}",
|
||||
"{user} has restored the attachment {attachment} to card {card}" : "{user} відновив вкладення {attachment} до картки {card}",
|
||||
"You have commented on card {card}" : "Ви залишили коментар до картки {card}",
|
||||
"{user} has commented on card {card}" : "{user} прокоментував картку {card}",
|
||||
"Deck" : "Колода",
|
||||
"Changes in the <strong>Deck app</strong>" : "Зміни у застосунку <strong>Колода</strong>",
|
||||
"A <strong>board, list or card</strong> was changed" : "Змінено <strong>таблицю, список або картку</strong>",
|
||||
"A <strong>comment</strong> was created on a card" : "Створено <strong>коментар</strong> на картці",
|
||||
"A <strong>card description</strong> has been changed" : "Змінено <strong>опис картки</strong>",
|
||||
"The file was uploaded" : "Файл завантажено",
|
||||
"The uploaded file exceeds the upload_max_filesize directive in php.ini" : "Файл для завантаження перевищує параметр upload_max_filesize у php.ini",
|
||||
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Розмір завантаженого файлу перевищує значення MAX_FILE_SIZE, яке було зазначено у HTML формі",
|
||||
@@ -59,30 +81,66 @@ OC.L10N.register(
|
||||
"Could not write file to disk" : "Неможливо записати файл на диск",
|
||||
"A PHP extension stopped the file upload" : "Розширення PHP призупинило завантаження файлу",
|
||||
"No file uploaded or file size exceeds maximum of %s" : "Немає завантажених файлів або розмір файлу перевищує максимум %s",
|
||||
"Invalid file type. Only JSON files are allowed." : "Неправильний тип файлу. Допускаються тільки файли у форматі JSON.",
|
||||
"Invalid JSON data" : "Неправильні дані JSON",
|
||||
"Failed to import board" : "Не вдалося імпортувати дошку",
|
||||
"Cards due today" : "Картки повинні бути оплачені сьогодні",
|
||||
"Cards due tomorrow" : "Картки на завтра",
|
||||
"Upcoming cards" : "Очікують на виконання",
|
||||
"Load more" : "Більше",
|
||||
"Welcome to Nextcloud Deck!" : "Ласкаво просимо до колоди Nextcloud!",
|
||||
"The card \"%s\" on \"%s\" has been assigned to you by %s." : "Картка \"%s\" на \"%s\" була призначена вам %s.",
|
||||
"{user} has assigned the card {deck-card} on {deck-board} to you." : "{user} призначив вам карту {deck-card} на {deck-board}.",
|
||||
"The card \"%s\" on \"%s\" has reached its due date." : "Термін дії картки \"%s\" на \"%s\" закінчився.",
|
||||
"The card {deck-card} on {deck-board} has reached its due date." : "Термін дії карти {deck-card} на {deck-board} закінчився.",
|
||||
"%s has mentioned you in a comment on \"%s\"." : "%s згадав вас у коментарі до \"%s\".",
|
||||
"{user} has mentioned you in a comment on {deck-card}." : "{user} згадав вас у коментарі до {deck-card}.",
|
||||
"The board \"%s\" has been shared with you by %s." : "Дошку \"%s\" з вами поділився %s.",
|
||||
"{user} has shared {deck-board} with you." : "{user} поділився з вами {deck-board}.",
|
||||
"Deck board" : "Дошка Deck",
|
||||
"Owned by %1$s" : "Належить %1$s",
|
||||
"Deck boards, cards and comments" : "Дошки колод, карти та коментарі",
|
||||
"From %1$s, in %2$s/%3$s, owned by %4$s" : "З %1$s, в %2$s/%3$s, у власності %4$s",
|
||||
"Create a new deck card" : "Створіть нову карту колоди",
|
||||
"Card comments" : "Коментарі до картки",
|
||||
"%s on %s" : "%s на %s",
|
||||
"Deck boards and cards" : "Колода та карти",
|
||||
"No data was provided to create an attachment." : "Для створення вкладення не було надано жодних даних.",
|
||||
"Finished" : "Завершено",
|
||||
"To review" : "На перегляд",
|
||||
"Action needed" : "Потребує дій",
|
||||
"Later" : "Пізніше",
|
||||
"copy" : "копіювати",
|
||||
"Read more inside" : "Читайте більше всередині",
|
||||
"Custom lists - click to rename!" : "Користувацькі списки - натисніть, щоб перейменувати!",
|
||||
"To Do" : "Зробити",
|
||||
"In Progress" : "В процесі",
|
||||
"Done" : "Готово",
|
||||
"1. Open to learn more about boards and cards" : "1. Відкриті, щоб дізнатися більше про дошки та картки",
|
||||
"2. Drag cards left and right, up and down" : "2. Перетягування карток вліво і вправо, вгору і вниз",
|
||||
"3. Apply rich formatting and link content" : "3. Застосовуйте багате форматування та посилання на вміст",
|
||||
"4. Share, comment and collaborate!" : "4. Діліться, коментуйте та співпрацюйте!",
|
||||
"Create your first card!" : "Створіть свою першу листівку!",
|
||||
"This comment has more than %s characters.\nAdded as an attachment to the card with name %s.\nAccessible on URL: %s." : "Цей коментар містить більше %s символів.\nДодано як вкладення до картки з іменем %s.\nДоступний за URL: %s.",
|
||||
"Attachments" : "Вкладення",
|
||||
"File" : "Файл",
|
||||
"date" : "дата",
|
||||
"Card not found" : "Картку не знайдено",
|
||||
"Path is already shared with this card" : "Шлях вже є спільним з цією карткою",
|
||||
"Invalid date, date format must be YYYY-MM-DD" : "Недійсна дата, формат дати має бути РРРР-ММ-ДД",
|
||||
"Personal planning and team project organization" : "Особисте планування та організація командних проектів",
|
||||
"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 - це інструмент організації в стилі канбан, призначений для особистого планування та організації проектів для команд, інтегрованих з Nextcloud.\n\n\n- 📥 Додавайте свої завдання на картки та впорядковуйте їх\n- 📄 Записуйте додаткові нотатки в Markdown\n- 🔖 Призначайте мітки для ще кращої організації\n- 👥 Діліться з командою, друзями чи родиною\n- Прикріплюйте файли та вбудовуйте їх в опис Markdown\n- 💬 Обговорюйте зі своєю командою за допомогою коментарів\n- ⚡ Відстежуйте зміни в потоці активностей\n- 🚀 Організуйте свій проект",
|
||||
"Add board" : "Додати дошку",
|
||||
"Card details" : "Деталі картки",
|
||||
"Select the board to link to a project" : "Виберіть дошку для прив'зки до проєкту",
|
||||
"Search by board title" : "Шукати за назвою дошки",
|
||||
"Select board" : "Вибрати дошку",
|
||||
"Move/copy card" : "Картка переміщення/копіювання",
|
||||
"Select a board" : "Вибрати дошку",
|
||||
"No lists available" : "Списки відсутні",
|
||||
"Select a list" : "Виберіть список",
|
||||
"Move card" : "Пересунути картку",
|
||||
"Copy card" : "Копіювальна картка",
|
||||
"Select the card to link to a project" : "Виберіть картку для прив'язки до проєкту",
|
||||
"Link to card" : "Прив'язати до картки",
|
||||
"Select a card" : "Вибрати картку",
|
||||
@@ -103,19 +161,27 @@ OC.L10N.register(
|
||||
"Filter by tag" : "Відібрати за мітками",
|
||||
"Filter by assigned user" : "Відібрати за призначеним користувачем",
|
||||
"Unassigned" : "Скасовано призначення",
|
||||
"Filter by status" : "Фільтр за статусом",
|
||||
"Open and completed" : "Відкрито та завершено",
|
||||
"Open" : "Відкрити",
|
||||
"Completed" : "Виконано",
|
||||
"Filter by due date" : "Відібрати за датою завершення",
|
||||
"Overdue" : "Протерміновано",
|
||||
"Next 24 hours" : "Наступні 24 години",
|
||||
"Next 7 days" : "Наступні 7 днів",
|
||||
"Next 30 days" : "Наступні 30 днів",
|
||||
"No due date" : "Без дати завершення",
|
||||
"Clear filter" : "Очистити фільтр",
|
||||
"View Modes" : "Режими перегляду",
|
||||
"Toggle View Modes" : "Перемикання режимів перегляду",
|
||||
"Hide archived cards" : "Приховати архівні картки",
|
||||
"Show archived cards" : "Показати архівні картки",
|
||||
"Toggle compact mode" : "Перемкнути компактний вигляд",
|
||||
"Hide card cover images" : "Приховати зображення обкладинок карток",
|
||||
"Show card cover images" : "Показати зображення обкладинки картки",
|
||||
"Open details" : "Показати деталі",
|
||||
"Details" : "Деталі",
|
||||
"Currently present people" : "Наразі присутні люди",
|
||||
"Loading board" : "Завантаження дошки",
|
||||
"Board not found" : "Дошку не знайдено",
|
||||
"Create a new list to add cards to this board" : "Створіть список щоб додати картки на цю дошку",
|
||||
@@ -126,35 +192,62 @@ OC.L10N.register(
|
||||
"Deleted lists" : "Вилучені списки",
|
||||
"Undo" : "Скасувати",
|
||||
"Deleted cards" : "Вилучені картки",
|
||||
"Failed to create share with {displayName}" : "Не вдалося створити спільний доступ з {displayName}",
|
||||
"Are you sure you want to transfer the board {title} to {user}?" : "Ви впевнені, що хочете перенести дошку {title} користувачеві {user}?",
|
||||
"Transfer the board." : "Перенесіть дошку.",
|
||||
"Transfer" : "Передати",
|
||||
"The board has been transferred to {user}" : "Дошка була передана {user}",
|
||||
"Failed to transfer the board to {user}" : "Не вдалося передати дошку користувачеві {user}",
|
||||
"Share board with a user, group or team …" : "Спільний доступ до дошки з користувачем, групою або командою ...",
|
||||
"Searching for users, groups and teams …" : "Пошук користувачів, груп і команд ...",
|
||||
"No participants found" : "Учасників не знайдено",
|
||||
"Board owner" : "Власник дошки",
|
||||
"(Group)" : "(група)",
|
||||
"(Team)" : "(Команда)",
|
||||
"Can edit" : "Може редагувати",
|
||||
"Can share" : "Can share",
|
||||
"Can manage" : "Може керувати",
|
||||
"Owner" : "Власник",
|
||||
"Delete" : "Вилучити",
|
||||
"List deleted" : "Список видалено",
|
||||
"Edit list title" : "Редагувати заголовок списку",
|
||||
"Archive all cards" : "Архівувати всі картки",
|
||||
"Unarchive all cards" : "Розархівувати всі картки",
|
||||
"Delete list" : "Вилучити список",
|
||||
"Archive all cards in this list" : "Архівуйте всі картки в цьому списку",
|
||||
"Unarchive all cards in this list" : "Розархівувати всі картки в цьому списку",
|
||||
"Add a new card" : "Додати нову картку",
|
||||
"Card name" : "Назва картки",
|
||||
"title and color value must be provided" : "потрібно зазначити назву та колір",
|
||||
"Edit" : "Редагувати",
|
||||
"Add a new tag" : "Додати нову мітку",
|
||||
"Board name" : "Назва дошки",
|
||||
"Members" : "Учасники",
|
||||
"Assign to users/groups/team" : "Призначити користувачам/групам/команді",
|
||||
"Assign a user to this card…" : "Призначити користувачеві цю картку",
|
||||
"Select a user to assign to this card…" : "Виберіть користувача, якого слід призначити на цю картку...",
|
||||
"File to share" : "Виберіть файл для надання доступу",
|
||||
"Invalid path selected" : "Вибрано неправильний шлях",
|
||||
"Upload new files" : "Додати файл",
|
||||
"Share from Files" : "Відкрити Файли",
|
||||
"Pending share" : "Очікувана акція",
|
||||
"Add this attachment" : "Долучити вкладення",
|
||||
"Show in Files" : "Показати в Файлах",
|
||||
"Download" : "Звантажити",
|
||||
"Remove attachment" : "Зніміть вкладення",
|
||||
"Delete Attachment" : "Забрати вкладення",
|
||||
"Restore Attachment" : "Відновити вкладення",
|
||||
"Modified" : "Змінено",
|
||||
"Created" : "Створено",
|
||||
"The title cannot be empty." : "Заголовок не може бути порожнім.",
|
||||
"Cannot close unsaved card!" : "Неможливо закрити незбережену картку!",
|
||||
"Open in sidebar view" : "Відкрити у вигляді бічної панелі",
|
||||
"Open in bigger view" : "Відкрити в більшому розмірі",
|
||||
"Comments" : "Коментарі",
|
||||
"Failed to load comments" : "Не вдалося завантажити коментарі",
|
||||
"No comments yet. Begin the discussion!" : "Коментарів немає, почніть обговорення!",
|
||||
"The comment cannot be empty." : "Коментар не може бути порожнім.",
|
||||
"The comment cannot be longer than 1000 characters." : "Коментар не може бути довшим за 1000 символів.",
|
||||
"Save" : "Зберегти",
|
||||
"Created:" : "Створено:",
|
||||
"In reply to" : "У відповідь",
|
||||
@@ -162,6 +255,7 @@ OC.L10N.register(
|
||||
"Reply" : "Відповісти",
|
||||
"Update" : "Оновлення",
|
||||
"Write a description …" : "Додайте опис ...",
|
||||
"Could not save description" : "Не вдалося зберегти опис",
|
||||
"Description" : "Опис",
|
||||
"(Unsaved)" : "(Не збережено)",
|
||||
"(Saving…)" : "(Зберігання...)",
|
||||
@@ -171,73 +265,150 @@ OC.L10N.register(
|
||||
"Add Attachment" : "Долучити вкладення",
|
||||
"Choose attachment" : "Вибрати вкладення",
|
||||
"Select Date" : "Вкажіть дату",
|
||||
"Later today – {timeLocale}" : "Пізніше сьогодні - {timeLocale}",
|
||||
"Set due date for later today" : "Встановіть термін сплати на сьогоднішній день",
|
||||
"Tomorrow – {timeLocale}" : "Завтра - {timeLocale}",
|
||||
"Set due date for tomorrow" : "Встановіть дедлайн на завтра",
|
||||
"This weekend – {timeLocale}" : "На цих вихідних - {timeLocale}",
|
||||
"Set due date for this weekend" : "Встановіть термін виконання на ці вихідні",
|
||||
"Next week – {timeLocale}" : "Наступного тижня - {timeLocale}",
|
||||
"Set due date for next week" : "Встановіть термін виконання на наступний тиждень",
|
||||
"Assign a due date to this card…" : "Призначте цій картці термін оплати...",
|
||||
"Set a due date" : "Встановити дату завершення",
|
||||
"Add due date" : "Додати термін сплати",
|
||||
"Choose a date" : "Виберіть дату",
|
||||
"Remove due date" : "Вилучити до",
|
||||
"Mark as done" : "Позначити як виконане",
|
||||
"Due at:" : "На часі:",
|
||||
"Not done" : "Ще не все.",
|
||||
"Unarchive card" : "Розархівувати картку",
|
||||
"Archive card" : "Архівувати картку",
|
||||
"Assign a tag to this card…" : "Додати мітку до цієї картки",
|
||||
"Select or create a tag…" : "Виберіть або створіть тег...",
|
||||
"Create a new tag:" : "Створіть новий тег:",
|
||||
"(group)" : "(група)",
|
||||
"{count} comments, {unread} unread" : "{count} коментарів, {unread} непрочитаних",
|
||||
"Todo items" : "Пункти завдань",
|
||||
"Edit card title" : "Редагувати заголовок картки",
|
||||
"Open link" : "Відкрити посилання",
|
||||
"Card deleted" : "Картку видалено",
|
||||
"Edit title" : "Редагувати",
|
||||
"Assign to me" : "Призначити мені",
|
||||
"Unassign myself" : "Зняти з себе повноваження.",
|
||||
"Mark as not done" : "Позначити як не виконано",
|
||||
"Delete card" : "Вилучити картку",
|
||||
"seconds ago" : "секунд тому",
|
||||
"Keyboard shortcuts" : "Скорочення",
|
||||
"Boost your productivity using Deck with keyboard shortcuts." : "Підвищуйте свою продуктивність, використовуючи Deck за допомогою комбінацій клавіш.",
|
||||
"Board actions" : "Дії правління",
|
||||
"Keyboard shortcut" : "Сполучення клавіш",
|
||||
"Action" : "Дія ",
|
||||
"Shift" : "Shift",
|
||||
"Scroll" : "Прокрутка",
|
||||
"Scroll sideways" : "Прокрутіть вбік",
|
||||
"Navigate between cards" : "Перехід між картками",
|
||||
"Esc" : "Esc",
|
||||
"Close card details" : "Закрити дані картки",
|
||||
"Ctrl" : "Ctrl",
|
||||
"Search" : "Пошук",
|
||||
"Show card filters" : "Показати фільтри карток",
|
||||
"Clear card filters" : "Очистити фільтри карток",
|
||||
"Show help dialog" : "Показати діалогове вікно довідки",
|
||||
"Card actions" : "Дії з карткою",
|
||||
"The following actions can be triggered on the currently highlighted card" : "На поточній виділеній картці можна виконати такі дії",
|
||||
"Enter" : "Ввід",
|
||||
"Space" : "Простір",
|
||||
"Open card details" : "Відкрити реквізити картки",
|
||||
"Edit the card title" : "Відредагуйте назву картки",
|
||||
"Assign yourself to the current card" : "Приєднайте себе до поточної картки",
|
||||
"Archive/unarchive the current card" : "Архівувати/розархівувати поточну картку",
|
||||
"Mark card as completed/not completed" : "Позначте картку як завершену/не завершену",
|
||||
"Open card menu" : "Відкрити меню картки",
|
||||
"All boards" : "Усі дошки",
|
||||
"Archived boards" : "Архівні дошки",
|
||||
"Shared with you" : "Вам надано доступ",
|
||||
"Deck settings" : "Налаштування колоди",
|
||||
"Use bigger card view" : "Режим перегляду зі збільшеними картками",
|
||||
"Show card ID badge" : "Покажіть бейдж з ідентифікаційною карткою",
|
||||
"Show boards in calendar/tasks" : "Показувати дошки в календарі та завданнях",
|
||||
"Limit board creation to some groups" : "Обмежити створення дошки для деяких груп",
|
||||
"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." : "Користувачі поза цими групами не зможуть створювати власні дошки, але зможуть працювати на дошках, до яких їм надано спільний доступ.",
|
||||
"Cancel edit" : "Скасувати редагування",
|
||||
"Save board" : "Зберегти дошку",
|
||||
"Board {0} deleted" : "Дошку {0} вилучено",
|
||||
"All cards" : "Всі карти",
|
||||
"Only assigned cards" : "Тільки призначені картки",
|
||||
"No reminder" : "Відсутні нагадування",
|
||||
"An error occurred" : "Виникла помилка",
|
||||
"Are you sure you want to delete the board {title}? This will delete all the data of this board including archived cards." : "Ви впевнені, що хочете вилучити дошку {title}? Це призведе до видалення всіх даних цієї дошки, включно архівні картки.",
|
||||
"Delete the board?" : "Вилучити дошку?",
|
||||
"Exporting board..." : "Експортна дошка...",
|
||||
"Board details" : "Деталі дошки",
|
||||
"Edit board" : "Редагувати дошку",
|
||||
"Clone board" : "Копіювати дошку",
|
||||
"Unarchive board" : "Розархівувати дошку",
|
||||
"Archive board" : "Архівувати дошку",
|
||||
"Export board" : "Дошка експорту",
|
||||
"Turn on due date reminders" : "Нагадування про термін виконання",
|
||||
"Turn off due date reminders" : "Вимкнути нагадування про терміни виконання",
|
||||
"Due date reminders" : "Нагадування про терміни виконання",
|
||||
"Assigned cards" : "Призначені картки",
|
||||
"No notifications" : "Немає сповіщень",
|
||||
"Delete board" : "Вилучити дошку",
|
||||
"Importing board..." : "Імпортна дошка...",
|
||||
"Board imported successfully" : "Плату успішно імпортовано",
|
||||
"Import board" : "Імпортна дошка",
|
||||
"Clone {boardTitle}" : "Клон {boardTitle}",
|
||||
"Clone cards" : "Копіювати картки",
|
||||
"Clone assignments" : "Призначення клонів",
|
||||
"Clone labels" : "Етикетки клонів",
|
||||
"Clone due dates" : "Клонувати дві дати",
|
||||
"Advanced options" : "Розширені налаштування",
|
||||
"Move all cards to the first list" : "Перемістіть усі картки до першого списку",
|
||||
"Restore archived cards" : "Відновлення заархівованих карток",
|
||||
"Clone" : "Копіювати",
|
||||
"Export {boardTitle}" : "Експорт {boardTitle}",
|
||||
"Export as JSON" : "Експорт як JSON",
|
||||
"Export as CSV" : "Експорт у CSV",
|
||||
"Note: Only the JSON format is supported for importing back into the Deck app." : "Примітка: Для імпорту в додаток Deck підтримується лише формат JSON.",
|
||||
"Export" : "Експортувати",
|
||||
"Loading filtered view" : "Завантаження відфільтрованого перегляду",
|
||||
"Today" : "Сьогодні",
|
||||
"Tomorrow" : "Завтра",
|
||||
"No due" : "Без призначеної дати",
|
||||
"Search for {searchQuery} in all boards" : "Шукати {searchQuery} на всіх дошках оголошень",
|
||||
"No results found" : "Не знайдено жодного результату",
|
||||
"Deck board {name}\n* Last modified on {lastMod}" : "Колода {name}\n* Востаннє змінено на {lastMod}",
|
||||
"* Created on {created}\n* Last modified on {lastMod}\n* {nbAttachments} attachments\n* {nbComments} comments" : "* Створено на {created}\n* Востаннє змінено на {lastMod}\n* {nbAttachments} вкладення\n* {nbComments} коментарі",
|
||||
"{nbCards} cards" : "{nbCards} картки",
|
||||
"Due on {date}" : "До {date}",
|
||||
"{stack} in {board}" : "{stack} в {board}",
|
||||
"Click to expand description" : "Натисніть, щоб розгорнути опис",
|
||||
"Click to expand comment" : "Натисніть, щоб розгорнути коментар",
|
||||
"Create card" : "Створити картку",
|
||||
"Create a new card" : "Створити нову картку",
|
||||
"Card title" : "Заголовок картки",
|
||||
"Creating the new card …" : "Створення нової картки ...",
|
||||
"Card \"{card}\" was added to \"{board}\"" : "Картку \"{card}\" додано до \"{board}\"",
|
||||
"Open card" : "Відкрити картку",
|
||||
"Close" : "Закрити",
|
||||
"No upcoming cards" : "Немає майбутніх завдань",
|
||||
"upcoming cards today" : "найближчі картки на сьогодні",
|
||||
"upcoming cards tomorrow" : "найближчі картки завтра",
|
||||
"upcoming cards" : "очікують на виконання",
|
||||
"New card" : "Нова картка",
|
||||
"Link to a board" : "Прив'язати до дошки",
|
||||
"Link to a card" : "Прив'язати до картки",
|
||||
"Create a card" : "Створити картку",
|
||||
"Message from {author} in {conversationName}" : "Повідомлення від {author} у {conversationName}",
|
||||
"Something went wrong" : "От халепа!",
|
||||
"Failed to upload {name}" : "Не вдалося завантажити {name}",
|
||||
"Maximum file size of {size} exceeded" : "Досягнуто максимальний розмір файлу {size}",
|
||||
"Assigned users" : "Призначені користувачі",
|
||||
"Due date" : "Дата виконання",
|
||||
"Error creating the share" : "Помилка створення спільного доступу",
|
||||
"Share with a Deck card" : "Поділіться з картою з колоди",
|
||||
"Share {file} with a Deck card" : "Поділіться {file} з картою колоди",
|
||||
"Share" : "Спільний доступ",
|
||||
"Personal" : "Особисте",
|
||||
"To do" : "Заплановано",
|
||||
|
||||
171
l10n/uk.json
171
l10n/uk.json
@@ -46,8 +46,30 @@
|
||||
"You have updated the due date of card {card} to {after}" : "Ви оновили дату завершення картки {card} на {after}",
|
||||
"{user} has updated the due date of card {card} to {after}" : "{user} оновив(-ла) дату завершення картки {card} на {after}",
|
||||
"You have added the tag {label} to card {card} in list {stack} on board {board}" : "Ви додали мітку {label} до картки {card} в списку {board}",
|
||||
"{user} has added the tag {label} to card {card} in list {stack} on board {board}" : "{user} додав тег {label} до карти {card} у списку {stack} на борту {board}",
|
||||
"You have removed the tag {label} from card {card} in list {stack} on board {board}" : "Ви видалили тег {label} з карти {card} у списку {stack} на борту {board}",
|
||||
"{user} has removed the tag {label} from card {card} in list {stack} on board {board}" : "{user} видалив тег {label} з карти {card} у списку {stack} на борту {board}",
|
||||
"You have assigned {assigneduser} to card {card} on board {board}" : "Ви призначили {assigneduser} на картку {card} на борту {board}",
|
||||
"{user} has assigned {assigneduser} to card {card} on board {board}" : "{user} призначив {assigneduser} на картку {card} на дошці {board}",
|
||||
"You have unassigned {assigneduser} from card {card} on board {board}" : "Ви скасували призначення {assigneduser} з карти {card} на борту {board}",
|
||||
"{user} has unassigned {assigneduser} from card {card} on board {board}" : "{user} скасував призначення {assigneduser} з карти {card} на дошці {board}",
|
||||
"You have moved the card {card} from list {stackBefore} to {stack}" : "Ви перемістили картку {card} зі списку {stackBefore} до {stack}",
|
||||
"{user} has moved the card {card} from list {stackBefore} to {stack}" : "{user} перемістив картку {card} зі списку {stackBefore} до {stack}",
|
||||
"You have added the attachment {attachment} to card {card}" : "Ви додали вкладення {attachment} до картки {card}",
|
||||
"{user} has added the attachment {attachment} to card {card}" : "{user} додав вкладення {attachment} до картки {card}",
|
||||
"You have updated the attachment {attachment} on card {card}" : "Ви оновили вкладення {attachment} на картці {card}",
|
||||
"{user} has updated the attachment {attachment} on card {card}" : " {user}оновив вкладення {attachment} на картці {card}",
|
||||
"You have deleted the attachment {attachment} from card {card}" : "Ви видалили вкладення {attachment} з картки {card}",
|
||||
"{user} has deleted the attachment {attachment} from card {card}" : "{user} видалив вкладення {attachment} з картки {card}",
|
||||
"You have restored the attachment {attachment} to card {card}" : "Ви відновили вкладення {attachment} до картки {card}",
|
||||
"{user} has restored the attachment {attachment} to card {card}" : "{user} відновив вкладення {attachment} до картки {card}",
|
||||
"You have commented on card {card}" : "Ви залишили коментар до картки {card}",
|
||||
"{user} has commented on card {card}" : "{user} прокоментував картку {card}",
|
||||
"Deck" : "Колода",
|
||||
"Changes in the <strong>Deck app</strong>" : "Зміни у застосунку <strong>Колода</strong>",
|
||||
"A <strong>board, list or card</strong> was changed" : "Змінено <strong>таблицю, список або картку</strong>",
|
||||
"A <strong>comment</strong> was created on a card" : "Створено <strong>коментар</strong> на картці",
|
||||
"A <strong>card description</strong> has been changed" : "Змінено <strong>опис картки</strong>",
|
||||
"The file was uploaded" : "Файл завантажено",
|
||||
"The uploaded file exceeds the upload_max_filesize directive in php.ini" : "Файл для завантаження перевищує параметр upload_max_filesize у php.ini",
|
||||
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Розмір завантаженого файлу перевищує значення MAX_FILE_SIZE, яке було зазначено у HTML формі",
|
||||
@@ -57,30 +79,66 @@
|
||||
"Could not write file to disk" : "Неможливо записати файл на диск",
|
||||
"A PHP extension stopped the file upload" : "Розширення PHP призупинило завантаження файлу",
|
||||
"No file uploaded or file size exceeds maximum of %s" : "Немає завантажених файлів або розмір файлу перевищує максимум %s",
|
||||
"Invalid file type. Only JSON files are allowed." : "Неправильний тип файлу. Допускаються тільки файли у форматі JSON.",
|
||||
"Invalid JSON data" : "Неправильні дані JSON",
|
||||
"Failed to import board" : "Не вдалося імпортувати дошку",
|
||||
"Cards due today" : "Картки повинні бути оплачені сьогодні",
|
||||
"Cards due tomorrow" : "Картки на завтра",
|
||||
"Upcoming cards" : "Очікують на виконання",
|
||||
"Load more" : "Більше",
|
||||
"Welcome to Nextcloud Deck!" : "Ласкаво просимо до колоди Nextcloud!",
|
||||
"The card \"%s\" on \"%s\" has been assigned to you by %s." : "Картка \"%s\" на \"%s\" була призначена вам %s.",
|
||||
"{user} has assigned the card {deck-card} on {deck-board} to you." : "{user} призначив вам карту {deck-card} на {deck-board}.",
|
||||
"The card \"%s\" on \"%s\" has reached its due date." : "Термін дії картки \"%s\" на \"%s\" закінчився.",
|
||||
"The card {deck-card} on {deck-board} has reached its due date." : "Термін дії карти {deck-card} на {deck-board} закінчився.",
|
||||
"%s has mentioned you in a comment on \"%s\"." : "%s згадав вас у коментарі до \"%s\".",
|
||||
"{user} has mentioned you in a comment on {deck-card}." : "{user} згадав вас у коментарі до {deck-card}.",
|
||||
"The board \"%s\" has been shared with you by %s." : "Дошку \"%s\" з вами поділився %s.",
|
||||
"{user} has shared {deck-board} with you." : "{user} поділився з вами {deck-board}.",
|
||||
"Deck board" : "Дошка Deck",
|
||||
"Owned by %1$s" : "Належить %1$s",
|
||||
"Deck boards, cards and comments" : "Дошки колод, карти та коментарі",
|
||||
"From %1$s, in %2$s/%3$s, owned by %4$s" : "З %1$s, в %2$s/%3$s, у власності %4$s",
|
||||
"Create a new deck card" : "Створіть нову карту колоди",
|
||||
"Card comments" : "Коментарі до картки",
|
||||
"%s on %s" : "%s на %s",
|
||||
"Deck boards and cards" : "Колода та карти",
|
||||
"No data was provided to create an attachment." : "Для створення вкладення не було надано жодних даних.",
|
||||
"Finished" : "Завершено",
|
||||
"To review" : "На перегляд",
|
||||
"Action needed" : "Потребує дій",
|
||||
"Later" : "Пізніше",
|
||||
"copy" : "копіювати",
|
||||
"Read more inside" : "Читайте більше всередині",
|
||||
"Custom lists - click to rename!" : "Користувацькі списки - натисніть, щоб перейменувати!",
|
||||
"To Do" : "Зробити",
|
||||
"In Progress" : "В процесі",
|
||||
"Done" : "Готово",
|
||||
"1. Open to learn more about boards and cards" : "1. Відкриті, щоб дізнатися більше про дошки та картки",
|
||||
"2. Drag cards left and right, up and down" : "2. Перетягування карток вліво і вправо, вгору і вниз",
|
||||
"3. Apply rich formatting and link content" : "3. Застосовуйте багате форматування та посилання на вміст",
|
||||
"4. Share, comment and collaborate!" : "4. Діліться, коментуйте та співпрацюйте!",
|
||||
"Create your first card!" : "Створіть свою першу листівку!",
|
||||
"This comment has more than %s characters.\nAdded as an attachment to the card with name %s.\nAccessible on URL: %s." : "Цей коментар містить більше %s символів.\nДодано як вкладення до картки з іменем %s.\nДоступний за URL: %s.",
|
||||
"Attachments" : "Вкладення",
|
||||
"File" : "Файл",
|
||||
"date" : "дата",
|
||||
"Card not found" : "Картку не знайдено",
|
||||
"Path is already shared with this card" : "Шлях вже є спільним з цією карткою",
|
||||
"Invalid date, date format must be YYYY-MM-DD" : "Недійсна дата, формат дати має бути РРРР-ММ-ДД",
|
||||
"Personal planning and team project organization" : "Особисте планування та організація командних проектів",
|
||||
"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 - це інструмент організації в стилі канбан, призначений для особистого планування та організації проектів для команд, інтегрованих з Nextcloud.\n\n\n- 📥 Додавайте свої завдання на картки та впорядковуйте їх\n- 📄 Записуйте додаткові нотатки в Markdown\n- 🔖 Призначайте мітки для ще кращої організації\n- 👥 Діліться з командою, друзями чи родиною\n- Прикріплюйте файли та вбудовуйте їх в опис Markdown\n- 💬 Обговорюйте зі своєю командою за допомогою коментарів\n- ⚡ Відстежуйте зміни в потоці активностей\n- 🚀 Організуйте свій проект",
|
||||
"Add board" : "Додати дошку",
|
||||
"Card details" : "Деталі картки",
|
||||
"Select the board to link to a project" : "Виберіть дошку для прив'зки до проєкту",
|
||||
"Search by board title" : "Шукати за назвою дошки",
|
||||
"Select board" : "Вибрати дошку",
|
||||
"Move/copy card" : "Картка переміщення/копіювання",
|
||||
"Select a board" : "Вибрати дошку",
|
||||
"No lists available" : "Списки відсутні",
|
||||
"Select a list" : "Виберіть список",
|
||||
"Move card" : "Пересунути картку",
|
||||
"Copy card" : "Копіювальна картка",
|
||||
"Select the card to link to a project" : "Виберіть картку для прив'язки до проєкту",
|
||||
"Link to card" : "Прив'язати до картки",
|
||||
"Select a card" : "Вибрати картку",
|
||||
@@ -101,19 +159,27 @@
|
||||
"Filter by tag" : "Відібрати за мітками",
|
||||
"Filter by assigned user" : "Відібрати за призначеним користувачем",
|
||||
"Unassigned" : "Скасовано призначення",
|
||||
"Filter by status" : "Фільтр за статусом",
|
||||
"Open and completed" : "Відкрито та завершено",
|
||||
"Open" : "Відкрити",
|
||||
"Completed" : "Виконано",
|
||||
"Filter by due date" : "Відібрати за датою завершення",
|
||||
"Overdue" : "Протерміновано",
|
||||
"Next 24 hours" : "Наступні 24 години",
|
||||
"Next 7 days" : "Наступні 7 днів",
|
||||
"Next 30 days" : "Наступні 30 днів",
|
||||
"No due date" : "Без дати завершення",
|
||||
"Clear filter" : "Очистити фільтр",
|
||||
"View Modes" : "Режими перегляду",
|
||||
"Toggle View Modes" : "Перемикання режимів перегляду",
|
||||
"Hide archived cards" : "Приховати архівні картки",
|
||||
"Show archived cards" : "Показати архівні картки",
|
||||
"Toggle compact mode" : "Перемкнути компактний вигляд",
|
||||
"Hide card cover images" : "Приховати зображення обкладинок карток",
|
||||
"Show card cover images" : "Показати зображення обкладинки картки",
|
||||
"Open details" : "Показати деталі",
|
||||
"Details" : "Деталі",
|
||||
"Currently present people" : "Наразі присутні люди",
|
||||
"Loading board" : "Завантаження дошки",
|
||||
"Board not found" : "Дошку не знайдено",
|
||||
"Create a new list to add cards to this board" : "Створіть список щоб додати картки на цю дошку",
|
||||
@@ -124,35 +190,62 @@
|
||||
"Deleted lists" : "Вилучені списки",
|
||||
"Undo" : "Скасувати",
|
||||
"Deleted cards" : "Вилучені картки",
|
||||
"Failed to create share with {displayName}" : "Не вдалося створити спільний доступ з {displayName}",
|
||||
"Are you sure you want to transfer the board {title} to {user}?" : "Ви впевнені, що хочете перенести дошку {title} користувачеві {user}?",
|
||||
"Transfer the board." : "Перенесіть дошку.",
|
||||
"Transfer" : "Передати",
|
||||
"The board has been transferred to {user}" : "Дошка була передана {user}",
|
||||
"Failed to transfer the board to {user}" : "Не вдалося передати дошку користувачеві {user}",
|
||||
"Share board with a user, group or team …" : "Спільний доступ до дошки з користувачем, групою або командою ...",
|
||||
"Searching for users, groups and teams …" : "Пошук користувачів, груп і команд ...",
|
||||
"No participants found" : "Учасників не знайдено",
|
||||
"Board owner" : "Власник дошки",
|
||||
"(Group)" : "(група)",
|
||||
"(Team)" : "(Команда)",
|
||||
"Can edit" : "Може редагувати",
|
||||
"Can share" : "Can share",
|
||||
"Can manage" : "Може керувати",
|
||||
"Owner" : "Власник",
|
||||
"Delete" : "Вилучити",
|
||||
"List deleted" : "Список видалено",
|
||||
"Edit list title" : "Редагувати заголовок списку",
|
||||
"Archive all cards" : "Архівувати всі картки",
|
||||
"Unarchive all cards" : "Розархівувати всі картки",
|
||||
"Delete list" : "Вилучити список",
|
||||
"Archive all cards in this list" : "Архівуйте всі картки в цьому списку",
|
||||
"Unarchive all cards in this list" : "Розархівувати всі картки в цьому списку",
|
||||
"Add a new card" : "Додати нову картку",
|
||||
"Card name" : "Назва картки",
|
||||
"title and color value must be provided" : "потрібно зазначити назву та колір",
|
||||
"Edit" : "Редагувати",
|
||||
"Add a new tag" : "Додати нову мітку",
|
||||
"Board name" : "Назва дошки",
|
||||
"Members" : "Учасники",
|
||||
"Assign to users/groups/team" : "Призначити користувачам/групам/команді",
|
||||
"Assign a user to this card…" : "Призначити користувачеві цю картку",
|
||||
"Select a user to assign to this card…" : "Виберіть користувача, якого слід призначити на цю картку...",
|
||||
"File to share" : "Виберіть файл для надання доступу",
|
||||
"Invalid path selected" : "Вибрано неправильний шлях",
|
||||
"Upload new files" : "Додати файл",
|
||||
"Share from Files" : "Відкрити Файли",
|
||||
"Pending share" : "Очікувана акція",
|
||||
"Add this attachment" : "Долучити вкладення",
|
||||
"Show in Files" : "Показати в Файлах",
|
||||
"Download" : "Звантажити",
|
||||
"Remove attachment" : "Зніміть вкладення",
|
||||
"Delete Attachment" : "Забрати вкладення",
|
||||
"Restore Attachment" : "Відновити вкладення",
|
||||
"Modified" : "Змінено",
|
||||
"Created" : "Створено",
|
||||
"The title cannot be empty." : "Заголовок не може бути порожнім.",
|
||||
"Cannot close unsaved card!" : "Неможливо закрити незбережену картку!",
|
||||
"Open in sidebar view" : "Відкрити у вигляді бічної панелі",
|
||||
"Open in bigger view" : "Відкрити в більшому розмірі",
|
||||
"Comments" : "Коментарі",
|
||||
"Failed to load comments" : "Не вдалося завантажити коментарі",
|
||||
"No comments yet. Begin the discussion!" : "Коментарів немає, почніть обговорення!",
|
||||
"The comment cannot be empty." : "Коментар не може бути порожнім.",
|
||||
"The comment cannot be longer than 1000 characters." : "Коментар не може бути довшим за 1000 символів.",
|
||||
"Save" : "Зберегти",
|
||||
"Created:" : "Створено:",
|
||||
"In reply to" : "У відповідь",
|
||||
@@ -160,6 +253,7 @@
|
||||
"Reply" : "Відповісти",
|
||||
"Update" : "Оновлення",
|
||||
"Write a description …" : "Додайте опис ...",
|
||||
"Could not save description" : "Не вдалося зберегти опис",
|
||||
"Description" : "Опис",
|
||||
"(Unsaved)" : "(Не збережено)",
|
||||
"(Saving…)" : "(Зберігання...)",
|
||||
@@ -169,73 +263,150 @@
|
||||
"Add Attachment" : "Долучити вкладення",
|
||||
"Choose attachment" : "Вибрати вкладення",
|
||||
"Select Date" : "Вкажіть дату",
|
||||
"Later today – {timeLocale}" : "Пізніше сьогодні - {timeLocale}",
|
||||
"Set due date for later today" : "Встановіть термін сплати на сьогоднішній день",
|
||||
"Tomorrow – {timeLocale}" : "Завтра - {timeLocale}",
|
||||
"Set due date for tomorrow" : "Встановіть дедлайн на завтра",
|
||||
"This weekend – {timeLocale}" : "На цих вихідних - {timeLocale}",
|
||||
"Set due date for this weekend" : "Встановіть термін виконання на ці вихідні",
|
||||
"Next week – {timeLocale}" : "Наступного тижня - {timeLocale}",
|
||||
"Set due date for next week" : "Встановіть термін виконання на наступний тиждень",
|
||||
"Assign a due date to this card…" : "Призначте цій картці термін оплати...",
|
||||
"Set a due date" : "Встановити дату завершення",
|
||||
"Add due date" : "Додати термін сплати",
|
||||
"Choose a date" : "Виберіть дату",
|
||||
"Remove due date" : "Вилучити до",
|
||||
"Mark as done" : "Позначити як виконане",
|
||||
"Due at:" : "На часі:",
|
||||
"Not done" : "Ще не все.",
|
||||
"Unarchive card" : "Розархівувати картку",
|
||||
"Archive card" : "Архівувати картку",
|
||||
"Assign a tag to this card…" : "Додати мітку до цієї картки",
|
||||
"Select or create a tag…" : "Виберіть або створіть тег...",
|
||||
"Create a new tag:" : "Створіть новий тег:",
|
||||
"(group)" : "(група)",
|
||||
"{count} comments, {unread} unread" : "{count} коментарів, {unread} непрочитаних",
|
||||
"Todo items" : "Пункти завдань",
|
||||
"Edit card title" : "Редагувати заголовок картки",
|
||||
"Open link" : "Відкрити посилання",
|
||||
"Card deleted" : "Картку видалено",
|
||||
"Edit title" : "Редагувати",
|
||||
"Assign to me" : "Призначити мені",
|
||||
"Unassign myself" : "Зняти з себе повноваження.",
|
||||
"Mark as not done" : "Позначити як не виконано",
|
||||
"Delete card" : "Вилучити картку",
|
||||
"seconds ago" : "секунд тому",
|
||||
"Keyboard shortcuts" : "Скорочення",
|
||||
"Boost your productivity using Deck with keyboard shortcuts." : "Підвищуйте свою продуктивність, використовуючи Deck за допомогою комбінацій клавіш.",
|
||||
"Board actions" : "Дії правління",
|
||||
"Keyboard shortcut" : "Сполучення клавіш",
|
||||
"Action" : "Дія ",
|
||||
"Shift" : "Shift",
|
||||
"Scroll" : "Прокрутка",
|
||||
"Scroll sideways" : "Прокрутіть вбік",
|
||||
"Navigate between cards" : "Перехід між картками",
|
||||
"Esc" : "Esc",
|
||||
"Close card details" : "Закрити дані картки",
|
||||
"Ctrl" : "Ctrl",
|
||||
"Search" : "Пошук",
|
||||
"Show card filters" : "Показати фільтри карток",
|
||||
"Clear card filters" : "Очистити фільтри карток",
|
||||
"Show help dialog" : "Показати діалогове вікно довідки",
|
||||
"Card actions" : "Дії з карткою",
|
||||
"The following actions can be triggered on the currently highlighted card" : "На поточній виділеній картці можна виконати такі дії",
|
||||
"Enter" : "Ввід",
|
||||
"Space" : "Простір",
|
||||
"Open card details" : "Відкрити реквізити картки",
|
||||
"Edit the card title" : "Відредагуйте назву картки",
|
||||
"Assign yourself to the current card" : "Приєднайте себе до поточної картки",
|
||||
"Archive/unarchive the current card" : "Архівувати/розархівувати поточну картку",
|
||||
"Mark card as completed/not completed" : "Позначте картку як завершену/не завершену",
|
||||
"Open card menu" : "Відкрити меню картки",
|
||||
"All boards" : "Усі дошки",
|
||||
"Archived boards" : "Архівні дошки",
|
||||
"Shared with you" : "Вам надано доступ",
|
||||
"Deck settings" : "Налаштування колоди",
|
||||
"Use bigger card view" : "Режим перегляду зі збільшеними картками",
|
||||
"Show card ID badge" : "Покажіть бейдж з ідентифікаційною карткою",
|
||||
"Show boards in calendar/tasks" : "Показувати дошки в календарі та завданнях",
|
||||
"Limit board creation to some groups" : "Обмежити створення дошки для деяких груп",
|
||||
"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." : "Користувачі поза цими групами не зможуть створювати власні дошки, але зможуть працювати на дошках, до яких їм надано спільний доступ.",
|
||||
"Cancel edit" : "Скасувати редагування",
|
||||
"Save board" : "Зберегти дошку",
|
||||
"Board {0} deleted" : "Дошку {0} вилучено",
|
||||
"All cards" : "Всі карти",
|
||||
"Only assigned cards" : "Тільки призначені картки",
|
||||
"No reminder" : "Відсутні нагадування",
|
||||
"An error occurred" : "Виникла помилка",
|
||||
"Are you sure you want to delete the board {title}? This will delete all the data of this board including archived cards." : "Ви впевнені, що хочете вилучити дошку {title}? Це призведе до видалення всіх даних цієї дошки, включно архівні картки.",
|
||||
"Delete the board?" : "Вилучити дошку?",
|
||||
"Exporting board..." : "Експортна дошка...",
|
||||
"Board details" : "Деталі дошки",
|
||||
"Edit board" : "Редагувати дошку",
|
||||
"Clone board" : "Копіювати дошку",
|
||||
"Unarchive board" : "Розархівувати дошку",
|
||||
"Archive board" : "Архівувати дошку",
|
||||
"Export board" : "Дошка експорту",
|
||||
"Turn on due date reminders" : "Нагадування про термін виконання",
|
||||
"Turn off due date reminders" : "Вимкнути нагадування про терміни виконання",
|
||||
"Due date reminders" : "Нагадування про терміни виконання",
|
||||
"Assigned cards" : "Призначені картки",
|
||||
"No notifications" : "Немає сповіщень",
|
||||
"Delete board" : "Вилучити дошку",
|
||||
"Importing board..." : "Імпортна дошка...",
|
||||
"Board imported successfully" : "Плату успішно імпортовано",
|
||||
"Import board" : "Імпортна дошка",
|
||||
"Clone {boardTitle}" : "Клон {boardTitle}",
|
||||
"Clone cards" : "Копіювати картки",
|
||||
"Clone assignments" : "Призначення клонів",
|
||||
"Clone labels" : "Етикетки клонів",
|
||||
"Clone due dates" : "Клонувати дві дати",
|
||||
"Advanced options" : "Розширені налаштування",
|
||||
"Move all cards to the first list" : "Перемістіть усі картки до першого списку",
|
||||
"Restore archived cards" : "Відновлення заархівованих карток",
|
||||
"Clone" : "Копіювати",
|
||||
"Export {boardTitle}" : "Експорт {boardTitle}",
|
||||
"Export as JSON" : "Експорт як JSON",
|
||||
"Export as CSV" : "Експорт у CSV",
|
||||
"Note: Only the JSON format is supported for importing back into the Deck app." : "Примітка: Для імпорту в додаток Deck підтримується лише формат JSON.",
|
||||
"Export" : "Експортувати",
|
||||
"Loading filtered view" : "Завантаження відфільтрованого перегляду",
|
||||
"Today" : "Сьогодні",
|
||||
"Tomorrow" : "Завтра",
|
||||
"No due" : "Без призначеної дати",
|
||||
"Search for {searchQuery} in all boards" : "Шукати {searchQuery} на всіх дошках оголошень",
|
||||
"No results found" : "Не знайдено жодного результату",
|
||||
"Deck board {name}\n* Last modified on {lastMod}" : "Колода {name}\n* Востаннє змінено на {lastMod}",
|
||||
"* Created on {created}\n* Last modified on {lastMod}\n* {nbAttachments} attachments\n* {nbComments} comments" : "* Створено на {created}\n* Востаннє змінено на {lastMod}\n* {nbAttachments} вкладення\n* {nbComments} коментарі",
|
||||
"{nbCards} cards" : "{nbCards} картки",
|
||||
"Due on {date}" : "До {date}",
|
||||
"{stack} in {board}" : "{stack} в {board}",
|
||||
"Click to expand description" : "Натисніть, щоб розгорнути опис",
|
||||
"Click to expand comment" : "Натисніть, щоб розгорнути коментар",
|
||||
"Create card" : "Створити картку",
|
||||
"Create a new card" : "Створити нову картку",
|
||||
"Card title" : "Заголовок картки",
|
||||
"Creating the new card …" : "Створення нової картки ...",
|
||||
"Card \"{card}\" was added to \"{board}\"" : "Картку \"{card}\" додано до \"{board}\"",
|
||||
"Open card" : "Відкрити картку",
|
||||
"Close" : "Закрити",
|
||||
"No upcoming cards" : "Немає майбутніх завдань",
|
||||
"upcoming cards today" : "найближчі картки на сьогодні",
|
||||
"upcoming cards tomorrow" : "найближчі картки завтра",
|
||||
"upcoming cards" : "очікують на виконання",
|
||||
"New card" : "Нова картка",
|
||||
"Link to a board" : "Прив'язати до дошки",
|
||||
"Link to a card" : "Прив'язати до картки",
|
||||
"Create a card" : "Створити картку",
|
||||
"Message from {author} in {conversationName}" : "Повідомлення від {author} у {conversationName}",
|
||||
"Something went wrong" : "От халепа!",
|
||||
"Failed to upload {name}" : "Не вдалося завантажити {name}",
|
||||
"Maximum file size of {size} exceeded" : "Досягнуто максимальний розмір файлу {size}",
|
||||
"Assigned users" : "Призначені користувачі",
|
||||
"Due date" : "Дата виконання",
|
||||
"Error creating the share" : "Помилка створення спільного доступу",
|
||||
"Share with a Deck card" : "Поділіться з картою з колоди",
|
||||
"Share {file} with a Deck card" : "Поділіться {file} з картою колоди",
|
||||
"Share" : "Спільний доступ",
|
||||
"Personal" : "Особисте",
|
||||
"To do" : "Заплановано",
|
||||
|
||||
12
l10n/uz.js
12
l10n/uz.js
@@ -20,12 +20,12 @@ OC.L10N.register(
|
||||
"Card not found" : "Karta topilmadi",
|
||||
"Add board" : "Doska qo'shing",
|
||||
"Move card" : "Kartani ko'chirish",
|
||||
"Cancel" : "Cancel",
|
||||
"Cancel" : "Bekor qilish",
|
||||
"Add card" : "Karta qo'shing",
|
||||
"Archived cards" : "Arxivlangan kartalar",
|
||||
"Add list" : "Roʻyxat qoʻshish",
|
||||
"Unassigned" : "Tayinlanmagan",
|
||||
"Open" : "Open",
|
||||
"Open" : "Ochish",
|
||||
"Overdue" : "Muddati o'tgan",
|
||||
"Next 7 days" : "Keyingi 7 kun",
|
||||
"Next 30 days" : "Keyingi 30 kun",
|
||||
@@ -37,13 +37,13 @@ OC.L10N.register(
|
||||
"Undo" : "Bekor qilish",
|
||||
"Can edit" : "Can edit",
|
||||
"Owner" : "Owner",
|
||||
"Delete" : "Delete",
|
||||
"Delete" : "O'chirish",
|
||||
"Delete list" : "Roʻyxatni oʻchirish",
|
||||
"Edit" : "Tahrirlash",
|
||||
"Download" : "Download",
|
||||
"Download" : "Yuklab olish",
|
||||
"Modified" : "Modified",
|
||||
"Comments" : "Comments",
|
||||
"Save" : "Save",
|
||||
"Save" : "Saqlash",
|
||||
"In reply to" : "ga javoban",
|
||||
"Reply" : "Javob bering",
|
||||
"Update" : "Update",
|
||||
@@ -55,7 +55,7 @@ OC.L10N.register(
|
||||
"Edit title" : "Sarlavhani tahrirlash",
|
||||
"Delete card" : "Kartani o'chirish",
|
||||
"seconds ago" : "seconds ago",
|
||||
"Search" : "Search",
|
||||
"Search" : "Qidirish",
|
||||
"Archived boards" : "Arxivlangan taxtalar",
|
||||
"Shared with you" : "Shared with you",
|
||||
"No reminder" : "Eslatma yo'q",
|
||||
|
||||
12
l10n/uz.json
12
l10n/uz.json
@@ -18,12 +18,12 @@
|
||||
"Card not found" : "Karta topilmadi",
|
||||
"Add board" : "Doska qo'shing",
|
||||
"Move card" : "Kartani ko'chirish",
|
||||
"Cancel" : "Cancel",
|
||||
"Cancel" : "Bekor qilish",
|
||||
"Add card" : "Karta qo'shing",
|
||||
"Archived cards" : "Arxivlangan kartalar",
|
||||
"Add list" : "Roʻyxat qoʻshish",
|
||||
"Unassigned" : "Tayinlanmagan",
|
||||
"Open" : "Open",
|
||||
"Open" : "Ochish",
|
||||
"Overdue" : "Muddati o'tgan",
|
||||
"Next 7 days" : "Keyingi 7 kun",
|
||||
"Next 30 days" : "Keyingi 30 kun",
|
||||
@@ -35,13 +35,13 @@
|
||||
"Undo" : "Bekor qilish",
|
||||
"Can edit" : "Can edit",
|
||||
"Owner" : "Owner",
|
||||
"Delete" : "Delete",
|
||||
"Delete" : "O'chirish",
|
||||
"Delete list" : "Roʻyxatni oʻchirish",
|
||||
"Edit" : "Tahrirlash",
|
||||
"Download" : "Download",
|
||||
"Download" : "Yuklab olish",
|
||||
"Modified" : "Modified",
|
||||
"Comments" : "Comments",
|
||||
"Save" : "Save",
|
||||
"Save" : "Saqlash",
|
||||
"In reply to" : "ga javoban",
|
||||
"Reply" : "Javob bering",
|
||||
"Update" : "Update",
|
||||
@@ -53,7 +53,7 @@
|
||||
"Edit title" : "Sarlavhani tahrirlash",
|
||||
"Delete card" : "Kartani o'chirish",
|
||||
"seconds ago" : "seconds ago",
|
||||
"Search" : "Search",
|
||||
"Search" : "Qidirish",
|
||||
"Archived boards" : "Arxivlangan taxtalar",
|
||||
"Shared with you" : "Shared with you",
|
||||
"No reminder" : "Eslatma yo'q",
|
||||
|
||||
67
lib/Command/CalendarToggle.php
Normal file
67
lib/Command/CalendarToggle.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
namespace OCA\Deck\Command;
|
||||
|
||||
use OCP\IConfig;
|
||||
use OCP\IUserManager;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class CalendarToggle extends Command {
|
||||
private IUserManager $userManager;
|
||||
private IConfig $config;
|
||||
|
||||
public function __construct(IUserManager $userManager, IConfig $config) {
|
||||
parent::__construct();
|
||||
$this->userManager = $userManager;
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
protected function configure() {
|
||||
$this
|
||||
->setName('deck:calendar-toggle')
|
||||
->setDescription('Enable or disable Deck calendar/tasks integration for all existing users. Users can still change their own setting afterwards. Only affects users that already exist at the time of execution.')
|
||||
->addOption(
|
||||
'on',
|
||||
null,
|
||||
InputOption::VALUE_NONE,
|
||||
'Enable calendar/tasks integration for all existing users (users can opt-out later)'
|
||||
)
|
||||
->addOption(
|
||||
'off',
|
||||
null,
|
||||
InputOption::VALUE_NONE,
|
||||
'Disable calendar/tasks integration for all existing users (users can opt-in later)'
|
||||
);
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int {
|
||||
$enable = $input->getOption('on');
|
||||
$disable = $input->getOption('off');
|
||||
if ($enable && $disable) {
|
||||
$output->writeln('<error>Cannot use --on and --off together.</error>');
|
||||
return 1;
|
||||
}
|
||||
if (!$enable && !$disable) {
|
||||
$output->writeln('<error>Please specify either --on or --off.</error>');
|
||||
return 1;
|
||||
}
|
||||
$value = $enable ? 'yes' : '';
|
||||
$users = $this->userManager->search('');
|
||||
$count = 0;
|
||||
foreach ($users as $user) {
|
||||
$uid = $user->getUID();
|
||||
$this->config->setUserValue($uid, 'deck', 'calendar', $value);
|
||||
$output->writeln("Set calendar integration to '" . ($enable ? 'on' : 'off') . "' for user: $uid");
|
||||
$count++;
|
||||
}
|
||||
$output->writeln("Done. Updated $count existing users.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -65,11 +65,11 @@ class CardController extends Controller {
|
||||
$card = $this->cardService->create($title, $stackId, $type, $order, $this->userId, $description, $duedate);
|
||||
|
||||
foreach ($labels as $label) {
|
||||
$this->assignLabel($card->id, $label);
|
||||
$this->assignLabel($card->getId(), $label);
|
||||
}
|
||||
|
||||
foreach ($users as $user) {
|
||||
$this->assignmentService->assignUser($card->id, $user['id'], $user['type']);
|
||||
$this->assignmentService->assignUser($card->getId(), $user['id'], $user['type']);
|
||||
}
|
||||
|
||||
return $card;
|
||||
|
||||
@@ -45,8 +45,7 @@ class SessionMapper extends QBMapper {
|
||||
$qb->select('id', 'board_id', 'last_contact', 'user_id', 'token')
|
||||
->from($this->getTableName())
|
||||
->where($qb->expr()->eq('board_id', $qb->createNamedParameter($boardId)))
|
||||
->andWhere($qb->expr()->gt('last_contact', $qb->createNamedParameter(time() - SessionService::SESSION_VALID_TIME)))
|
||||
->executeQuery();
|
||||
->andWhere($qb->expr()->gt('last_contact', $qb->createNamedParameter(time() - SessionService::SESSION_VALID_TIME)));
|
||||
|
||||
return $this->findEntities($qb);
|
||||
}
|
||||
|
||||
@@ -320,14 +320,14 @@ class BoardService {
|
||||
return $board;
|
||||
}
|
||||
|
||||
private function applyPermissions($boardId, $edit, $share, $manage) {
|
||||
private function applyPermissions($boardId, $edit, $share, $manage, $oldAcl = null) {
|
||||
try {
|
||||
$this->permissionService->checkPermission($this->boardMapper, $boardId, Acl::PERMISSION_MANAGE);
|
||||
} catch (NoPermissionException $e) {
|
||||
$acls = $this->aclMapper->findAll($boardId);
|
||||
$edit = $this->permissionService->userCan($acls, Acl::PERMISSION_EDIT, $this->userId) && $edit;
|
||||
$share = $this->permissionService->userCan($acls, Acl::PERMISSION_SHARE, $this->userId) && $share;
|
||||
$manage = $this->permissionService->userCan($acls, Acl::PERMISSION_MANAGE, $this->userId) && $manage;
|
||||
$edit = $this->permissionService->userCan($acls, Acl::PERMISSION_EDIT, $this->userId) ? $edit : $oldAcl?->getPermissionEdit() ?? false;
|
||||
$share = $this->permissionService->userCan($acls, Acl::PERMISSION_SHARE, $this->userId) ? $share : $oldAcl?->getPermissionShare() ?? false;
|
||||
$manage = $this->permissionService->userCan($acls, Acl::PERMISSION_MANAGE, $this->userId) ? $manage : $oldAcl?->getPermissionManage() ?? false;
|
||||
}
|
||||
return [$edit, $share, $manage];
|
||||
}
|
||||
@@ -417,7 +417,7 @@ class BoardService {
|
||||
|
||||
/** @var Acl $acl */
|
||||
$acl = $this->aclMapper->find($id);
|
||||
[$edit, $share, $manage] = $this->applyPermissions($acl->getBoardId(), $edit, $share, $manage);
|
||||
[$edit, $share, $manage] = $this->applyPermissions($acl->getBoardId(), $edit, $share, $manage, $acl);
|
||||
$acl->setPermissionEdit($edit);
|
||||
$acl->setPermissionShare($share);
|
||||
$acl->setPermissionManage($manage);
|
||||
@@ -439,7 +439,7 @@ class BoardService {
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function deleteAcl(int $id): ?Acl {
|
||||
$this->permissionService->checkPermission($this->aclMapper, $id, Acl::PERMISSION_SHARE);
|
||||
$this->permissionService->checkPermission($this->aclMapper, $id, Acl::PERMISSION_MANAGE);
|
||||
/** @var Acl $acl */
|
||||
$acl = $this->aclMapper->find($id);
|
||||
$this->boardMapper->mapAcl($acl);
|
||||
@@ -621,7 +621,9 @@ class BoardService {
|
||||
|
||||
if ($fullDetails) {
|
||||
$this->enrichWithStacks($board);
|
||||
$this->enrichWithLabels($board);
|
||||
if ($board->getLabels() === null) {
|
||||
$this->enrichWithLabels($board);
|
||||
}
|
||||
$this->enrichWithUsers($board);
|
||||
$this->enrichWithBoardSettings($board);
|
||||
$this->enrichWithActiveSessions($board);
|
||||
|
||||
@@ -356,7 +356,7 @@ class CardService {
|
||||
if ($resetDuedateNotification) {
|
||||
$this->notificationHelper->markDuedateAsRead($card);
|
||||
}
|
||||
$this->changeHelper->cardChanged($card->getId(), true);
|
||||
$this->changeHelper->cardChanged($card->getId());
|
||||
|
||||
$this->eventDispatcher->dispatchTyped(new CardUpdatedEvent($card, $changes->getBefore()));
|
||||
|
||||
@@ -418,11 +418,12 @@ class CardService {
|
||||
if ($card->getArchived()) {
|
||||
throw new StatusException('Operation not allowed. This card is archived.');
|
||||
}
|
||||
$changes = new ChangeSet($card);
|
||||
$card->setTitle($title);
|
||||
$this->changeHelper->cardChanged($card->getId(), false);
|
||||
$update = $this->cardMapper->update($card);
|
||||
|
||||
$this->eventDispatcher->dispatchTyped(new CardUpdatedEvent($card));
|
||||
$this->eventDispatcher->dispatchTyped(new CardUpdatedEvent($card, $changes->getBefore()));
|
||||
|
||||
return $update;
|
||||
}
|
||||
@@ -441,7 +442,6 @@ class CardService {
|
||||
public function reorder($id, $stackId, $order) {
|
||||
$this->cardServiceValidator->check(compact('id', 'stackId', 'order'));
|
||||
|
||||
|
||||
$this->permissionService->checkPermission($this->cardMapper, $id, Acl::PERMISSION_EDIT);
|
||||
$this->permissionService->checkPermission($this->stackMapper, $stackId, Acl::PERMISSION_EDIT);
|
||||
|
||||
@@ -459,30 +459,30 @@ class CardService {
|
||||
$changes->setAfter($card);
|
||||
$this->activityManager->triggerUpdateEvents(ActivityManager::DECK_OBJECT_CARD, $changes, ActivityManager::SUBJECT_CARD_UPDATE);
|
||||
|
||||
$cards = $this->cardMapper->findAll($stackId);
|
||||
$cardsToReorder = $this->cardMapper->findAll($stackId);
|
||||
$result = [];
|
||||
$i = 0;
|
||||
foreach ($cards as $card) {
|
||||
if ($card->getArchived()) {
|
||||
foreach ($cardsToReorder as $cardToReorder) {
|
||||
if ($cardToReorder->getArchived()) {
|
||||
throw new StatusException('Operation not allowed. This card is archived.');
|
||||
}
|
||||
if ($card->id === $id) {
|
||||
$card->setOrder($order);
|
||||
$card->setLastModified(time());
|
||||
if ($cardToReorder->id === $id) {
|
||||
$cardToReorder->setOrder($order);
|
||||
$cardToReorder->setLastModified(time());
|
||||
}
|
||||
|
||||
if ($i === $order) {
|
||||
$i++;
|
||||
}
|
||||
|
||||
if ($card->id !== $id) {
|
||||
$card->setOrder($i++);
|
||||
if ($cardToReorder->id !== $id) {
|
||||
$cardToReorder->setOrder($i++);
|
||||
}
|
||||
$this->cardMapper->update($card);
|
||||
$result[$card->getOrder()] = $card;
|
||||
$this->cardMapper->update($cardToReorder);
|
||||
$result[$cardToReorder->getOrder()] = $cardToReorder;
|
||||
}
|
||||
$this->changeHelper->cardChanged($id, false);
|
||||
$this->eventDispatcher->dispatchTyped(new CardUpdatedEvent($card));
|
||||
$this->eventDispatcher->dispatchTyped(new CardUpdatedEvent($card, $changes->getBefore()));
|
||||
|
||||
return array_values($result);
|
||||
}
|
||||
@@ -499,19 +499,19 @@ class CardService {
|
||||
public function archive($id) {
|
||||
$this->cardServiceValidator->check(compact('id'));
|
||||
|
||||
|
||||
$this->permissionService->checkPermission($this->cardMapper, $id, Acl::PERMISSION_EDIT);
|
||||
if ($this->boardService->isArchived($this->cardMapper, $id)) {
|
||||
throw new StatusException('Operation not allowed. This board is archived.');
|
||||
}
|
||||
$card = $this->cardMapper->find($id);
|
||||
$changes = new ChangeSet($card);
|
||||
$card->setArchived(true);
|
||||
$newCard = $this->cardMapper->update($card);
|
||||
$this->notificationHelper->markDuedateAsRead($card);
|
||||
$this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_CARD, $newCard, ActivityManager::SUBJECT_CARD_UPDATE_ARCHIVE);
|
||||
$this->changeHelper->cardChanged($id, false);
|
||||
|
||||
$this->eventDispatcher->dispatchTyped(new CardUpdatedEvent($card));
|
||||
$this->eventDispatcher->dispatchTyped(new CardUpdatedEvent($card, $changes->getBefore()));
|
||||
|
||||
return $newCard;
|
||||
}
|
||||
@@ -534,12 +534,13 @@ class CardService {
|
||||
throw new StatusException('Operation not allowed. This board is archived.');
|
||||
}
|
||||
$card = $this->cardMapper->find($id);
|
||||
$changes = new ChangeSet($card);
|
||||
$card->setArchived(false);
|
||||
$newCard = $this->cardMapper->update($card);
|
||||
$this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_CARD, $newCard, ActivityManager::SUBJECT_CARD_UPDATE_UNARCHIVE);
|
||||
$this->changeHelper->cardChanged($id, false);
|
||||
|
||||
$this->eventDispatcher->dispatchTyped(new CardUpdatedEvent($card));
|
||||
$this->eventDispatcher->dispatchTyped(new CardUpdatedEvent($card, $changes->getBefore()));
|
||||
|
||||
return $newCard;
|
||||
}
|
||||
@@ -559,13 +560,14 @@ class CardService {
|
||||
throw new StatusException('Operation not allowed. This board is archived.');
|
||||
}
|
||||
$card = $this->cardMapper->find($id);
|
||||
$changes = new ChangeSet($card);
|
||||
$card->setDone(new \DateTime());
|
||||
$newCard = $this->cardMapper->update($card);
|
||||
$this->notificationHelper->markDuedateAsRead($card);
|
||||
$this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_CARD, $newCard, ActivityManager::SUBJECT_CARD_UPDATE_DONE);
|
||||
$this->changeHelper->cardChanged($id, false);
|
||||
|
||||
$this->eventDispatcher->dispatchTyped(new CardUpdatedEvent($card));
|
||||
$this->eventDispatcher->dispatchTyped(new CardUpdatedEvent($card, $changes->getBefore()));
|
||||
|
||||
return $newCard;
|
||||
}
|
||||
@@ -585,12 +587,13 @@ class CardService {
|
||||
throw new StatusException('Operation not allowed. This board is archived.');
|
||||
}
|
||||
$card = $this->cardMapper->find($id);
|
||||
$changes = new ChangeSet($card);
|
||||
$card->setDone(null);
|
||||
$newCard = $this->cardMapper->update($card);
|
||||
$this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_CARD, $newCard, ActivityManager::SUBJECT_CARD_UPDATE_UNDONE);
|
||||
$this->changeHelper->cardChanged($id, false);
|
||||
|
||||
$this->eventDispatcher->dispatchTyped(new CardUpdatedEvent($card));
|
||||
$this->eventDispatcher->dispatchTyped(new CardUpdatedEvent($card, $changes->getBefore()));
|
||||
|
||||
return $newCard;
|
||||
}
|
||||
@@ -652,9 +655,6 @@ class CardService {
|
||||
throw new StatusException('Operation not allowed. This card is archived.');
|
||||
}
|
||||
$label = $this->labelMapper->find($labelId);
|
||||
if ($label->getBoardId() !== $this->cardMapper->findBoardId($card->getId())) {
|
||||
throw new StatusException('Operation not allowed. Label does not exist.');
|
||||
}
|
||||
$this->cardMapper->removeLabel($cardId, $labelId);
|
||||
$this->changeHelper->cardChanged($cardId);
|
||||
$this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_CARD, $card, ActivityManager::SUBJECT_LABEL_UNASSING, ['label' => $label]);
|
||||
|
||||
@@ -214,7 +214,7 @@ class PermissionService {
|
||||
}
|
||||
|
||||
try {
|
||||
$board = $this->boardMapper->find($boardId);
|
||||
$board = $this->getBoard($boardId);
|
||||
} catch (DoesNotExistException $e) {
|
||||
return [];
|
||||
} catch (MultipleObjectsReturnedException $e) {
|
||||
@@ -227,7 +227,7 @@ class PermissionService {
|
||||
} else {
|
||||
$users[$board->getOwner()] = new User($board->getOwner(), $this->userManager);
|
||||
}
|
||||
$acls = $this->aclMapper->findAll($boardId);
|
||||
$acls = $board->getAcl();
|
||||
/** @var Acl $acl */
|
||||
foreach ($acls as $acl) {
|
||||
if ($acl->getType() === Acl::PERMISSION_TYPE_USER) {
|
||||
|
||||
12751
package-lock.json
generated
12751
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
33
package.json
33
package.json
@@ -31,22 +31,19 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/polyfill": "^7.12.1",
|
||||
"@babel/runtime": "^7.27.0",
|
||||
"@babel/runtime": "^7.27.1",
|
||||
"@nextcloud/auth": "^2.4.0",
|
||||
"@nextcloud/axios": "^2.5.1",
|
||||
"@nextcloud/capabilities": "^1.2.0",
|
||||
"@nextcloud/dialogs": "^7.0.0-rc.1",
|
||||
"@nextcloud/dialogs": "^6.0.1",
|
||||
"@nextcloud/event-bus": "^3.3.2",
|
||||
"@nextcloud/files": "^3.10.1",
|
||||
"@nextcloud/initial-state": "^2.2.0",
|
||||
"@nextcloud/l10n": "^3.1.0",
|
||||
"@nextcloud/moment": "^1.3.2",
|
||||
"@nextcloud/moment": "^1.3.4",
|
||||
"@nextcloud/notify_push": "^1.3.0",
|
||||
"@nextcloud/router": "^3.0.1",
|
||||
"@nextcloud/vue": "^9.0.0-rc.3",
|
||||
"@vue/compiler-sfc": "^3.5.13",
|
||||
"@vue/vue3-jest": "^29.2.6",
|
||||
"@vueuse/core": "^13.1.0",
|
||||
"@nextcloud/vue": "^8.27.0",
|
||||
"blueimp-md5": "^2.19.0",
|
||||
"chroma-js": "^3.1.2",
|
||||
"dompurify": "^3.2.5",
|
||||
@@ -57,14 +54,16 @@
|
||||
"moment": "^2.30.1",
|
||||
"p-queue": "^8.0.1",
|
||||
"url-search-params-polyfill": "^8.2.5",
|
||||
"v3-infinite-loading": "^1.3.2",
|
||||
"vue": "^3.5.13",
|
||||
"vue": "^2.7.15",
|
||||
"vue-at": "^2.5.1",
|
||||
"vue-click-outside": "^1.1.0",
|
||||
"vue-easymde": "^2.0.0",
|
||||
"vue-infinite-loading": "^2.4.5",
|
||||
"vue-material-design-icons": "^5.3.1",
|
||||
"vue-router": "^4.5.0",
|
||||
"vue3-smooth-dnd": "^0.0.6",
|
||||
"vuex": "^4.1.0"
|
||||
"vue-router": "^3.6.5",
|
||||
"vue-smooth-dnd": "^0.8.1",
|
||||
"vuex": "^3.6.2",
|
||||
"vuex-router-sync": "^5.0.0"
|
||||
},
|
||||
"browserslist": [
|
||||
"extends @nextcloud/browserslist-config"
|
||||
@@ -76,18 +75,20 @@
|
||||
"devDependencies": {
|
||||
"@nextcloud/babel-config": "^1.2.0",
|
||||
"@nextcloud/browserslist-config": "^3.0.1",
|
||||
"@nextcloud/cypress": "^1.0.0-beta.13",
|
||||
"@nextcloud/cypress": "^1.0.0-beta.15",
|
||||
"@nextcloud/eslint-config": "^8.4.2",
|
||||
"@nextcloud/stylelint-config": "^3.0.1",
|
||||
"@nextcloud/webpack-vue-config": "github:nextcloud-libraries/webpack-vue-config#vue3",
|
||||
"@relative-ci/agent": "^4.2.14",
|
||||
"@nextcloud/webpack-vue-config": "^6.3.0",
|
||||
"@relative-ci/agent": "^4.3.1",
|
||||
"@vue/test-utils": "^2.4.6",
|
||||
"@vue/vue2-jest": "^29.2.6",
|
||||
"cypress": "^13.17.0",
|
||||
"eslint-plugin-cypress": "^3.6.0",
|
||||
"eslint-webpack-plugin": "^5.0.1",
|
||||
"jest": "^29.7.0",
|
||||
"jest-serializer-vue": "^3.1.0",
|
||||
"stylelint-webpack-plugin": "^5.0.1"
|
||||
"stylelint-webpack-plugin": "^5.0.1",
|
||||
"vue-template-compiler": "^2.7.16"
|
||||
},
|
||||
"jest": {
|
||||
"moduleFileExtensions": [
|
||||
|
||||
213
src/App.vue
213
src/App.vue
@@ -1,51 +1,15 @@
|
||||
<!--
|
||||
- SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
|
||||
- SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
|
||||
- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
-->
|
||||
<script>
|
||||
import { NcAppContent, NcContent, NcModal } from '@nextcloud/vue'
|
||||
import CardMoveDialog from './CardMoveDialog.vue'
|
||||
import AppNavigation from './components/navigation/AppNavigation.vue'
|
||||
import KeyboardShortcuts from './components/KeyboardShortcuts.vue'
|
||||
import { BoardApi } from './services/BoardApi.js'
|
||||
|
||||
const boardApi = new BoardApi()
|
||||
|
||||
export default {
|
||||
name: 'App',
|
||||
components: {
|
||||
NcContent,
|
||||
AppNavigation,
|
||||
NcAppContent,
|
||||
KeyboardShortcuts,
|
||||
CardMoveDialog,
|
||||
NcModal,
|
||||
},
|
||||
provide() {
|
||||
return {
|
||||
boardApi,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
cardDetailsInModal() {
|
||||
return this.$store.getters.config('cardDetailsInModal')
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
hideModal() {
|
||||
this.$router.push({ name: 'board' })
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NcContent app-name="deck">
|
||||
<NcContent app-name="deck" :class="{ 'nav-hidden': !navShown, 'sidebar-hidden': !sidebarRouterView }">
|
||||
<AppNavigation />
|
||||
<NcAppContent :allow-swipe-navigation="false">
|
||||
<router-view />
|
||||
</NcAppContent>
|
||||
|
||||
<div v-if="$route.params.id || $route.params.cardId">
|
||||
<NcModal v-if="cardDetailsInModal && $route.params.cardId"
|
||||
:name="t('deck', 'Card details')"
|
||||
@@ -57,10 +21,179 @@ export default {
|
||||
<router-view name="sidebar" />
|
||||
</div>
|
||||
</NcModal>
|
||||
|
||||
<router-view name="sidebar" :visible="!cardDetailsInModal || !$route.params.cardId" />
|
||||
</div>
|
||||
|
||||
<KeyboardShortcuts />
|
||||
<CardMoveDialog />
|
||||
</NcContent>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
import AppNavigation from './components/navigation/AppNavigation.vue'
|
||||
import KeyboardShortcuts from './components/KeyboardShortcuts.vue'
|
||||
import { NcModal, NcContent, NcAppContent, isMobile } from '@nextcloud/vue'
|
||||
import { BoardApi } from './services/BoardApi.js'
|
||||
import { emit, subscribe } from '@nextcloud/event-bus'
|
||||
import { loadState } from '@nextcloud/initial-state'
|
||||
import CardMoveDialog from './CardMoveDialog.vue'
|
||||
|
||||
const boardApi = new BoardApi()
|
||||
|
||||
export default {
|
||||
name: 'App',
|
||||
components: {
|
||||
CardMoveDialog,
|
||||
AppNavigation,
|
||||
NcModal,
|
||||
NcContent,
|
||||
NcAppContent,
|
||||
KeyboardShortcuts,
|
||||
},
|
||||
mixins: [isMobile],
|
||||
provide() {
|
||||
return {
|
||||
boardApi,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
addButton: {
|
||||
icon: 'icon-add',
|
||||
classes: [],
|
||||
text: t('deck', 'Add board'),
|
||||
edit: {
|
||||
text: t('deck', 'Add board'),
|
||||
action: () => {
|
||||
},
|
||||
reset: () => {
|
||||
},
|
||||
},
|
||||
action: () => {
|
||||
this.addButton.classes.push('editing')
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
navShown: state => state.navShown,
|
||||
sidebarShownState: state => state.sidebarShown,
|
||||
currentBoard: state => state.currentBoard,
|
||||
}),
|
||||
// TODO: properly handle sidebar showing for route subview and board sidebar
|
||||
sidebarRouterView() {
|
||||
// console.log(this.$route)
|
||||
return this.$route.name === 'card' || this.$route.name === 'board.details'
|
||||
},
|
||||
sidebarShown() {
|
||||
return this.sidebarRouterView || this.sidebarShownState
|
||||
},
|
||||
cardDetailsInModal: {
|
||||
get() {
|
||||
return this.$store.getters.config('cardDetailsInModal')
|
||||
},
|
||||
set(newValue) {
|
||||
this.$store.dispatch('setConfig', { cardDetailsInModal: newValue })
|
||||
},
|
||||
},
|
||||
},
|
||||
created() {
|
||||
const initialState = loadState('deck', 'initialBoards', null)
|
||||
if (initialState !== null) {
|
||||
this.$store.dispatch('loadBoards')
|
||||
}
|
||||
this.$store.dispatch('loadSharees')
|
||||
},
|
||||
mounted() {
|
||||
// Set navigation to initial state and update in case it gets toggled
|
||||
emit('toggle-navigation', { open: !this.isMobile && this.navShown, _initial: true })
|
||||
this.$nextTick(() => {
|
||||
subscribe('navigation-toggled', (navState) => {
|
||||
this.$store.dispatch('toggleNav', navState.open)
|
||||
})
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
hideModal() {
|
||||
this.$router.push({ name: 'board' })
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
#content-vue {
|
||||
#app-content {
|
||||
transition: margin-left 100ms ease;
|
||||
position: relative;
|
||||
overflow-x: hidden;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
#app-sidebar {
|
||||
transition: max-width 100ms ease;
|
||||
}
|
||||
|
||||
&.nav-hidden {
|
||||
#app-content {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.sidebar-hidden {
|
||||
#app-sidebar {
|
||||
max-width: 0;
|
||||
min-width: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
@import '../css/print';
|
||||
|
||||
.icon-activity {
|
||||
background-image: url(../img/activity-dark.svg);
|
||||
|
||||
body[data-theme-dark] & {
|
||||
background-image: url(../img/activity.svg);
|
||||
}
|
||||
}
|
||||
|
||||
.avatardiv.circles {
|
||||
background: var(--color-primary-element);
|
||||
}
|
||||
|
||||
.icon-circles {
|
||||
background-image: url(../img/circles-dark.svg);
|
||||
opacity: 1;
|
||||
background-size: 20px;
|
||||
background-position: center center;
|
||||
}
|
||||
|
||||
.icon-circles-white, .icon-circles.icon-white {
|
||||
background-image: url(../img/circles.svg);
|
||||
opacity: 1;
|
||||
background-size: 20px;
|
||||
background-position: center center;
|
||||
}
|
||||
|
||||
.icon-colorpicker {
|
||||
background-image: url('../img/color_picker.svg');
|
||||
}
|
||||
|
||||
.v-select {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.modal__card {
|
||||
width: 100%;
|
||||
min-width: 100%;
|
||||
height: calc(100% - 20px);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -22,10 +22,10 @@
|
||||
label="title" />
|
||||
</div>
|
||||
<template #actions>
|
||||
<NcButton :disabled="!isBoardAndStackChoosen" variant="secondary" @click="moveCard">
|
||||
<NcButton :disabled="!isBoardAndStackChoosen" type="secondary" @click="moveCard">
|
||||
{{ t('deck', 'Move card') }}
|
||||
</NcButton>
|
||||
<NcButton :disabled="!isBoardAndStackChoosen" variant="primary" @click="cloneCard">
|
||||
<NcButton :disabled="!isBoardAndStackChoosen" type="primary" @click="cloneCard">
|
||||
{{ t('deck', 'Copy card') }}
|
||||
</NcButton>
|
||||
</template>
|
||||
@@ -72,7 +72,7 @@ export default {
|
||||
mounted() {
|
||||
subscribe('deck:card:show-move-dialog', this.openModal)
|
||||
},
|
||||
unmounted() {
|
||||
destroyed() {
|
||||
unsubscribe('deck:card:show-move-dialog', this.openModal)
|
||||
},
|
||||
methods: {
|
||||
|
||||
@@ -10,15 +10,9 @@
|
||||
:key="activity.activity_id"
|
||||
:activity="activity" />
|
||||
<InfiniteLoading :identifier="objectId" @infinite="infiniteHandler" @change="changeObject">
|
||||
<template #spinner>
|
||||
<div class="icon-loading" />
|
||||
</template>
|
||||
<template #no-more>
|
||||
<div />
|
||||
</template>
|
||||
<template #no-results>
|
||||
<div />
|
||||
</template>
|
||||
<div slot="spinner" class="icon-loading" />
|
||||
<div slot="no-more" />
|
||||
<div slot="no-results" />
|
||||
</InfiniteLoading>
|
||||
</div>
|
||||
</template>
|
||||
@@ -27,7 +21,7 @@
|
||||
import axios from '@nextcloud/axios'
|
||||
import { generateOcsUrl } from '@nextcloud/router'
|
||||
import ActivityEntry from './ActivityEntry.vue'
|
||||
// import InfiniteLoading from 'v3-infinite-loading'
|
||||
import InfiniteLoading from 'vue-infinite-loading'
|
||||
|
||||
const ACTIVITY_FETCH_LIMIT = 50
|
||||
|
||||
@@ -35,6 +29,7 @@ export default {
|
||||
name: 'ActivityList',
|
||||
components: {
|
||||
ActivityEntry,
|
||||
InfiniteLoading,
|
||||
},
|
||||
props: {
|
||||
filter: {
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
:title="t('deck', 'Apply filter')"
|
||||
:aria-label="t('deck', 'Apply filter')"
|
||||
class="filter-button"
|
||||
:variant="isFilterActive ? 'primary' : 'tertiary'">
|
||||
:type="isFilterActive ? 'primary' : 'tertiary'">
|
||||
<template #icon>
|
||||
<FilterIcon v-if="isFilterActive" :size="20" decorative />
|
||||
<FilterOffIcon v-else :size="20" decorative />
|
||||
@@ -231,16 +231,12 @@
|
||||
</NcActionButton>
|
||||
<NcActionButton v-if="compactMode"
|
||||
@click="toggleCompactMode">
|
||||
<template #icon>
|
||||
<ArrowExpandVerticalIcon :size="20" decorative />
|
||||
</template>
|
||||
<ArrowExpandVerticalIcon slot="icon" :size="20" decorative />
|
||||
{{ t('deck', 'Toggle compact mode') }}
|
||||
</NcActionButton>
|
||||
<NcActionButton v-else
|
||||
@click="toggleCompactMode">
|
||||
<template #icon>
|
||||
<ArrowCollapseVerticalIcon :size="20" decorative />
|
||||
</template>
|
||||
<ArrowCollapseVerticalIcon slot="icon" :size="20" decorative />
|
||||
{{ t('deck', 'Toggle compact mode') }}
|
||||
</NcActionButton>
|
||||
<NcActionButton @click="toggleShowCardCover">
|
||||
@@ -267,10 +263,10 @@ import { mapState, mapGetters } from 'vuex'
|
||||
import { subscribe, unsubscribe } from '@nextcloud/event-bus'
|
||||
import { NcActions, NcActionButton, NcAvatar, NcButton, NcPopover, NcModal } from '@nextcloud/vue'
|
||||
import labelStyle from '../mixins/labelStyle.js'
|
||||
import ArchiveIcon from 'vue-material-design-icons/Archive.vue'
|
||||
import ImageIcon from 'vue-material-design-icons/ImageMultiple.vue'
|
||||
import FilterIcon from 'vue-material-design-icons/Filter.vue'
|
||||
import FilterOffIcon from 'vue-material-design-icons/FilterOff.vue'
|
||||
import ArchiveIcon from 'vue-material-design-icons/ArchiveOutline.vue'
|
||||
import ImageIcon from 'vue-material-design-icons/ImageMultipleOutline.vue'
|
||||
import FilterIcon from 'vue-material-design-icons/FilterOutline.vue'
|
||||
import FilterOffIcon from 'vue-material-design-icons/FilterOffOutline.vue'
|
||||
import TableColumnPlusAfter from 'vue-material-design-icons/TableColumnPlusAfter.vue'
|
||||
import ArrowCollapseVerticalIcon from 'vue-material-design-icons/ArrowCollapseVertical.vue'
|
||||
import ArrowExpandVerticalIcon from 'vue-material-design-icons/ArrowExpandVertical.vue'
|
||||
@@ -278,7 +274,6 @@ import SessionList from './SessionList.vue'
|
||||
import { isNotifyPushEnabled } from '../sessions.js'
|
||||
import CreateNewCardCustomPicker from '../views/CreateNewCardCustomPicker.vue'
|
||||
import { getCurrentUser } from '@nextcloud/auth'
|
||||
import { onClickOutside } from '@vueuse/core'
|
||||
|
||||
export default {
|
||||
name: 'Controls',
|
||||
@@ -364,11 +359,6 @@ export default {
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
onClickOutside(() => {
|
||||
this.hideAddStack()
|
||||
})
|
||||
},
|
||||
beforeMount() {
|
||||
subscribe('deck:board:show-new-card', this.clickShowAddCardModel)
|
||||
subscribe('deck:board:toggle-filter-popover', this.triggerOpenFilters)
|
||||
@@ -376,7 +366,7 @@ export default {
|
||||
subscribe('deck:board:toggle-filter-by-me', this.triggerFilterByMe)
|
||||
|
||||
},
|
||||
beforeUnmount() {
|
||||
beforeDestroy() {
|
||||
unsubscribe('deck:board:show-new-card', this.clickShowAddCardModel)
|
||||
unsubscribe('deck:board:toggle-filter-popover', this.triggerOpenFilters)
|
||||
unsubscribe('deck:board:clear-filter', this.triggerClearFilter)
|
||||
@@ -518,6 +508,20 @@ export default {
|
||||
|
||||
#stack-add form {
|
||||
display: flex;
|
||||
|
||||
#new-stack-input-main {
|
||||
margin-right: 8px;
|
||||
}
|
||||
.icon-confirm {
|
||||
border: 2px solid var(--color-border-maxcontrast) !important;
|
||||
border-left: none !important;
|
||||
}
|
||||
&:focus-within, &:focus, &:focus-visible,
|
||||
&:hover {
|
||||
.icon-confirm {
|
||||
border-color: var(--color-main-text) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<!-- :style="{top:cardTop, left:cardLeft}" -->
|
||||
<div v-if="card && selector"
|
||||
ref="shortcutModal"
|
||||
v-click-outside="close"
|
||||
class="keyboard-shortcuts__modal"
|
||||
tabindex="0"
|
||||
@keydown.esc="close">
|
||||
@@ -17,7 +18,6 @@
|
||||
</template>
|
||||
<script>
|
||||
import DueDateSelector from './card/DueDateSelector.vue'
|
||||
import { onClickOutside } from '@vueuse/core'
|
||||
import { emit, subscribe, unsubscribe } from '@nextcloud/event-bus'
|
||||
import { mapState } from 'vuex'
|
||||
import TagSelector from './card/TagSelector.vue'
|
||||
@@ -50,9 +50,8 @@ export default {
|
||||
subscribe('deck:card:show-assignment-selector', this.handleShowAssignemnt)
|
||||
subscribe('deck:card:show-due-date-selector', this.handleShowDueDate)
|
||||
subscribe('deck:card:show-label-selector', this.handleShowLabel)
|
||||
onClickOutside(this.close)
|
||||
},
|
||||
unmounted() {
|
||||
destroyed() {
|
||||
document.removeEventListener('keydown', this.onKeydown)
|
||||
unsubscribe('deck:card:show-assignment-selector', this.handleShowAssignemnt)
|
||||
unsubscribe('deck:card:show-due-date-selector', this.handleShowDueDate)
|
||||
|
||||
@@ -29,12 +29,12 @@
|
||||
{{ t('deck', 'Create a new list to add cards to this board') }}
|
||||
<form @submit.prevent="addNewStack()">
|
||||
<NcTextField ref="newStackInput"
|
||||
v-model="newStackTitle"
|
||||
:disable="loading"
|
||||
:value.sync="newStackTitle"
|
||||
:placeholder="t('deck', 'List name')"
|
||||
type="text" />
|
||||
<NcButton variant="secondary"
|
||||
type="submit"
|
||||
<NcButton type="secondary"
|
||||
native-type="submit"
|
||||
:disabled="loading"
|
||||
:title="t('deck', 'Add list')">
|
||||
<template #icon>
|
||||
@@ -63,10 +63,7 @@
|
||||
data-click-closes-sidebar="true"
|
||||
data-dragscroll-enabled
|
||||
class="stack-draggable-wrapper">
|
||||
<Stack :stack="stack"
|
||||
:dragging="draggingStack"
|
||||
data-click-closes-sidebar="true"
|
||||
@open-card="openCard" />
|
||||
<Stack :stack="stack" :dragging="draggingStack" data-click-closes-sidebar="true" />
|
||||
</Draggable>
|
||||
</Container>
|
||||
</div>
|
||||
@@ -85,7 +82,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Container, Draggable } from 'vue3-smooth-dnd'
|
||||
import { Container, Draggable } from 'vue-smooth-dnd'
|
||||
import { mapState, mapGetters } from 'vuex'
|
||||
import Controls from '../Controls.vue'
|
||||
import DeckIcon from '../icons/DeckIcon.vue'
|
||||
@@ -168,14 +165,14 @@ export default {
|
||||
created() {
|
||||
this.session = createSession(this.id)
|
||||
this.fetchData()
|
||||
this.$root.$on('open-card', (cardId) => {
|
||||
this.localModal = cardId
|
||||
})
|
||||
},
|
||||
beforeUnmount() {
|
||||
beforeDestroy() {
|
||||
this.session.close()
|
||||
},
|
||||
methods: {
|
||||
openCard(cardId) {
|
||||
|
||||
},
|
||||
async fetchData() {
|
||||
this.loading = true
|
||||
try {
|
||||
@@ -256,8 +253,8 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@use '../../css/animations';
|
||||
@use '../../css/variables';
|
||||
@import '../../css/animations';
|
||||
@import '../../css/variables';
|
||||
|
||||
form {
|
||||
text-align: center;
|
||||
@@ -285,7 +282,7 @@ export default {
|
||||
}
|
||||
|
||||
.board {
|
||||
padding-left: variables.$board-spacing;
|
||||
padding-left: $board-spacing;
|
||||
position: relative;
|
||||
max-height: calc(100% - var(--default-clickable-area));
|
||||
overflow: hidden;
|
||||
@@ -316,8 +313,8 @@ export default {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
// Margin left instead of padidng to avoid jumps on dropping a card
|
||||
margin-left: variables.$stack-spacing;
|
||||
padding-right: variables.$stack-spacing;
|
||||
margin-left: $stack-spacing;
|
||||
padding-right: $stack-spacing;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
padding-top: 15px;
|
||||
|
||||
@@ -56,9 +56,9 @@ import DeletedTabSidebar from './DeletedTabSidebar.vue'
|
||||
import TimelineTabSidebar from './TimelineTabSidebar.vue'
|
||||
import { NcAppSidebar, NcAppSidebarTab } from '@nextcloud/vue'
|
||||
import ActivityIcon from 'vue-material-design-icons/LightningBolt.vue'
|
||||
import SharingIcon from 'vue-material-design-icons/ShareVariant.vue'
|
||||
import TagsIcon from 'vue-material-design-icons/TagMultiple.vue'
|
||||
import TrashIcon from 'vue-material-design-icons/Delete.vue'
|
||||
import SharingIcon from 'vue-material-design-icons/ShareVariantOutline.vue'
|
||||
import TagsIcon from 'vue-material-design-icons/TagMultipleOutline.vue'
|
||||
import TrashIcon from 'vue-material-design-icons/DeleteOutline.vue'
|
||||
const capabilities = window.OC.getCapabilities()
|
||||
|
||||
export default {
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
non-drag-area-selector=".dragDisabled"
|
||||
:drag-handle-selector="dragHandleSelector"
|
||||
data-dragscroll-enabled
|
||||
:should-accept-drop="() => canEdit"
|
||||
@should-accept-drop="canEdit"
|
||||
@drag-start="draggingCard = true"
|
||||
@drag-end="draggingCard = false"
|
||||
@drop="($event) => onDropCard(stack.id, $event)">
|
||||
@@ -102,10 +102,7 @@
|
||||
<transition :appear="animate && !card.animated && (card.animated=true)"
|
||||
:appear-class="'zoom-appear-class'"
|
||||
:appear-active-class="'zoom-appear-active-class'">
|
||||
<CardItem :id="card.id"
|
||||
ref="card"
|
||||
:dragging="draggingCard"
|
||||
@open-card="openCard" />
|
||||
<CardItem :id="card.id" ref="card" :dragging="draggingCard" />
|
||||
</transition>
|
||||
</Draggable>
|
||||
</Container>
|
||||
@@ -139,8 +136,8 @@
|
||||
<script>
|
||||
import ClickOutside from 'vue-click-outside'
|
||||
import { mapGetters, mapState } from 'vuex'
|
||||
import { Container, Draggable } from 'vue3-smooth-dnd'
|
||||
import ArchiveIcon from 'vue-material-design-icons/Archive.vue'
|
||||
import { Container, Draggable } from 'vue-smooth-dnd'
|
||||
import ArchiveIcon from 'vue-material-design-icons/ArchiveOutline.vue'
|
||||
import CardPlusOutline from 'vue-material-design-icons/CardPlusOutline.vue'
|
||||
import { NcActions, NcActionButton, NcModal } from '@nextcloud/vue'
|
||||
import { showError, showUndo } from '@nextcloud/dialogs'
|
||||
@@ -174,9 +171,6 @@ export default {
|
||||
default: undefined,
|
||||
},
|
||||
},
|
||||
emits: [
|
||||
'open-card',
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
editing: false,
|
||||
@@ -239,9 +233,6 @@ export default {
|
||||
},
|
||||
|
||||
methods: {
|
||||
openCard(cardId) {
|
||||
this.$emit('open-card', cardId)
|
||||
},
|
||||
stopCardCreation(e) {
|
||||
// For some reason the submit event triggers a MouseEvent that is bubbling to the outside
|
||||
// so we have to ignore it
|
||||
@@ -371,10 +362,10 @@ export default {
|
||||
|
||||
@use 'sass:math';
|
||||
|
||||
@use './../../css/variables';
|
||||
@import './../../css/variables';
|
||||
|
||||
.stack {
|
||||
width: variables.$stack-width + variables.$stack-spacing * 3;
|
||||
width: $stack-width + $stack-spacing * 3;
|
||||
}
|
||||
|
||||
.stack__header {
|
||||
@@ -382,8 +373,8 @@ export default {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
padding-left: variables.$card-spacing;
|
||||
padding-right: variables.$card-spacing;
|
||||
padding-left: $card-spacing;
|
||||
padding-right: $card-spacing;
|
||||
margin: 6px;
|
||||
margin-top: 0;
|
||||
cursor: grab;
|
||||
@@ -427,7 +418,7 @@ export default {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: calc(variables.$stack-width - 60px);
|
||||
max-width: calc($stack-width - 60px);
|
||||
border-radius: 3px;
|
||||
padding: 4px 4px;
|
||||
font-size: var(--default-font-size);
|
||||
@@ -468,8 +459,8 @@ export default {
|
||||
|
||||
form {
|
||||
display: flex;
|
||||
margin-left: variables.$stack-spacing;
|
||||
margin-right: variables.$stack-spacing;
|
||||
margin-left: $stack-spacing;
|
||||
margin-right: $stack-spacing;
|
||||
width: 100%;
|
||||
border: 2px solid var(--color-border-maxcontrast);
|
||||
border-radius: var(--border-radius-large);
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
<script>
|
||||
import { defineComponent } from 'vue'
|
||||
import { NcAvatar, NcSelect } from '@nextcloud/vue'
|
||||
import AccountMultiple from 'vue-material-design-icons/AccountMultiple.vue'
|
||||
import AccountMultiple from 'vue-material-design-icons/AccountMultipleOutline.vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'AssignmentSelector',
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
-->
|
||||
|
||||
<!-- eslint-disable vue/no-v-model-argument -->
|
||||
<template>
|
||||
<NcAppSidebar v-if="currentBoard && currentCard"
|
||||
ref="cardSidebar"
|
||||
v-model:name-editable="isEditingTitle"
|
||||
:active="tabId"
|
||||
:name="displayTitle"
|
||||
:subname="subtitle"
|
||||
:subtitle="subtitleTooltip"
|
||||
@update:name="value => titleEditing = value"
|
||||
:name-editable.sync="isEditingTitle"
|
||||
@update:name="(value) => titleEditing = value"
|
||||
@update:active="(value) => activeTabId = value"
|
||||
@dismiss-editing="titleEditing = currentCard.title"
|
||||
@submit-name="handleSubmitTitle"
|
||||
@opened="focusHeader"
|
||||
@@ -25,71 +25,39 @@
|
||||
{{ t('deck', 'Open in bigger view') }}
|
||||
</NcActionButton>
|
||||
|
||||
<NcActionButton v-if="canEdit && !isCurrentUserAssigned"
|
||||
icon="icon-user"
|
||||
:close-after-click="true"
|
||||
@click="assignCardToMe()">
|
||||
{{ t('deck', 'Assign to me') }}
|
||||
</NcActionButton>
|
||||
<NcActionButton v-if="canEdit && isCurrentUserAssigned"
|
||||
icon="icon-user"
|
||||
:close-after-click="true"
|
||||
@click="unassignCardFromMe()">
|
||||
{{ t('deck', 'Unassign myself') }}
|
||||
</NcActionButton>
|
||||
<NcActionButton v-if="canEdit"
|
||||
icon="icon-checkmark"
|
||||
:close-after-click="true"
|
||||
@click="changeCardDoneStatus()">
|
||||
{{ currentCard.done ? t('deck', 'Mark as not done') : t('deck', 'Mark as done') }}
|
||||
</NcActionButton>
|
||||
<NcActionButton v-if="canEdit"
|
||||
icon="icon-external"
|
||||
:close-after-click="true"
|
||||
@click="openCardMoveDialog">
|
||||
{{ t('deck', 'Move/copy card') }}
|
||||
</NcActionButton>
|
||||
<NcActionButton v-for="action in cardActions"
|
||||
:key="action.label"
|
||||
:close-after-click="true"
|
||||
:icon="action.icon"
|
||||
@click="action.callback(cardRichObject)">
|
||||
{{ action.label }}
|
||||
</NcActionButton>
|
||||
<NcActionButton v-if="canEditBoard" :close-after-click="true" @click="archiveUnarchiveCard()">
|
||||
<template #icon>
|
||||
<ArchiveIcon :size="20" decorative />
|
||||
</template>
|
||||
{{ currentCard.archived ? t('deck', 'Unarchive card') : t('deck', 'Archive card') }}
|
||||
</NcActionButton>
|
||||
<NcActionButton v-if="canEdit"
|
||||
icon="icon-delete"
|
||||
:close-after-click="true"
|
||||
@click="deleteCard()">
|
||||
{{ t('deck', 'Delete card') }}
|
||||
</NcActionButton>
|
||||
<CardMenuEntries :card="currentCard" :hide-details-entry="true" />
|
||||
</template>
|
||||
<template #description>
|
||||
<NcReferenceList v-if="currentCard.referenceData" :text="currentCard.title" :interactive="false" />
|
||||
<NcReferenceList v-if="currentCard.referenceData"
|
||||
:text="currentCard.title"
|
||||
:interactive="false" />
|
||||
</template>
|
||||
|
||||
<NcAppSidebarTab id="details" :order="0" :name="t('deck', 'Details')">
|
||||
<NcAppSidebarTab id="details"
|
||||
:order="0"
|
||||
:name="t('deck', 'Details')">
|
||||
<CardSidebarTabDetails :card="currentCard" />
|
||||
<template #icon>
|
||||
<HomeIcon :size="20" />
|
||||
<HomeIcon v-if="activeTabId === 'details'" :size="20" />
|
||||
<HomeOutlineIcon v-else :size="20" />
|
||||
</template>
|
||||
</NcAppSidebarTab>
|
||||
|
||||
<NcAppSidebarTab id="attachments" :order="1" :name="t('deck', 'Attachments')">
|
||||
<NcAppSidebarTab id="attachments"
|
||||
:order="1"
|
||||
:name="t('deck', 'Attachments')">
|
||||
<template #icon>
|
||||
<AttachmentIcon :size="20" />
|
||||
</template>
|
||||
<CardSidebarTabAttachments :card="currentCard" />
|
||||
</NcAppSidebarTab>
|
||||
|
||||
<NcAppSidebarTab id="comments" :order="2" :name="t('deck', 'Comments')">
|
||||
<NcAppSidebarTab id="comments"
|
||||
:order="2"
|
||||
:name="t('deck', 'Comments')">
|
||||
<template #icon>
|
||||
<CommentIcon :size="20" />
|
||||
<CommentIcon v-if="activeTabId === 'comments'" :size="20" />
|
||||
<CommentOutlineIcon v-else :size="20" />
|
||||
</template>
|
||||
<CardSidebarTabComments :card="currentCard" :tab-query="tabQuery" />
|
||||
</NcAppSidebarTab>
|
||||
@@ -108,7 +76,7 @@
|
||||
|
||||
<script>
|
||||
import { NcActionButton, NcAppSidebar, NcAppSidebarTab } from '@nextcloud/vue'
|
||||
import { NcReferenceList } from '@nextcloud/vue/components/NcRichText'
|
||||
import { NcReferenceList } from '@nextcloud/vue/dist/Components/NcRichText.js'
|
||||
import { getCapabilities } from '@nextcloud/capabilities'
|
||||
import { mapState, mapGetters } from 'vuex'
|
||||
import CardSidebarTabDetails from './CardSidebarTabDetails.vue'
|
||||
@@ -119,18 +87,14 @@ import relativeDate from '../../mixins/relativeDate.js'
|
||||
import moment from '@nextcloud/moment'
|
||||
import AttachmentIcon from 'vue-material-design-icons/Paperclip.vue'
|
||||
import HomeIcon from 'vue-material-design-icons/Home.vue'
|
||||
import HomeOutlineIcon from 'vue-material-design-icons/HomeOutline.vue'
|
||||
import CommentIcon from 'vue-material-design-icons/Comment.vue'
|
||||
import CommentOutlineIcon from 'vue-material-design-icons/CommentOutline.vue'
|
||||
import ActivityIcon from 'vue-material-design-icons/LightningBolt.vue'
|
||||
|
||||
import { showError, showWarning, showUndo } from '@nextcloud/dialogs'
|
||||
import { showError, showWarning } from '@nextcloud/dialogs'
|
||||
import { getLocale } from '@nextcloud/l10n'
|
||||
import { emit } from '@nextcloud/event-bus'
|
||||
|
||||
import ArchiveIcon from 'vue-material-design-icons/Archive.vue'
|
||||
import { getCurrentUser } from '@nextcloud/auth'
|
||||
import { generateUrl } from '@nextcloud/router'
|
||||
|
||||
import '@nextcloud/dialogs/style.css'
|
||||
import CardMenuEntries from '../cards/CardMenuEntries.vue'
|
||||
|
||||
const capabilities = getCapabilities()
|
||||
|
||||
@@ -148,8 +112,10 @@ export default {
|
||||
ActivityIcon,
|
||||
AttachmentIcon,
|
||||
CommentIcon,
|
||||
CommentOutlineIcon,
|
||||
HomeIcon,
|
||||
ArchiveIcon,
|
||||
HomeOutlineIcon,
|
||||
CardMenuEntries,
|
||||
},
|
||||
mixins: [relativeDate],
|
||||
props: {
|
||||
@@ -174,6 +140,7 @@ export default {
|
||||
titleEditing: '',
|
||||
hasActivity: capabilities && capabilities.activity,
|
||||
locale: getLocale(),
|
||||
activeTabId: this.tabId || 'details',
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -181,17 +148,8 @@ export default {
|
||||
isFullApp: (state) => state.isFullApp,
|
||||
currentBoard: (state) => state.currentBoard,
|
||||
hasCardSaveError: (state) => state.hasCardSaveError,
|
||||
showArchived: (state) => state.showArchived,
|
||||
}),
|
||||
...mapGetters([
|
||||
'canEdit',
|
||||
'assignables',
|
||||
'cardActions',
|
||||
'stackById',
|
||||
'isArchived',
|
||||
'boards',
|
||||
'boardById',
|
||||
]),
|
||||
...mapGetters(['canEdit', 'assignables', 'cardActions', 'stackById']),
|
||||
currentCard() {
|
||||
return this.$store.getters.cardById(this.id)
|
||||
},
|
||||
@@ -218,31 +176,6 @@ export default {
|
||||
return reference ? reference.openGraphObject.name : this.currentCard.title
|
||||
},
|
||||
},
|
||||
canEdit() {
|
||||
return !this.currentCard.archived
|
||||
},
|
||||
canEditBoard() {
|
||||
if (this.currentBoard) {
|
||||
return this.$store.getters.canEdit
|
||||
}
|
||||
const board = this.$store.getters.boards.find((item) => item.id === this.currentCard.boardId)
|
||||
return !!board?.permissions?.PERMISSION_EDIT
|
||||
},
|
||||
isCurrentUserAssigned() {
|
||||
return this.currentCard.assignedUsers.find((item) => item.type === 0 && item.participant.uid === getCurrentUser()?.uid)
|
||||
},
|
||||
boardId() {
|
||||
return this.card?.boardId ? this.currentCard.boardId : Number(this.$route.params.id)
|
||||
},
|
||||
cardRichObject() {
|
||||
return {
|
||||
id: '' + this.currentCard.id,
|
||||
name: this.currentCard.title,
|
||||
boardname: this.boardById(this.boardId)?.title,
|
||||
stackname: this.stackById(this.currentCard.stackId)?.title,
|
||||
link: window.location.protocol + '//' + window.location.host + generateUrl('/apps/deck/') + `card/${this.currentCard.id}`,
|
||||
}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
currentCard() {
|
||||
@@ -291,46 +224,12 @@ export default {
|
||||
formatDate(timestamp) {
|
||||
return moment.unix(timestamp).locale(this.locale).format('LLLL')
|
||||
},
|
||||
deleteCard() {
|
||||
this.$store.dispatch('deleteCard', this.currentCard)
|
||||
const undoCard = { ...this.currentCard, deletedAt: 0 }
|
||||
showUndo(t('deck', 'Card deleted'), () => this.$store.dispatch('cardUndoDelete', undoCard))
|
||||
if (this.$router.currentRoute.name === 'card') {
|
||||
this.$router.push({ name: 'board' })
|
||||
}
|
||||
},
|
||||
changeCardDoneStatus() {
|
||||
this.$store.dispatch('changeCardDoneStatus', { ...this.currentCard, done: !this.currentCard.done })
|
||||
},
|
||||
archiveUnarchiveCard() {
|
||||
this.$store.dispatch('archiveUnarchiveCard', { ...this.currentCard, archived: !this.currentCard.archived })
|
||||
},
|
||||
assignCardToMe() {
|
||||
this.$store.dispatch('assignCardToUser', {
|
||||
card: this.currentCard,
|
||||
assignee: {
|
||||
userId: getCurrentUser()?.uid,
|
||||
type: 0,
|
||||
},
|
||||
})
|
||||
},
|
||||
unassignCardFromMe() {
|
||||
this.$store.dispatch('removeUserFromCard', {
|
||||
card: this.currentCard,
|
||||
assignee: {
|
||||
userId: getCurrentUser()?.uid,
|
||||
type: 0,
|
||||
},
|
||||
})
|
||||
},
|
||||
openCardMoveDialog() {
|
||||
emit('deck:card:show-move-dialog', this.currentCard)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
section.app-sidebar__tab--active {
|
||||
min-height: auto;
|
||||
display: flex;
|
||||
@@ -382,7 +281,6 @@ section.app-sidebar__tab--active {
|
||||
z-index: 100;
|
||||
background-color: var(--color-main-background);
|
||||
}
|
||||
|
||||
.app-sidebar-tabs__nav {
|
||||
position: sticky;
|
||||
top: 87px;
|
||||
@@ -395,10 +293,10 @@ section.app-sidebar__tab--active {
|
||||
overflow: initial;
|
||||
}
|
||||
|
||||
#emptycontent,
|
||||
.emptycontent {
|
||||
#emptycontent, .emptycontent {
|
||||
margin-top: 88px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -23,11 +23,11 @@
|
||||
:key="comment.id"
|
||||
:comment="comment"
|
||||
@doReload="loadComments" />
|
||||
<!-- <InfiniteLoading :identifier="card.id" @infinite="infiniteHandler">
|
||||
<InfiniteLoading :identifier="card.id" @infinite="infiniteHandler">
|
||||
<div slot="spinner" class="icon-loading" />
|
||||
<div slot="no-more" />
|
||||
<div slot="no-results" />
|
||||
</InfiniteLoading> -->
|
||||
</InfiniteLoading>
|
||||
</ul>
|
||||
<div v-else-if="isLoading" class="icon icon-loading" />
|
||||
<div v-else class="emptycontent">
|
||||
@@ -42,7 +42,7 @@ import { mapState, mapGetters } from 'vuex'
|
||||
import { NcAvatar } from '@nextcloud/vue'
|
||||
import CommentItem from './CommentItem.vue'
|
||||
import CommentForm from './CommentForm.vue'
|
||||
// import InfiniteLoading from 'v3-infinite-loading'
|
||||
import InfiniteLoading from 'vue-infinite-loading'
|
||||
import { getCurrentUser } from '@nextcloud/auth'
|
||||
|
||||
export default {
|
||||
@@ -51,7 +51,7 @@ export default {
|
||||
NcAvatar,
|
||||
CommentItem,
|
||||
CommentForm,
|
||||
// InfiniteLoading,
|
||||
InfiniteLoading,
|
||||
},
|
||||
props: {
|
||||
card: {
|
||||
|
||||
@@ -2,13 +2,8 @@
|
||||
- SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
|
||||
- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
-->
|
||||
<template>
|
||||
<div>
|
||||
THIS HAS AT
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- <template>
|
||||
<template>
|
||||
<div class="comment-form">
|
||||
<form @submit.prevent="submit">
|
||||
<At ref="at"
|
||||
@@ -196,4 +191,4 @@ export default {
|
||||
.atwho-li--avatar {
|
||||
margin-right: 10px;
|
||||
}
|
||||
</style> -->
|
||||
</style>
|
||||
|
||||
@@ -82,7 +82,7 @@ import CommentForm from './CommentForm.vue'
|
||||
import { getCurrentUser } from '@nextcloud/auth'
|
||||
import md5 from 'blueimp-md5'
|
||||
import relativeDate from '../../mixins/relativeDate.js'
|
||||
import ReplyIcon from 'vue-material-design-icons/Reply.vue'
|
||||
import ReplyIcon from 'vue-material-design-icons/ReplyOutline.vue'
|
||||
import moment from 'moment'
|
||||
|
||||
const AtMention = {
|
||||
|
||||
@@ -175,7 +175,7 @@ export default {
|
||||
mounted() {
|
||||
this.setupEditor()
|
||||
},
|
||||
async beforeUnmount() {
|
||||
async beforeDestroy() {
|
||||
await this.destroyEditor()
|
||||
},
|
||||
methods: {
|
||||
|
||||
@@ -4,12 +4,8 @@
|
||||
-->
|
||||
<template>
|
||||
<CardDetailEntry :label="t('deck', 'Assign a due date to this card…')" data-test="due-date-selector">
|
||||
<template v-if="!card.done" #icon>
|
||||
<Calendar :size="20" />
|
||||
</template>
|
||||
<template v-else #icon>
|
||||
<CalendarCheck :size="20" />
|
||||
</template>
|
||||
<Calendar v-if="!card.done" slot="icon" :size="20" />
|
||||
<CalendarCheck v-else slot="icon" :size="20" />
|
||||
<template v-if="!card.done && !card.archived">
|
||||
<NcDateTimePickerNative v-if="duedate"
|
||||
id="card-duedate-picker"
|
||||
@@ -19,7 +15,7 @@
|
||||
type="datetime-local" />
|
||||
<NcActions v-if="canEdit"
|
||||
:menu-title="!duedate ? t('deck', 'Add due date') : null"
|
||||
variant="tertiary"
|
||||
type="tertiary"
|
||||
data-cy-due-date-actions>
|
||||
<template v-if="!duedate" #icon>
|
||||
<Plus :size="20" />
|
||||
@@ -52,7 +48,7 @@
|
||||
</NcActions>
|
||||
|
||||
<NcButton v-if="!card.done"
|
||||
variant="secondary"
|
||||
type="secondary"
|
||||
class="completed-button"
|
||||
@click="changeCardDoneStatus()">
|
||||
<template #icon>
|
||||
@@ -73,14 +69,14 @@
|
||||
</div>
|
||||
<div class="due-actions">
|
||||
<NcButton v-if="!card.archived"
|
||||
variant="tertiary"
|
||||
type="tertiary"
|
||||
:name="t('deck', 'Not done')"
|
||||
@click="changeCardDoneStatus()">
|
||||
<template #icon>
|
||||
<ClearIcon :size="20" />
|
||||
</template>
|
||||
</NcButton>
|
||||
<NcButton variant="secondary" @click="archiveUnarchiveCard()">
|
||||
<NcButton type="secondary" @click="archiveUnarchiveCard()">
|
||||
<template #icon>
|
||||
<ArchiveIcon :size="20" />
|
||||
</template>
|
||||
@@ -103,10 +99,10 @@ import {
|
||||
import readableDate from '../../mixins/readableDate.js'
|
||||
import { getDayNamesMin, getFirstDay, getMonthNamesShort } from '@nextcloud/l10n'
|
||||
import moment from '@nextcloud/moment'
|
||||
import ArchiveIcon from 'vue-material-design-icons/Archive.vue'
|
||||
import ArchiveIcon from 'vue-material-design-icons/ArchiveOutline.vue'
|
||||
import Plus from 'vue-material-design-icons/Plus.vue'
|
||||
import Calendar from 'vue-material-design-icons/Calendar.vue'
|
||||
import CalendarCheck from 'vue-material-design-icons/CalendarCheck.vue'
|
||||
import Calendar from 'vue-material-design-icons/CalendarOutline.vue'
|
||||
import CalendarCheck from 'vue-material-design-icons/CalendarCheckOutline.vue'
|
||||
import CheckIcon from 'vue-material-design-icons/Check.vue'
|
||||
import ClearIcon from 'vue-material-design-icons/Close.vue'
|
||||
import CardDetailEntry from './CardDetailEntry.vue'
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<div class="selector-wrapper--icon">
|
||||
<TagMultiple :size="20" />
|
||||
</div>
|
||||
<NcSelect v-model="assignedLabels"
|
||||
<NcSelect :value="assignedLabels"
|
||||
class="selector-wrapper--selector"
|
||||
:multiple="true"
|
||||
:disabled="disabled"
|
||||
@@ -44,7 +44,7 @@
|
||||
<script>
|
||||
import { NcSelect } from '@nextcloud/vue'
|
||||
import Color from '../../mixins/color.js'
|
||||
import TagMultiple from 'vue-material-design-icons/TagMultiple.vue'
|
||||
import TagMultiple from 'vue-material-design-icons/TagMultipleOutline.vue'
|
||||
|
||||
export default {
|
||||
name: 'TagSelector',
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
<script>
|
||||
import { NcAvatar, NcPopover } from '@nextcloud/vue'
|
||||
import { generateUrl } from '@nextcloud/router'
|
||||
import AccountMultiple from 'vue-material-design-icons/AccountMultiple.vue'
|
||||
import AccountMultiple from 'vue-material-design-icons/AccountMultipleOutline.vue'
|
||||
|
||||
export default {
|
||||
name: 'AvatarList',
|
||||
|
||||
@@ -49,8 +49,8 @@ import CardId from './badges/CardId.vue'
|
||||
import TextIcon from 'vue-material-design-icons/Text.vue'
|
||||
import AttachmentIcon from 'vue-material-design-icons/Paperclip.vue'
|
||||
import CheckmarkIcon from 'vue-material-design-icons/CheckboxMarked.vue'
|
||||
import CommentIcon from 'vue-material-design-icons/Comment.vue'
|
||||
import CommentUnreadIcon from 'vue-material-design-icons/CommentAccount.vue'
|
||||
import CommentIcon from 'vue-material-design-icons/CommentOutline.vue'
|
||||
import CommentUnreadIcon from 'vue-material-design-icons/CommentAccountOutline.vue'
|
||||
import DueDate from './badges/DueDate.vue'
|
||||
|
||||
export default {
|
||||
|
||||
@@ -72,7 +72,7 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@use '../../css/variables';
|
||||
@import '../../css/variables';
|
||||
|
||||
.card-cover {
|
||||
height: 90px;
|
||||
|
||||
@@ -88,7 +88,6 @@ import CardMenu from './CardMenu.vue'
|
||||
import CardCover from './CardCover.vue'
|
||||
import DueDate from './badges/DueDate.vue'
|
||||
import { getCurrentUser } from '@nextcloud/auth'
|
||||
import { emit } from '@nextcloud/event-bus'
|
||||
|
||||
const TITLE_EDITING_STATE = {
|
||||
OFF: 0,
|
||||
@@ -121,7 +120,6 @@ export default {
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
emits: ['open-card'],
|
||||
data() {
|
||||
return {
|
||||
highlight: false,
|
||||
@@ -228,9 +226,8 @@ export default {
|
||||
this.$router.push({ name: 'card', params: { id: boardId, cardId: this.card.id } }).catch(() => {})
|
||||
return
|
||||
}
|
||||
emit('open-card', {
|
||||
cardId: this.card.id,
|
||||
})
|
||||
|
||||
this.$root.$emit('open-card', this.card.id)
|
||||
},
|
||||
triggerEditTitle() {
|
||||
this.editingTitle = TITLE_EDITING_STATE.PENDING
|
||||
@@ -321,8 +318,8 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@use './../../css/animations';
|
||||
@use './../../css/variables';
|
||||
@import './../../css/animations';
|
||||
@import './../../css/variables';
|
||||
|
||||
@mixin dark-card {
|
||||
border: 2px solid var(--color-border-dark);
|
||||
@@ -334,8 +331,8 @@ export default {
|
||||
border-radius: var(--border-radius-large);
|
||||
font-size: 100%;
|
||||
background-color: var(--color-main-background);
|
||||
margin-bottom: variables.$card-spacing;
|
||||
padding: var(--default-grid-baseline) variables.$card-padding;
|
||||
margin-bottom: $card-spacing;
|
||||
padding: var(--default-grid-baseline) $card-padding;
|
||||
border: 2px solid var(--color-border-dark);
|
||||
width: 100%;
|
||||
display: flex;
|
||||
@@ -473,7 +470,7 @@ export default {
|
||||
width: 32px;
|
||||
}
|
||||
&.has-labels {
|
||||
padding-bottom: variables.$card-padding;
|
||||
padding-bottom: $card-padding;
|
||||
}
|
||||
.labels {
|
||||
height: 6px;
|
||||
|
||||
@@ -6,190 +6,40 @@
|
||||
<template>
|
||||
<div v-if="card" class="card-menu" @click.stop.prevent>
|
||||
<NcButton v-if="card.referenceData"
|
||||
variant="tertiary"
|
||||
:title="t('deck', 'Open link')"
|
||||
type="tertiary"
|
||||
:title="t('deck','Open link')"
|
||||
@click="openLink">
|
||||
<template #icon>
|
||||
<LinkIcon :size="20" />
|
||||
</template>
|
||||
</NcButton>
|
||||
<NcActions>
|
||||
<NcActionButton v-if="!hideDetailsEntry" :close-after-click="true" @click="openCard">
|
||||
<template #icon>
|
||||
<CardBulletedIcon icon :size="20" decorative />
|
||||
</template>
|
||||
{{ t('deck', 'Card details') }}
|
||||
</NcActionButton>
|
||||
<NcActionButton v-if="canEdit" :close-after-click="true" @click="editTitle">
|
||||
<template #icon>
|
||||
<PencilIcon :size="20" decorative />
|
||||
</template>
|
||||
{{ t('deck', 'Edit title') }}
|
||||
</NcActionButton>
|
||||
<NcActionButton v-if="canEdit && !isCurrentUserAssigned"
|
||||
icon="icon-user"
|
||||
:close-after-click="true"
|
||||
@click="assignCardToMe()">
|
||||
{{ t('deck', 'Assign to me') }}
|
||||
</NcActionButton>
|
||||
<NcActionButton v-if="canEdit && isCurrentUserAssigned"
|
||||
icon="icon-user"
|
||||
:close-after-click="true"
|
||||
@click="unassignCardFromMe()">
|
||||
{{ t('deck', 'Unassign myself') }}
|
||||
</NcActionButton>
|
||||
<NcActionButton v-if="canEdit"
|
||||
icon="icon-checkmark"
|
||||
:close-after-click="true"
|
||||
@click="changeCardDoneStatus()">
|
||||
{{ card.done ? t('deck', 'Mark as not done') : t('deck', 'Mark as done') }}
|
||||
</NcActionButton>
|
||||
<NcActionButton v-if="canEdit"
|
||||
icon="icon-external"
|
||||
:close-after-click="true"
|
||||
@click="openCardMoveDialog">
|
||||
{{ t('deck', 'Move/copy card') }}
|
||||
</NcActionButton>
|
||||
<NcActionButton v-for="action in cardActions"
|
||||
:key="action.label"
|
||||
:close-after-click="true"
|
||||
:icon="action.icon"
|
||||
@click="action.callback(cardRichObject)">
|
||||
{{ action.label }}
|
||||
</NcActionButton>
|
||||
<NcActionButton v-if="canEditBoard" :close-after-click="true" @click="archiveUnarchiveCard()">
|
||||
<template #icon>
|
||||
<ArchiveIcon :size="20" decorative />
|
||||
</template>
|
||||
{{ card.archived ? t('deck', 'Unarchive card') : t('deck', 'Archive card') }}
|
||||
</NcActionButton>
|
||||
<NcActionButton v-if="canEdit"
|
||||
icon="icon-delete"
|
||||
:close-after-click="true"
|
||||
@click="deleteCard()">
|
||||
{{ t('deck', 'Delete card') }}
|
||||
</NcActionButton>
|
||||
<CardMenuEntries :card="card" @edit-title="editTitle" />
|
||||
</NcActions>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { NcActions, NcButton, NcActionButton } from '@nextcloud/vue'
|
||||
import { NcActions, NcButton } from '@nextcloud/vue'
|
||||
import LinkIcon from 'vue-material-design-icons/Link.vue'
|
||||
import ArchiveIcon from 'vue-material-design-icons/Archive.vue'
|
||||
import { getCurrentUser } from '@nextcloud/auth'
|
||||
import CardBulletedIcon from 'vue-material-design-icons/CardBulleted.vue'
|
||||
import PencilIcon from 'vue-material-design-icons/Pencil.vue'
|
||||
import { mapGetters, mapState } from 'vuex'
|
||||
import { showUndo } from '@nextcloud/dialogs'
|
||||
import { generateUrl } from '@nextcloud/router'
|
||||
|
||||
import '@nextcloud/dialogs/style.css'
|
||||
import { emit } from '@nextcloud/event-bus'
|
||||
import CardMenuEntries from './CardMenuEntries.vue'
|
||||
|
||||
export default {
|
||||
name: 'CardMenu',
|
||||
components: { NcActions, NcButton, LinkIcon, NcActionButton, PencilIcon, CardBulletedIcon, ArchiveIcon },
|
||||
components: { NcActions, NcButton, LinkIcon, CardMenuEntries },
|
||||
props: {
|
||||
card: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
hideDetailsEntry: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
emits: ['edit-title'],
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'isArchived',
|
||||
'boards',
|
||||
'cardActions',
|
||||
'stackById',
|
||||
'boardById',
|
||||
]),
|
||||
...mapState({
|
||||
showArchived: state => state.showArchived,
|
||||
currentBoard: state => state.currentBoard,
|
||||
}),
|
||||
canEdit() {
|
||||
return !this.card.archived
|
||||
},
|
||||
canEditBoard() {
|
||||
if (this.currentBoard) {
|
||||
return this.$store.getters.canEdit
|
||||
}
|
||||
const board = this.$store.getters.boards.find((item) => item.id === this.card.boardId)
|
||||
return !!board?.permissions?.PERMISSION_EDIT
|
||||
},
|
||||
isCurrentUserAssigned() {
|
||||
return this.card.assignedUsers.find((item) => item.type === 0 && item.participant.uid === getCurrentUser()?.uid)
|
||||
},
|
||||
boardId() {
|
||||
return this.card?.boardId ? this.card.boardId : Number(this.$route.params.id)
|
||||
},
|
||||
cardRichObject() {
|
||||
return {
|
||||
id: '' + this.card.id,
|
||||
name: this.card.title,
|
||||
boardname: this.boardById(this.boardId)?.title,
|
||||
stackname: this.stackById(this.card.stackId)?.title,
|
||||
link: window.location.protocol + '//' + window.location.host + generateUrl('/apps/deck/') + `card/${this.card.id}`,
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
openLink() {
|
||||
window.open(this.card?.referenceData?.openGraphObject?.link)
|
||||
return false
|
||||
},
|
||||
openCard() {
|
||||
const boardId = this.card?.boardId ? this.card.boardId : this.$route?.params.id ?? this.currentBoard.id
|
||||
|
||||
if (this.$router) {
|
||||
this.$router?.push({ name: 'card', params: { id: boardId, cardId: this.card.id } }).catch(() => { })
|
||||
return
|
||||
}
|
||||
|
||||
this.$root.$emit('open-card', this.card.id)
|
||||
},
|
||||
editTitle() {
|
||||
this.$emit('edit-title', this.card.id)
|
||||
},
|
||||
deleteCard() {
|
||||
this.$store.dispatch('deleteCard', this.card)
|
||||
const undoCard = { ...this.card, deletedAt: 0 }
|
||||
showUndo(t('deck', 'Card deleted'), () => this.$store.dispatch('cardUndoDelete', undoCard))
|
||||
if (this.$router.currentRoute.name === 'card') {
|
||||
this.$router.push({ name: 'board' })
|
||||
}
|
||||
},
|
||||
changeCardDoneStatus() {
|
||||
this.$store.dispatch('changeCardDoneStatus', { ...this.card, done: !this.card.done })
|
||||
},
|
||||
archiveUnarchiveCard() {
|
||||
this.$store.dispatch('archiveUnarchiveCard', { ...this.card, archived: !this.card.archived })
|
||||
},
|
||||
assignCardToMe() {
|
||||
this.$store.dispatch('assignCardToUser', {
|
||||
card: this.card,
|
||||
assignee: {
|
||||
userId: getCurrentUser()?.uid,
|
||||
type: 0,
|
||||
},
|
||||
})
|
||||
},
|
||||
unassignCardFromMe() {
|
||||
this.$store.dispatch('removeUserFromCard', {
|
||||
card: this.card,
|
||||
assignee: {
|
||||
userId: getCurrentUser()?.uid,
|
||||
type: 0,
|
||||
},
|
||||
})
|
||||
},
|
||||
openCardMoveDialog() {
|
||||
emit('deck:card:show-move-dialog', this.card)
|
||||
editTitle(id) {
|
||||
this.$emit('edit-title', id)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
187
src/components/cards/CardMenuEntries.vue
Normal file
187
src/components/cards/CardMenuEntries.vue
Normal file
@@ -0,0 +1,187 @@
|
||||
<!--
|
||||
- SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
|
||||
- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<NcActionButton v-if="!hideDetailsEntry" :close-after-click="true" @click="openCard">
|
||||
<CardBulletedIcon slot="icon" :size="20" decorative />
|
||||
{{ t('deck', 'Card details') }}
|
||||
</NcActionButton>
|
||||
<NcActionButton v-if="canEdit" :close-after-click="true" @click="editTitle">
|
||||
<template #icon>
|
||||
<PencilIcon :size="20" decorative />
|
||||
</template>
|
||||
{{ t('deck', 'Edit title') }}
|
||||
</NcActionButton>
|
||||
<NcActionButton v-if="canEdit && !isCurrentUserAssigned"
|
||||
icon="icon-user"
|
||||
:close-after-click="true"
|
||||
@click="assignCardToMe()">
|
||||
{{ t('deck', 'Assign to me') }}
|
||||
</NcActionButton>
|
||||
<NcActionButton v-if="canEdit && isCurrentUserAssigned"
|
||||
icon="icon-user"
|
||||
:close-after-click="true"
|
||||
@click="unassignCardFromMe()">
|
||||
{{ t('deck', 'Unassign myself') }}
|
||||
</NcActionButton>
|
||||
<NcActionButton v-if="canEdit"
|
||||
icon="icon-checkmark"
|
||||
:close-after-click="true"
|
||||
@click="changeCardDoneStatus()">
|
||||
{{ card.done ? t('deck', 'Mark as not done') : t('deck', 'Mark as done') }}
|
||||
</NcActionButton>
|
||||
<NcActionButton v-if="canEdit"
|
||||
icon="icon-external"
|
||||
:close-after-click="true"
|
||||
@click="openCardMoveDialog">
|
||||
{{ t('deck', 'Move/copy card') }}
|
||||
</NcActionButton>
|
||||
<NcActionButton v-for="action in cardActions"
|
||||
:key="action.label"
|
||||
:close-after-click="true"
|
||||
:icon="action.icon"
|
||||
@click="action.callback(cardRichObject)">
|
||||
{{ action.label }}
|
||||
</NcActionButton>
|
||||
<NcActionButton v-if="canEditBoard" :close-after-click="true" @click="archiveUnarchiveCard()">
|
||||
<template #icon>
|
||||
<ArchiveIcon :size="20" decorative />
|
||||
</template>
|
||||
{{ card.archived ? t('deck', 'Unarchive card') : t('deck', 'Archive card') }}
|
||||
</NcActionButton>
|
||||
<NcActionButton v-if="canEdit"
|
||||
icon="icon-delete"
|
||||
:close-after-click="true"
|
||||
@click="deleteCard()">
|
||||
{{ t('deck', 'Delete card') }}
|
||||
</NcActionButton>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { NcActionButton } from '@nextcloud/vue'
|
||||
import { mapGetters, mapState } from 'vuex'
|
||||
import ArchiveIcon from 'vue-material-design-icons/ArchiveOutline.vue'
|
||||
import CardBulletedIcon from 'vue-material-design-icons/CardBulletedOutline.vue'
|
||||
import PencilIcon from 'vue-material-design-icons/PencilOutline.vue'
|
||||
import { generateUrl } from '@nextcloud/router'
|
||||
import { getCurrentUser } from '@nextcloud/auth'
|
||||
import { showUndo } from '@nextcloud/dialogs'
|
||||
|
||||
import '@nextcloud/dialogs/style.css'
|
||||
import { emit } from '@nextcloud/event-bus'
|
||||
|
||||
export default {
|
||||
name: 'CardMenuEntries',
|
||||
components: { NcActionButton, ArchiveIcon, CardBulletedIcon, PencilIcon },
|
||||
props: {
|
||||
card: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
hideDetailsEntry: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
emits: ['edit-title'],
|
||||
data() {
|
||||
return {
|
||||
modalShow: false,
|
||||
selectedBoard: '',
|
||||
selectedStack: '',
|
||||
stacksFromBoard: [],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'isArchived',
|
||||
'boards',
|
||||
'cardActions',
|
||||
'stackById',
|
||||
'boardById',
|
||||
]),
|
||||
...mapState({
|
||||
showArchived: state => state.showArchived,
|
||||
currentBoard: state => state.currentBoard,
|
||||
}),
|
||||
canEdit() {
|
||||
return !this.card.archived
|
||||
},
|
||||
canEditBoard() {
|
||||
if (this.currentBoard) {
|
||||
return this.$store.getters.canEdit
|
||||
}
|
||||
const board = this.$store.getters.boards.find((item) => item.id === this.card.boardId)
|
||||
return !!board?.permissions?.PERMISSION_EDIT
|
||||
},
|
||||
isCurrentUserAssigned() {
|
||||
return this.card.assignedUsers.find((item) => item.type === 0 && item.participant.uid === getCurrentUser()?.uid)
|
||||
},
|
||||
boardId() {
|
||||
return this.card?.boardId ? this.card.boardId : Number(this.$route.params.id)
|
||||
},
|
||||
cardRichObject() {
|
||||
return {
|
||||
id: '' + this.card.id,
|
||||
name: this.card.title,
|
||||
boardname: this.boardById(this.boardId)?.title,
|
||||
stackname: this.stackById(this.card.stackId)?.title,
|
||||
link: window.location.protocol + '//' + window.location.host + generateUrl('/apps/deck/') + `card/${this.card.id}`,
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
openCard() {
|
||||
const boardId = this.card?.boardId ? this.card.boardId : this.$route?.params.id ?? this.currentBoard.id
|
||||
|
||||
if (this.$router) {
|
||||
this.$router?.push({ name: 'card', params: { id: boardId, cardId: this.card.id } }).catch(() => {})
|
||||
return
|
||||
}
|
||||
|
||||
this.$root.$emit('open-card', this.card.id)
|
||||
},
|
||||
editTitle() {
|
||||
this.$emit('edit-title', this.card.id)
|
||||
},
|
||||
deleteCard() {
|
||||
this.$store.dispatch('deleteCard', this.card)
|
||||
const undoCard = { ...this.card, deletedAt: 0 }
|
||||
showUndo(t('deck', 'Card deleted'), () => this.$store.dispatch('cardUndoDelete', undoCard))
|
||||
if (this.$router.currentRoute.name === 'card') {
|
||||
this.$router.push({ name: 'board' })
|
||||
}
|
||||
},
|
||||
changeCardDoneStatus() {
|
||||
this.$store.dispatch('changeCardDoneStatus', { ...this.card, done: !this.card.done })
|
||||
},
|
||||
archiveUnarchiveCard() {
|
||||
this.$store.dispatch('archiveUnarchiveCard', { ...this.card, archived: !this.card.archived })
|
||||
},
|
||||
assignCardToMe() {
|
||||
this.$store.dispatch('assignCardToUser', {
|
||||
card: this.card,
|
||||
assignee: {
|
||||
userId: getCurrentUser()?.uid,
|
||||
type: 0,
|
||||
},
|
||||
})
|
||||
},
|
||||
unassignCardFromMe() {
|
||||
this.$store.dispatch('removeUserFromCard', {
|
||||
card: this.card,
|
||||
assignee: {
|
||||
userId: getCurrentUser()?.uid,
|
||||
type: 0,
|
||||
},
|
||||
})
|
||||
},
|
||||
openCardMoveDialog() {
|
||||
emit('deck:card:show-move-dialog', this.card)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -151,13 +151,16 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { NcModal } from '@nextcloud/vue'
|
||||
import { NcModal, Tooltip } from '@nextcloud/vue'
|
||||
|
||||
export default {
|
||||
name: 'HelpModal',
|
||||
components: {
|
||||
NcModal,
|
||||
},
|
||||
directives: {
|
||||
Tooltip,
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
:exact="true"
|
||||
to="/">
|
||||
<template #icon>
|
||||
<CalendarIcon :size="20" />
|
||||
<CalendarIcon v-if="$route.path === '/'" :size="20" />
|
||||
<CalendarOutlineIcon v-else :size="20" />
|
||||
</template>
|
||||
</NcAppNavigationItem>
|
||||
<AppNavigationBoardCategory id="deck-navigation-all"
|
||||
@@ -29,7 +30,8 @@
|
||||
:text="t('deck', 'Archived boards')"
|
||||
:boards="archivedBoards">
|
||||
<template #icon>
|
||||
<ArchiveIcon :size="20" decorative />
|
||||
<ArchiveIcon v-if="$route.path === '/board/archived'" :size="20" decorative />
|
||||
<ArchiveOutlineIcon v-else :size="20" decorative />
|
||||
</template>
|
||||
</AppNavigationBoardCategory>
|
||||
<AppNavigationBoardCategory id="deck-navigation-shared"
|
||||
@@ -112,9 +114,11 @@ import { loadState } from '@nextcloud/initial-state'
|
||||
import { generateOcsUrl } from '@nextcloud/router'
|
||||
import { getCurrentUser } from '@nextcloud/auth'
|
||||
import ArchiveIcon from 'vue-material-design-icons/Archive.vue'
|
||||
import ArchiveOutlineIcon from 'vue-material-design-icons/ArchiveOutline.vue'
|
||||
import CalendarIcon from 'vue-material-design-icons/Calendar.vue'
|
||||
import CalendarOutlineIcon from 'vue-material-design-icons/CalendarOutline.vue'
|
||||
import DeckIcon from './../icons/DeckIcon.vue'
|
||||
import ShareVariantIcon from 'vue-material-design-icons/Share.vue'
|
||||
import ShareVariantIcon from 'vue-material-design-icons/ShareOutline.vue'
|
||||
import HelpModal from './../modals/HelpModal.vue'
|
||||
import { subscribe } from '@nextcloud/event-bus'
|
||||
import AppNavigationImportBoard from './AppNavigationImportBoard.vue'
|
||||
@@ -133,7 +137,9 @@ export default {
|
||||
NcSelect,
|
||||
NcAppNavigationItem,
|
||||
ArchiveIcon,
|
||||
ArchiveOutlineIcon,
|
||||
CalendarIcon,
|
||||
CalendarOutlineIcon,
|
||||
DeckIcon,
|
||||
ShareVariantIcon,
|
||||
HelpModal,
|
||||
|
||||
@@ -13,12 +13,12 @@
|
||||
</NcColorPicker>
|
||||
<form @submit.prevent.stop="createBoard">
|
||||
<NcTextField ref="inputField"
|
||||
v-model="value"
|
||||
:disable="loading"
|
||||
:value.sync="value"
|
||||
:placeholder="t('deck', 'Board name')"
|
||||
type="text"
|
||||
required />
|
||||
<NcButton variant="tertiary"
|
||||
<NcButton type="tertiary"
|
||||
:disabled="loading"
|
||||
:title="t('deck', 'Cancel edit')"
|
||||
@click.stop.prevent="cancelEdit">
|
||||
@@ -26,8 +26,8 @@
|
||||
<CloseIcon :size="20" />
|
||||
</template>
|
||||
</NcButton>
|
||||
<NcButton variant="tertiary"
|
||||
type="submit"
|
||||
<NcButton type="tertiary"
|
||||
native-type="submit"
|
||||
:disabled="loading"
|
||||
:title="t('deck', 'Save board')">
|
||||
<template #icon>
|
||||
@@ -77,7 +77,6 @@ export default {
|
||||
})
|
||||
},
|
||||
async createBoard(e) {
|
||||
alert('createBoard called')
|
||||
this.loading = true
|
||||
const title = this.value.trim()
|
||||
await this.$store.dispatch('createBoard', {
|
||||
@@ -89,7 +88,6 @@ export default {
|
||||
this.color = randomColor()
|
||||
},
|
||||
cancelEdit(e) {
|
||||
alert('cancelEdit called')
|
||||
this.editing = false
|
||||
this.color = randomColor()
|
||||
},
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<AccountIcon v-if="board.acl.length > 0" />
|
||||
</template>
|
||||
|
||||
<template v-if="!deleted" #actions>
|
||||
<template v-if="!deleted" slot="actions">
|
||||
<template v-if="!isDueSubmenuActive">
|
||||
<NcActionButton icon="icon-info"
|
||||
:close-after-click="true"
|
||||
@@ -129,17 +129,17 @@
|
||||
:placeholder="t('deck', 'Board name')"
|
||||
type="text"
|
||||
required />
|
||||
<NcButton variant="tertiary"
|
||||
<NcButton type="tertiary"
|
||||
:disabled="loading"
|
||||
type="submit"
|
||||
native-type="submit"
|
||||
:title="t('deck', 'Cancel edit')"
|
||||
@click.stop.prevent="cancelEdit">
|
||||
<template #icon>
|
||||
<CloseIcon :size="20" />
|
||||
</template>
|
||||
</NcButton>
|
||||
<NcButton variant="tertiary"
|
||||
type="submit"
|
||||
<NcButton type="tertiary"
|
||||
native-type="submit"
|
||||
:disabled="loading"
|
||||
:title="t('deck', 'Save board')">
|
||||
<template #icon>
|
||||
@@ -152,11 +152,11 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { NcAppNavigationIconBullet, NcAppNavigationItem, NcColorPicker, NcButton, NcTextField, NcActionButton, NcLoadingIcon } from '@nextcloud/vue'
|
||||
import { NcAppNavigationIconBullet, NcAppNavigationItem, NcColorPicker, NcButton, NcTextField, NcActionButton } from '@nextcloud/vue'
|
||||
import ClickOutside from 'vue-click-outside'
|
||||
import ArchiveIcon from 'vue-material-design-icons/Archive.vue'
|
||||
import ArchiveIcon from 'vue-material-design-icons/ArchiveOutline.vue'
|
||||
import CloneIcon from 'vue-material-design-icons/ContentDuplicate.vue'
|
||||
import AccountIcon from 'vue-material-design-icons/Account.vue'
|
||||
import AccountIcon from 'vue-material-design-icons/AccountOutline.vue'
|
||||
import CloseIcon from 'vue-material-design-icons/Close.vue'
|
||||
import CheckIcon from 'vue-material-design-icons/Check.vue'
|
||||
|
||||
@@ -186,7 +186,6 @@ export default {
|
||||
CheckIcon,
|
||||
BoardCloneModal,
|
||||
BoardExportModal,
|
||||
NcLoadingIcon,
|
||||
},
|
||||
directives: {
|
||||
ClickOutside,
|
||||
|
||||
@@ -31,6 +31,10 @@ export default {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
text: {
|
||||
type: String,
|
||||
required: true,
|
||||
|
||||
@@ -5,16 +5,16 @@
|
||||
<template>
|
||||
<NcDialog :name="t('deck', 'Clone {boardTitle}', {boardTitle: boardTitle})" :show="true" @close="close(false)">
|
||||
<div class="modal__content">
|
||||
<NcCheckboxRadioSwitch v-model="withCards">
|
||||
<NcCheckboxRadioSwitch :checked.sync="withCards">
|
||||
{{ t('deck', 'Clone cards') }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
<NcCheckboxRadioSwitch v-if="withCards" v-model="withAssignments">
|
||||
<NcCheckboxRadioSwitch v-if="withCards" :checked.sync="withAssignments">
|
||||
{{ t('deck', 'Clone assignments') }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
<NcCheckboxRadioSwitch v-if="withCards" v-model="withLabels">
|
||||
<NcCheckboxRadioSwitch v-if="withCards" :checked.sync="withLabels">
|
||||
{{ t('deck', 'Clone labels') }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
<NcCheckboxRadioSwitch v-if="withCards" v-model="withDueDate">
|
||||
<NcCheckboxRadioSwitch v-if="withCards" :checked.sync="withDueDate">
|
||||
{{ t('deck', 'Clone due dates') }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
<div v-if="withCards" class="accordion" :class="{ 'is-open': accordionOpen }">
|
||||
@@ -25,10 +25,10 @@
|
||||
{{ t('deck', 'Advanced options') }}
|
||||
</div>
|
||||
<div v-if="accordionOpen" class="accordion__content">
|
||||
<NcCheckboxRadioSwitch v-if="withCards" v-model="moveCardsToLeftStack">
|
||||
<NcCheckboxRadioSwitch v-if="withCards" :checked.sync="moveCardsToLeftStack">
|
||||
{{ t('deck', 'Move all cards to the first list') }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
<NcCheckboxRadioSwitch v-if="withCards" v-model="restoreArchivedCards">
|
||||
<NcCheckboxRadioSwitch v-if="withCards" :checked.sync="restoreArchivedCards">
|
||||
{{ t('deck', 'Restore archived cards') }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
</div>
|
||||
@@ -39,7 +39,7 @@
|
||||
<NcButton @click="cancel">
|
||||
{{ t('deck', 'Cancel') }}
|
||||
</NcButton>
|
||||
<NcButton variant="primary" @click="save">
|
||||
<NcButton type="primary" @click="save">
|
||||
{{ t('deck', 'Clone') }}
|
||||
</NcButton>
|
||||
</template>
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
<template>
|
||||
<NcDialog :name="t('deck', 'Export {boardTitle}', {boardTitle: boardTitle})" @update:open="close">
|
||||
<div class="modal__content">
|
||||
<NcCheckboxRadioSwitch v-model="exportFormat"
|
||||
<NcCheckboxRadioSwitch :checked.sync="exportFormat"
|
||||
value="json"
|
||||
type="radio"
|
||||
name="board_export_format">
|
||||
{{ t('deck', 'Export as JSON') }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
<NcCheckboxRadioSwitch v-model="exportFormat"
|
||||
<NcCheckboxRadioSwitch :checked.sync="exportFormat"
|
||||
value="csv"
|
||||
type="radio"
|
||||
name="board_export_format">
|
||||
@@ -27,7 +27,7 @@
|
||||
<NcButton @click="close">
|
||||
{{ t('deck', 'Cancel') }}
|
||||
</NcButton>
|
||||
<NcButton variant="primary" @click="exportBoard">
|
||||
<NcButton type="primary" @click="exportBoard">
|
||||
{{ t('deck', 'Export') }}
|
||||
</NcButton>
|
||||
</template>
|
||||
|
||||
@@ -145,7 +145,7 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@use './../../css/variables';
|
||||
@import './../../css/variables';
|
||||
|
||||
.overview-wrapper {
|
||||
position: relative;
|
||||
@@ -162,16 +162,16 @@ export default {
|
||||
overflow-x: scroll;
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
padding-left: variables.$board-spacing;
|
||||
padding-right: variables.$board-spacing;
|
||||
padding-left: $board-spacing;
|
||||
padding-right: $board-spacing;
|
||||
|
||||
.dashboard-column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: variables.$stack-width;
|
||||
width: variables.$stack-width;
|
||||
margin-left: variables.$stack-spacing;
|
||||
margin-right: variables.$stack-spacing;
|
||||
min-width: $stack-width;
|
||||
width: $stack-width;
|
||||
margin-left: $stack-spacing;
|
||||
margin-right: $stack-spacing;
|
||||
|
||||
h3 {
|
||||
font-size: var(--default-font-size);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div v-if="searchQuery !== ''" class="global-search">
|
||||
<div v-if="searchQuery!==''" class="global-search">
|
||||
<h2>
|
||||
<NcRichText :text="t('deck', 'Search for {searchQuery} in all boards')" :arguments="queryStringArgs" />
|
||||
<div v-if="loading" class="icon-loading-small" />
|
||||
@@ -19,13 +19,13 @@
|
||||
:key="card.id"
|
||||
:standalone="true" />
|
||||
<Placeholder v-if="loading" />
|
||||
<!-- <InfiniteLoading :identifier="searchQuery" @infinite="infiniteHandler">
|
||||
<InfiniteLoading :identifier="searchQuery" @infinite="infiniteHandler">
|
||||
<div slot="spinner" />
|
||||
<div slot="no-more" />
|
||||
<div slot="no-results">
|
||||
{{ t('deck', 'No results found') }}
|
||||
</div>
|
||||
</InfiniteLoading> -->
|
||||
</InfiniteLoading>
|
||||
</div>
|
||||
<div v-else>
|
||||
<p>{{ t('deck', 'No results found') }}</p>
|
||||
@@ -39,7 +39,7 @@ import CardItem from '../cards/CardItem.vue'
|
||||
import { mapState } from 'vuex'
|
||||
import axios from '@nextcloud/axios'
|
||||
import { generateOcsUrl } from '@nextcloud/router'
|
||||
// import InfiniteLoading from 'v3-infinite-loading'
|
||||
import InfiniteLoading from 'vue-infinite-loading'
|
||||
import Placeholder from './Placeholder.vue'
|
||||
import { NcActions, NcActionButton, NcRichText } from '@nextcloud/vue'
|
||||
|
||||
@@ -70,14 +70,7 @@ function search({ query, cursor }) {
|
||||
|
||||
export default {
|
||||
name: 'GlobalSearchResults',
|
||||
components: {
|
||||
CardItem,
|
||||
// InfiniteLoading,
|
||||
NcRichText,
|
||||
Placeholder,
|
||||
NcActions,
|
||||
NcActionButton,
|
||||
},
|
||||
components: { CardItem, InfiniteLoading, NcRichText, Placeholder, NcActions, NcActionButton },
|
||||
data() {
|
||||
return {
|
||||
results: [],
|
||||
@@ -162,11 +155,11 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@use '../../css/variables';
|
||||
@import '../../css/variables';
|
||||
|
||||
.global-search {
|
||||
width: 100%;
|
||||
padding: variables.$board-spacing + variables.$stack-spacing;
|
||||
padding: $board-spacing + $stack-spacing;
|
||||
padding-bottom: 0;
|
||||
overflow: hidden;
|
||||
min-height: 35vh;
|
||||
@@ -182,7 +175,6 @@ export default {
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
.search-wrapper {
|
||||
overflow: scroll;
|
||||
height: 100%;
|
||||
@@ -190,14 +182,13 @@ export default {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
h2>div {
|
||||
h2 > div {
|
||||
display: inline-block;
|
||||
|
||||
&.icon-loading-small {
|
||||
margin-right: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
h2:deep(span) {
|
||||
background-color: var(--color-background-dark);
|
||||
padding: 3px;
|
||||
@@ -208,14 +199,13 @@ export default {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
&>div {
|
||||
& > div {
|
||||
flex-grow: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&:deep(.card) {
|
||||
width: variables.$stack-width;
|
||||
margin-right: variables.$stack-spacing;
|
||||
width: $stack-width;
|
||||
margin-right: $stack-spacing;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -58,18 +58,18 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@use '../../css/variables';
|
||||
@import '../../css/variables';
|
||||
$clickable-area: var(--default-clickable-area);
|
||||
|
||||
.card--placeholder {
|
||||
width: variables.$stack-width;
|
||||
margin-right: variables.$stack-spacing;
|
||||
padding: variables.$card-padding;
|
||||
width: $stack-width;
|
||||
margin-right: $stack-spacing;
|
||||
padding: $card-padding;
|
||||
transition: box-shadow 0.1s ease-in-out;
|
||||
box-shadow: 0 0 2px 0 var(--color-box-shadow);
|
||||
border-radius: var(--border-radius-large);
|
||||
font-size: 100%;
|
||||
margin-bottom: variables.$card-spacing;
|
||||
margin-bottom: $card-spacing;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,34 +3,38 @@
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import Vue from 'vue'
|
||||
|
||||
import './../css/collections.css'
|
||||
import FileSharingPicker from './views/FileSharingPicker.js'
|
||||
import { buildSelector } from './helpers/selector.js'
|
||||
|
||||
import './shared-init.js'
|
||||
|
||||
export function initCollections() {
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
if (OCA.Sharing && OCA.Sharing.ShareSearch) {
|
||||
OCA.Sharing.ShareSearch.addNewResult(FileSharingPicker)
|
||||
}
|
||||
Vue.prototype.t = t
|
||||
Vue.prototype.n = n
|
||||
Vue.prototype.OC = OC
|
||||
|
||||
window.OCP.Collaboration.registerType('deck', {
|
||||
action: () => {
|
||||
const BoardSelector = () => import('./BoardSelector.vue')
|
||||
return buildSelector(BoardSelector)
|
||||
},
|
||||
typeString: t('deck', 'Link to a board'),
|
||||
typeIconClass: 'icon-deck',
|
||||
})
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
if (OCA.Sharing && OCA.Sharing.ShareSearch) {
|
||||
OCA.Sharing.ShareSearch.addNewResult(FileSharingPicker)
|
||||
}
|
||||
|
||||
window.OCP.Collaboration.registerType('deck-card', {
|
||||
action: () => {
|
||||
const CardSelector = () => import('./CardSelector.vue')
|
||||
return buildSelector(CardSelector)
|
||||
},
|
||||
typeString: t('deck', 'Link to a card'),
|
||||
typeIconClass: 'icon-deck',
|
||||
})
|
||||
window.OCP.Collaboration.registerType('deck', {
|
||||
action: () => {
|
||||
const BoardSelector = () => import('./BoardSelector.vue')
|
||||
return buildSelector(BoardSelector)
|
||||
},
|
||||
typeString: t('deck', 'Link to a board'),
|
||||
typeIconClass: 'icon-deck',
|
||||
})
|
||||
}
|
||||
|
||||
window.OCP.Collaboration.registerType('deck-card', {
|
||||
action: () => {
|
||||
const CardSelector = () => import('./CardSelector.vue')
|
||||
return buildSelector(CardSelector)
|
||||
},
|
||||
typeString: t('deck', 'Link to a card'),
|
||||
typeIconClass: 'icon-deck',
|
||||
})
|
||||
})
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { registerWidget, registerCustomPickerElement, NcCustomPickerRenderResult } from '@nextcloud/vue'
|
||||
import { registerWidget, registerCustomPickerElement, NcCustomPickerRenderResult } from '@nextcloud/vue/dist/Functions/registerReference.js'
|
||||
import { translate, translatePlural } from '@nextcloud/l10n'
|
||||
|
||||
import './shared-init.js'
|
||||
|
||||
48
src/main.js
48
src/main.js
@@ -2,10 +2,11 @@
|
||||
* SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
import { createApp } from 'vue'
|
||||
import Vue from 'vue'
|
||||
import App from './App.vue'
|
||||
import router from './router.js'
|
||||
import store from './store/main.js'
|
||||
import { sync } from 'vuex-router-sync'
|
||||
import { translate, translatePlural } from '@nextcloud/l10n'
|
||||
import { showError } from '@nextcloud/dialogs'
|
||||
import { subscribe } from '@nextcloud/event-bus'
|
||||
@@ -13,33 +14,27 @@ import ClickOutside from 'vue-click-outside'
|
||||
import './shared-init.js'
|
||||
import './models/index.js'
|
||||
import './sessions.js'
|
||||
import { initCollections } from './init-collections.js'
|
||||
|
||||
// the server snap.js conflicts with vertical scrolling so we disable it
|
||||
document.body.setAttribute('data-snap-ignore', 'true')
|
||||
|
||||
const app = createApp(App)
|
||||
sync(store, router)
|
||||
|
||||
app.config.globalProperties.t = translate
|
||||
app.config.globalProperties.n = translatePlural
|
||||
app.config.globalProperties.OC = OC
|
||||
Vue.prototype.t = translate
|
||||
Vue.prototype.n = translatePlural
|
||||
|
||||
initCollections({ t, n, OC })
|
||||
Vue.directive('click-outside', ClickOutside)
|
||||
|
||||
app.directive('click-outside', ClickOutside)
|
||||
|
||||
app.directive('focus', {
|
||||
mounted(el) {
|
||||
Vue.directive('focus', {
|
||||
inserted(el) {
|
||||
el.focus()
|
||||
},
|
||||
})
|
||||
|
||||
app.config.errorHandler = (err, vm, info) => {
|
||||
Vue.config.errorHandler = (err, vm, info) => {
|
||||
if (err.response && err.response.data.message) {
|
||||
const errorMessage = translate('deck', 'Something went wrong')
|
||||
showError(
|
||||
`${errorMessage}: ${err.response.data.status} ${err.response.data.message}`,
|
||||
)
|
||||
const errorMessage = t('deck', 'Something went wrong')
|
||||
showError(`${errorMessage}: ${err.response.data.status} ${err.response.data.message}`)
|
||||
}
|
||||
console.error(err)
|
||||
}
|
||||
@@ -52,14 +47,16 @@ window.addEventListener('DOMContentLoaded', () => {
|
||||
window.OCA.Files = {}
|
||||
}
|
||||
// register unused client for the sidebar to have access to its parser methods
|
||||
Object.assign(
|
||||
window.OCA.Files,
|
||||
{ App: { fileList: { filesClient: OC.Files.getClient() } } },
|
||||
window.OCA.Files,
|
||||
)
|
||||
Object.assign(window.OCA.Files, { App: { fileList: { filesClient: OC.Files.getClient() } } }, window.OCA.Files)
|
||||
})
|
||||
|
||||
app.mixin({
|
||||
/* eslint-disable-next-line no-new */
|
||||
new Vue({
|
||||
el: '#content',
|
||||
// eslint-disable-next-line vue/match-component-file-name
|
||||
name: 'Deck',
|
||||
router,
|
||||
store,
|
||||
data() {
|
||||
return {
|
||||
time: Date.now(),
|
||||
@@ -78,7 +75,7 @@ app.mixin({
|
||||
this.time = Date.now()
|
||||
}, 1000)
|
||||
},
|
||||
beforeUnmount() {
|
||||
beforeDestroy() {
|
||||
clearInterval(this.interval)
|
||||
},
|
||||
methods: {
|
||||
@@ -89,12 +86,9 @@ app.mixin({
|
||||
this.$store.commit('setSearchQuery', '')
|
||||
},
|
||||
},
|
||||
render: h => h(App),
|
||||
})
|
||||
|
||||
app.use(router)
|
||||
app.use(store)
|
||||
app.mount('#content')
|
||||
|
||||
if (!window.OCA.Deck) {
|
||||
window.OCA.Deck = {}
|
||||
}
|
||||
|
||||
@@ -26,8 +26,7 @@ export default {
|
||||
return
|
||||
}
|
||||
|
||||
this.uploadQueue[file.name] = { name: file.name, progress: 0 }
|
||||
|
||||
this.$set(this.uploadQueue, file.name, { name: file.name, progress: 0 })
|
||||
const bodyFormData = new FormData()
|
||||
bodyFormData.append('cardId', this.cardId)
|
||||
bodyFormData.append('type', type)
|
||||
@@ -40,7 +39,7 @@ export default {
|
||||
onUploadProgress: (e) => {
|
||||
const percentCompleted = Math.round((e.loaded * 100) / e.total)
|
||||
console.debug(percentCompleted)
|
||||
this.uploadQueue[file.name].progress = percentCompleted
|
||||
this.$set(this.uploadQueue[file.name], 'progress', percentCompleted)
|
||||
},
|
||||
})
|
||||
} catch (err) {
|
||||
@@ -51,7 +50,7 @@ export default {
|
||||
showError(err.response.data ? err.response.data.message : 'Failed to upload file')
|
||||
}
|
||||
}
|
||||
delete this.uploadQueue[file.name]
|
||||
this.$delete(this.uploadQueue, file.name)
|
||||
})
|
||||
|
||||
},
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
import Vue from 'vue'
|
||||
import Router from 'vue-router'
|
||||
import { generateUrl, getRootUrl } from '@nextcloud/router'
|
||||
import { BOARD_FILTERS } from './store/main.js'
|
||||
import Boards from './components/boards/Boards.vue'
|
||||
@@ -13,14 +14,17 @@ import BoardSidebar from './components/board/BoardSidebar.vue'
|
||||
import CardSidebar from './components/card/CardSidebar.vue'
|
||||
import Overview from './components/overview/Overview.vue'
|
||||
|
||||
Vue.use(Router)
|
||||
|
||||
// We apply a dynamic base URL depending on the URL used in the browser
|
||||
const baseUrl = generateUrl('/apps/deck/')
|
||||
const webRootWithIndexPHP = getRootUrl() + '/index.php'
|
||||
const doesURLContainIndexPHP = window.location.pathname.startsWith(webRootWithIndexPHP)
|
||||
const currentBaseUrl = doesURLContainIndexPHP ? baseUrl : baseUrl.replace('/index.php/', '/')
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(currentBaseUrl),
|
||||
const router = new Router({
|
||||
mode: 'history',
|
||||
base: currentBaseUrl,
|
||||
linkActiveClass: 'active',
|
||||
routes: [
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
*/
|
||||
|
||||
import { AttachmentApi } from './../services/AttachmentApi.js'
|
||||
import Vue from 'vue'
|
||||
|
||||
const apiClient = new AttachmentApi()
|
||||
|
||||
@@ -23,20 +24,20 @@ export default {
|
||||
mutations: {
|
||||
createAttachment(state, { cardId, attachment }) {
|
||||
if (typeof state.attachments[cardId] === 'undefined') {
|
||||
state.attachments[cardId] = [attachment]
|
||||
Vue.set(state.attachments, cardId, [attachment])
|
||||
} else {
|
||||
state.attachments[cardId].push(attachment)
|
||||
}
|
||||
},
|
||||
|
||||
createAttachments(state, { cardId, attachments }) {
|
||||
state.attachments[cardId] = attachments
|
||||
Vue.set(state.attachments, cardId, attachments)
|
||||
},
|
||||
|
||||
updateAttachment(state, { cardId, attachment }) {
|
||||
const existingIndex = state.attachments[attachment.cardId].findIndex(a => a.id === attachment.id && a.type === attachment.type)
|
||||
if (existingIndex !== -1) {
|
||||
state.attachments[cardId][existingIndex] = attachment
|
||||
Vue.set(state.attachments[cardId], existingIndex, attachment)
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
import { CardApi } from './../services/CardApi.js'
|
||||
import moment from 'moment'
|
||||
import Vue from 'vue'
|
||||
|
||||
const apiClient = new CardApi()
|
||||
|
||||
@@ -189,7 +190,7 @@ export default {
|
||||
const existingIndex = state.cards.findIndex(_card => _card.id === card.id)
|
||||
if (existingIndex !== -1) {
|
||||
const existingCard = state.cards.find(_card => _card.id === card.id)
|
||||
state.cards[existingIndex] = { ...existingCard, ...card }
|
||||
Vue.set(state.cards, existingIndex, Object.assign({}, existingCard, card))
|
||||
} else {
|
||||
state.cards.push(card)
|
||||
}
|
||||
@@ -203,15 +204,15 @@ export default {
|
||||
updateCard(state, card) {
|
||||
const existingIndex = state.cards.findIndex(_card => _card.id === card.id)
|
||||
if (existingIndex !== -1) {
|
||||
state.cards[existingIndex] = { ...state.cards[existingIndex], ...card }
|
||||
Vue.set(state.cards, existingIndex, Object.assign({}, state.cards[existingIndex], card))
|
||||
}
|
||||
},
|
||||
updateCardsReorder(state, cards) {
|
||||
for (const newCard of cards) {
|
||||
const existingIndex = state.cards.findIndex(_card => _card.id === newCard.id)
|
||||
if (existingIndex !== -1) {
|
||||
state.cards[existingIndex].order = newCard.order
|
||||
state.cards[existingIndex].stackId = newCard.stackId
|
||||
Vue.set(state.cards[existingIndex], 'order', newCard.order)
|
||||
Vue.set(state.cards[existingIndex], 'stackId', newCard.stackId)
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -233,26 +234,26 @@ export default {
|
||||
updateCardProperty(state, { card, property }) {
|
||||
const existingIndex = state.cards.findIndex(_card => _card.id === card.id)
|
||||
if (existingIndex !== -1) {
|
||||
state.cards[existingIndex][property] = card[property]
|
||||
state.cards[existingIndex].lastModifiedBy = Date.now() / 1000
|
||||
Vue.set(state.cards[existingIndex], property, card[property])
|
||||
Vue.set(state.cards[existingIndex], 'lastModified', Date.now() / 1000)
|
||||
}
|
||||
},
|
||||
cardSetAttachmentCount(state, { cardId, count }) {
|
||||
const existingIndex = state.cards.findIndex(_card => _card.id === cardId)
|
||||
if (existingIndex !== -1) {
|
||||
state.cards[existingIndex].attachmentCount = count
|
||||
Vue.set(state.cards[existingIndex], 'attachmentCount', count)
|
||||
}
|
||||
},
|
||||
cardIncreaseAttachmentCount(state, cardId) {
|
||||
const existingIndex = state.cards.findIndex(_card => _card.id === cardId)
|
||||
if (existingIndex !== -1) {
|
||||
state.cards[existingIndex].attachmentCount = state.cards[existingIndex].attachmentCount + 1
|
||||
Vue.set(state.cards[existingIndex], 'attachmentCount', state.cards[existingIndex].attachmentCount + 1)
|
||||
}
|
||||
},
|
||||
cardDecreaseAttachmentCount(state, cardId) {
|
||||
const existingIndex = state.cards.findIndex(_card => _card.id === cardId)
|
||||
if (existingIndex !== -1) {
|
||||
state.cards[existingIndex].attachmentCount = state.cards[existingIndex].attachmentCount - 1
|
||||
Vue.set(state.cards[existingIndex], 'attachmentCount', state.cards[existingIndex].attachmentCount - 1)
|
||||
}
|
||||
},
|
||||
addNewCard(state, card) {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
*/
|
||||
|
||||
import { CommentApi } from '../services/CommentApi.js'
|
||||
import Vue from 'vue'
|
||||
|
||||
const apiClient = new CommentApi()
|
||||
|
||||
@@ -33,10 +34,10 @@ export default {
|
||||
},
|
||||
addComments(state, { comments, cardId }) {
|
||||
if (state.comments[cardId] === undefined) {
|
||||
state.comments[cardId] = {
|
||||
hasMore: comments.length >= 0,
|
||||
Vue.set(state.comments, cardId, {
|
||||
hasMore: comments.length > 0,
|
||||
comments: [...comments],
|
||||
}
|
||||
})
|
||||
} else {
|
||||
const newComments = comments.filter((comment) => {
|
||||
return state.comments[cardId].comments.findIndex((item) => item.id === comment.id) === -1
|
||||
@@ -58,11 +59,11 @@ export default {
|
||||
},
|
||||
markCommentsAsRead(state, cardId) {
|
||||
state.comments[cardId].comments.forEach(_comment => {
|
||||
_comment.isUnread = false
|
||||
Vue.set(_comment, 'isUnread', false)
|
||||
})
|
||||
},
|
||||
setReplyTo(state, comment) {
|
||||
state.replyTo = comment
|
||||
Vue.set(state, 'replyTo', comment)
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
import 'url-search-params-polyfill'
|
||||
|
||||
import { loadState } from '@nextcloud/initial-state'
|
||||
import { createStore } from 'vuex'
|
||||
import Vue from 'vue'
|
||||
import Vuex from 'vuex'
|
||||
import axios from '@nextcloud/axios'
|
||||
import { generateOcsUrl, generateUrl } from '@nextcloud/router'
|
||||
import { BoardApi } from '../services/BoardApi.js'
|
||||
@@ -17,6 +18,7 @@ import comment from './comment.js'
|
||||
import trashbin from './trashbin.js'
|
||||
import attachment from './attachment.js'
|
||||
import overview from './overview.js'
|
||||
Vue.use(Vuex)
|
||||
|
||||
const apiClient = new BoardApi()
|
||||
const debug = process.env.NODE_ENV !== 'production'
|
||||
@@ -27,7 +29,7 @@ export const BOARD_FILTERS = {
|
||||
SHARED: 'shared',
|
||||
}
|
||||
|
||||
const store = createStore({
|
||||
export default new Vuex.Store({
|
||||
modules: {
|
||||
actions,
|
||||
stack,
|
||||
@@ -128,10 +130,10 @@ const store = createStore({
|
||||
},
|
||||
mutations: {
|
||||
setFullApp(state, isFullApp) {
|
||||
state.isFullApp = isFullApp
|
||||
Vue.set(state, 'isFullApp', isFullApp)
|
||||
},
|
||||
setHasCardSaveError(state, hasCardSaveError) {
|
||||
state.hasCardSaveError = hasCardSaveError
|
||||
Vue.set(state, 'hasCardSaveError', hasCardSaveError)
|
||||
},
|
||||
SET_CONFIG(state, { key, value }) {
|
||||
const [scope, id, configKey] = key.split(':', 3)
|
||||
@@ -143,11 +145,11 @@ const store = createStore({
|
||||
})
|
||||
|
||||
if (indexExisting > -1) {
|
||||
state.boards[indexExisting].settings[configKey] = value
|
||||
Vue.set(state.boards[indexExisting].settings, configKey, value)
|
||||
}
|
||||
break
|
||||
default:
|
||||
state.config[key] = value
|
||||
Vue.set(state.config, key, value)
|
||||
}
|
||||
},
|
||||
setSearchQuery(state, searchQuery) {
|
||||
@@ -160,7 +162,7 @@ const store = createStore({
|
||||
Object.keys(filter).forEach((key) => {
|
||||
switch (key) {
|
||||
case 'due':
|
||||
state.filter[key] = filter.due
|
||||
Vue.set(state.filter, key, filter.due)
|
||||
break
|
||||
default:
|
||||
filter[key].forEach((item) => {
|
||||
@@ -187,7 +189,7 @@ const store = createStore({
|
||||
})
|
||||
|
||||
if (indexExisting > -1) {
|
||||
state.boards[indexExisting] = board
|
||||
Vue.set(state.boards, indexExisting, board)
|
||||
} else {
|
||||
state.boards.push(board)
|
||||
}
|
||||
@@ -199,7 +201,7 @@ const store = createStore({
|
||||
})
|
||||
|
||||
if (indexExisting > -1) {
|
||||
state.boards[indexExisting] = board
|
||||
Vue.set(state.boards, indexExisting, board)
|
||||
} else {
|
||||
state.boards.push(board)
|
||||
}
|
||||
@@ -232,7 +234,7 @@ const store = createStore({
|
||||
state.boards = boards
|
||||
},
|
||||
setSharees(state, shareesUsersAndGroups) {
|
||||
state.sharees = shareesUsersAndGroups.exact.users
|
||||
Vue.set(state, 'sharees', shareesUsersAndGroups.exact.users)
|
||||
state.sharees.push(...shareesUsersAndGroups.exact.groups)
|
||||
state.sharees.push(...shareesUsersAndGroups.exact.circles)
|
||||
|
||||
@@ -282,7 +284,7 @@ const store = createStore({
|
||||
updateAclFromCurrentBoard(state, acl) {
|
||||
for (const acl_ in state.currentBoard.acl) {
|
||||
if (state.currentBoard.acl[acl_].participant.uid === acl.participant.uid) {
|
||||
state.currentBoard.acl[acl_] = acl
|
||||
Vue.set(state.currentBoard.acl, acl_, acl)
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -298,7 +300,7 @@ const store = createStore({
|
||||
}
|
||||
|
||||
if (removeIndex > -1) {
|
||||
state.currentBoard.acl.splice(removeIndex, 1)
|
||||
Vue.delete(state.currentBoard.acl, removeIndex)
|
||||
}
|
||||
},
|
||||
TOGGLE_SHORTCUT_LOCK(state, lock) {
|
||||
@@ -529,5 +531,3 @@ const store = createStore({
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export default store
|
||||
|
||||
@@ -3,7 +3,10 @@
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import Vue from 'vue'
|
||||
import Vuex from 'vuex'
|
||||
import { OverviewApi } from '../services/OverviewApi.js'
|
||||
Vue.use(Vuex)
|
||||
|
||||
const apiClient = new OverviewApi()
|
||||
export default {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import Vue from 'vue'
|
||||
import { StackApi } from './../services/StackApi.js'
|
||||
import applyOrderToArray from './../helpers/applyOrderToArray.js'
|
||||
|
||||
@@ -25,7 +26,7 @@ export default {
|
||||
const existingIndex = state.stacks.findIndex(_stack => _stack.id === stack.id)
|
||||
if (existingIndex !== -1) {
|
||||
const existingStack = state.stacks.find(_stack => _stack.id === stack.id)
|
||||
state.stacks[existingIndex] = { ...existingStack, ...stack }
|
||||
Vue.set(state.stacks, existingIndex, Object.assign({}, existingStack, stack))
|
||||
} else {
|
||||
state.stacks.push(stack)
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ import DeckIcon from '../components/icons/DeckIcon.vue'
|
||||
import { BoardApi } from './../services/BoardApi.js'
|
||||
import store from './../store/main.js'
|
||||
|
||||
import { NcUserBubble } from '@nextcloud/vue'
|
||||
import NcUserBubble from '@nextcloud/vue/dist/Components/NcUserBubble.js'
|
||||
|
||||
import moment from '@nextcloud/moment'
|
||||
import { generateUrl } from '@nextcloud/router'
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CalendarBlankIcon from 'vue-material-design-icons/CalendarBlank.vue'
|
||||
import CalendarBlankIcon from 'vue-material-design-icons/CalendarBlankOutline.vue'
|
||||
import TextIcon from 'vue-material-design-icons/Text.vue'
|
||||
import CardBulletedOutlineIcon from 'vue-material-design-icons/CardBulletedOutline.vue'
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CalendarBlankIcon from 'vue-material-design-icons/CalendarBlank.vue'
|
||||
import CalendarBlankIcon from 'vue-material-design-icons/CalendarBlankOutline.vue'
|
||||
import TextIcon from 'vue-material-design-icons/Text.vue'
|
||||
import CardBulletedOutlineIcon from 'vue-material-design-icons/CardBulletedOutline.vue'
|
||||
import CommentProcessingOutlineIcon from 'vue-material-design-icons/CommentProcessingOutline.vue'
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
{{ t('deck', 'Cancel') }}
|
||||
</NcButton>
|
||||
<NcButton :disabled="loading || !isBoardAndStackChoosen"
|
||||
variant="primary"
|
||||
type="primary"
|
||||
@click="createCard">
|
||||
{{ t('deck', 'Create card') }}
|
||||
</NcButton>
|
||||
@@ -212,8 +212,8 @@ export default {
|
||||
},
|
||||
},
|
||||
beforeMount() {
|
||||
this.card.title = this.title
|
||||
this.card.description = this.description
|
||||
this.$set(this.card, 'title', this.title)
|
||||
this.$set(this.card, 'description', this.description)
|
||||
this.fetchBoards()
|
||||
},
|
||||
mounted() {
|
||||
@@ -276,10 +276,11 @@ export default {
|
||||
}
|
||||
},
|
||||
onSelectLabel(label) {
|
||||
if (!label.id) return
|
||||
this.card.labels.push(label)
|
||||
},
|
||||
onRemoveLabel(removedLabel) {
|
||||
this.card.labels = this.card.label.filter(label => label.id !== removedLabel.id)
|
||||
this.card.labels = this.card.labels.filter(label => label.id !== removedLabel.id)
|
||||
},
|
||||
onSelectUser(user) {
|
||||
this.card.assignedUsers.push(user)
|
||||
|
||||
@@ -1 +1 @@
|
||||
81091
|
||||
81373
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~9",
|
||||
"behat/behat": "~3.21.1",
|
||||
"behat/behat": "~3.23.0",
|
||||
"guzzlehttp/guzzle": "7.9.2",
|
||||
"jarnaiz/behat-junit-formatter": "^1.3",
|
||||
"sabre/dav": "4.7.0",
|
||||
|
||||
@@ -475,9 +475,6 @@ class CardServiceTest extends TestCase {
|
||||
$label->setBoardId(1);
|
||||
$this->cardMapper->expects($this->once())->method('find')->willReturn($card);
|
||||
$this->cardMapper->expects($this->once())->method('removeLabel');
|
||||
$this->cardMapper->expects($this->once())
|
||||
->method('findBoardId')
|
||||
->willReturn(1);
|
||||
$this->labelMapper->expects($this->once())
|
||||
->method('find')
|
||||
->willReturn($label);
|
||||
|
||||
@@ -347,9 +347,8 @@ class PermissionServiceTest extends \Test\TestCase {
|
||||
->method('__call')
|
||||
->with('getOwner', [])
|
||||
->willReturn('user1');
|
||||
$this->aclMapper->expects($this->once())
|
||||
->method('findAll')
|
||||
->with(123)
|
||||
$board->expects($this->any())
|
||||
->method('getAcl')
|
||||
->willReturn([$aclUser, $aclGroup]);
|
||||
$this->boardMapper->expects($this->once())
|
||||
->method('find')
|
||||
|
||||
@@ -7,7 +7,7 @@ const isDevServer = process.env.WEBPACK_SERVE
|
||||
|
||||
webpackConfig.entry = {
|
||||
...webpackConfig.entry,
|
||||
// collections: path.join(__dirname, 'src', 'init-collections.js'),
|
||||
collections: path.join(__dirname, 'src', 'init-collections.js'),
|
||||
dashboard: path.join(__dirname, 'src', 'init-dashboard.js'),
|
||||
calendar: path.join(__dirname, 'src', 'init-calendar.js'),
|
||||
talk: path.join(__dirname, 'src', 'init-talk.js'),
|
||||
@@ -22,9 +22,6 @@ if (isDevServer) {
|
||||
})
|
||||
)
|
||||
} else {
|
||||
webpackConfig.output.clean = {
|
||||
keep: /\webpack-stats\.json$/,
|
||||
}
|
||||
webpackConfig.stats = {
|
||||
context: path.resolve(__dirname, 'src'),
|
||||
assets: true,
|
||||
@@ -33,5 +30,7 @@ if (isDevServer) {
|
||||
modules: true,
|
||||
}
|
||||
}
|
||||
// Workaround for https://github.com/nextcloud/webpack-vue-config/pull/432 causing problems with nextcloud-vue-collections
|
||||
webpackConfig.resolve.alias = {}
|
||||
|
||||
module.exports = webpackConfig
|
||||
|
||||
Reference in New Issue
Block a user