diff options
-rw-r--r-- | CHANGELOG.md | 17 | ||||
-rw-r--r-- | Dockerfile | 10 | ||||
-rw-r--r-- | Stackerfile.yml | 2 | ||||
-rw-r--r-- | client/components/boards/boardBody.js | 2 | ||||
-rw-r--r-- | client/components/boards/boardsList.js | 4 | ||||
-rw-r--r-- | client/components/cards/cardDetails.js | 6 | ||||
-rw-r--r-- | client/components/lists/list.styl | 4 | ||||
-rw-r--r-- | client/components/lists/listBody.js | 12 | ||||
-rw-r--r-- | client/components/lists/listHeader.jade | 2 | ||||
-rw-r--r-- | client/components/sidebar/sidebarArchives.jade | 96 | ||||
-rw-r--r-- | client/components/sidebar/sidebarArchives.js | 22 | ||||
-rw-r--r-- | i18n/fi.i18n.json | 140 | ||||
-rw-r--r-- | models/export.js | 23 | ||||
-rw-r--r-- | openapi/generate_openapi.py | 2 | ||||
-rw-r--r-- | package.json | 2 | ||||
-rw-r--r-- | sandstorm-pkgdef.capnp | 4 | ||||
-rw-r--r-- | server/publications/boards.js | 12 | ||||
-rw-r--r-- | server/publications/fast-render.js | 2 |
18 files changed, 209 insertions, 153 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 45aadf43..ae3fd7d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,20 @@ +# v2.73 2019-05-14 Wekan release + +This release fixes the following bugs with Apache I-CLA: + +- [Card count placement and export API functionality back](https://github.com/wekan/wekan/pulls/2406). + Thanks to bentiss. +- [Few fixes for Dockerfile](https://github.com/wekan/wekan/pulls/2407). + Thanks to bentiss. + +and fixes the following bugs: + +- Fixed [#2338](https://github.com/wekan/wekan/issues/2338) -> [Slow opening of big boards with too many archived items](https://github.com/wekan/wekan/pull/2402). + If some Wekan users see errors with this, please empty your browser cache. + Thanks to nerminator. + +Thanks to above GitHub users for their contributions and translators for their translations. + # v2.72 2019-05-13 Wekan release This release adds the following new features: @@ -194,7 +194,7 @@ RUN \ \ # Get additional packages #mkdir -p /home/wekan/app/packages && \ - chown wekan --recursive /home/wekan && \ + #chown wekan:wekan --recursive /home/wekan && \ # REPOS BELOW ARE INCLUDED TO WEKAN REPO #cd /home/wekan/app/packages && \ #gosu wekan:wekan git clone --depth 1 -b master https://github.com/wekan/flow-router.git kadira-flow-router && \ @@ -212,7 +212,7 @@ RUN \ gosu wekan:wekan /home/wekan/.meteor/meteor -- help; \ \ # extract the OpenAPI specification - npm install -g api2html@0.3.0 && \ + npm install -g api2html@0.3.3 && \ mkdir -p /home/wekan/python && \ chown wekan --recursive /home/wekan/python && \ cd /home/wekan/python && \ @@ -220,9 +220,9 @@ RUN \ cd /home/wekan/python/esprima-python && \ python3 setup.py install --record files.txt && \ cd /home/wekan/app &&\ - mkdir -p ./public/api && \ - python3 ./openapi/generate_openapi.py --release $(git describe --tags --abbrev=0) > ./public/api/wekan.yml && \ - /opt/nodejs/bin/api2html -c ./public/logo-header.png -o ./public/api/wekan.html ./public/api/wekan.yml; \ + gosu wekan:wekan mkdir -p ./public/api && \ + gosu wekan:wekan python3 ./openapi/generate_openapi.py --release $(git describe --tags --abbrev=0) > ./public/api/wekan.yml && \ + gosu wekan:wekan /opt/nodejs/bin/api2html -c ./public/logo-header.png -o ./public/api/wekan.html ./public/api/wekan.yml; \ # Build app cd /home/wekan/app && \ gosu wekan:wekan /home/wekan/.meteor/meteor add standard-minifier-js && \ diff --git a/Stackerfile.yml b/Stackerfile.yml index 83360b8f..427e9988 100644 --- a/Stackerfile.yml +++ b/Stackerfile.yml @@ -1,5 +1,5 @@ appId: wekan-public/apps/77b94f60-dec9-0136-304e-16ff53095928 -appVersion: "v2.72.0" +appVersion: "v2.73.0" files: userUploads: - README.md diff --git a/client/components/boards/boardBody.js b/client/components/boards/boardBody.js index 301c0742..dc5e0ede 100644 --- a/client/components/boards/boardBody.js +++ b/client/components/boards/boardBody.js @@ -14,7 +14,7 @@ BlazeComponent.extendComponent({ const currentBoardId = Session.get('currentBoard'); if (!currentBoardId) return; - const handle = subManager.subscribe('board', currentBoardId); + const handle = subManager.subscribe('board', currentBoardId, false); Tracker.nonreactive(() => { Tracker.autorun(() => { this.isBoardReady.set(handle.ready()); diff --git a/client/components/boards/boardsList.js b/client/components/boards/boardsList.js index e97070ee..0fb80230 100644 --- a/client/components/boards/boardsList.js +++ b/client/components/boards/boardsList.js @@ -33,12 +33,12 @@ BlazeComponent.extendComponent({ }, hasOvertimeCards() { - subManager.subscribe('board', this.currentData()._id); + subManager.subscribe('board', this.currentData()._id, false); return this.currentData().hasOvertimeCards(); }, hasSpentTimeCards() { - subManager.subscribe('board', this.currentData()._id); + subManager.subscribe('board', this.currentData()._id, false); return this.currentData().hasSpentTimeCards(); }, diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index 79e9e311..c9254751 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -424,7 +424,7 @@ Template.moveCardPopup.events({ }); BlazeComponent.extendComponent({ onCreated() { - subManager.subscribe('board', Session.get('currentBoard')); + subManager.subscribe('board', Session.get('currentBoard'), false); this.selectedBoardId = new ReactiveVar(Session.get('currentBoard')); }, @@ -453,7 +453,7 @@ BlazeComponent.extendComponent({ return [{ 'change .js-select-boards'(evt) { this.selectedBoardId.set($(evt.currentTarget).val()); - subManager.subscribe('board', this.selectedBoardId.get()); + subManager.subscribe('board', this.selectedBoardId.get(), false); }, }]; }, @@ -676,7 +676,7 @@ BlazeComponent.extendComponent({ if (selection === 'none') { this.parentBoard.set(null); } else { - subManager.subscribe('board', $(evt.currentTarget).val()); + subManager.subscribe('board', $(evt.currentTarget).val(), false); this.parentBoard.set(selection); list.prop('disabled', false); } diff --git a/client/components/lists/list.styl b/client/components/lists/list.styl index dcbeb93f..05da07e1 100644 --- a/client/components/lists/list.styl +++ b/client/components/lists/list.styl @@ -99,6 +99,10 @@ .highlight color: #ce1414 + .cardCount + color: #8c8c8c + font-size: 0.8em + .list-body flex: 1 1 auto flex-direction: column diff --git a/client/components/lists/listBody.js b/client/components/lists/listBody.js index a5ccba3f..bce350dd 100644 --- a/client/components/lists/listBody.js +++ b/client/components/lists/listBody.js @@ -348,7 +348,7 @@ BlazeComponent.extendComponent({ this.boardId = Session.get('currentBoard'); // In order to get current board info - subManager.subscribe('board', this.boardId); + subManager.subscribe('board', this.boardId, false); this.board = Boards.findOne(this.boardId); // List where to insert card const list = $(Popup._getTopStack().openerElement).closest('.js-list'); @@ -414,7 +414,7 @@ BlazeComponent.extendComponent({ events() { return [{ 'change .js-select-boards'(evt) { - subManager.subscribe('board', $(evt.currentTarget).val()); + subManager.subscribe('board', $(evt.currentTarget).val(), false); this.selectedBoardId.set($(evt.currentTarget).val()); }, 'change .js-select-swimlanes'(evt) { @@ -500,13 +500,13 @@ BlazeComponent.extendComponent({ } const boardId = board._id; // Subscribe to this board - subManager.subscribe('board', boardId); + subManager.subscribe('board', boardId, false); this.selectedBoardId = new ReactiveVar(boardId); if (!this.isBoardTemplateSearch) { this.boardId = Session.get('currentBoard'); // In order to get current board info - subManager.subscribe('board', this.boardId); + subManager.subscribe('board', this.boardId, false); this.swimlaneId = ''; // Swimlane where to insert card const swimlane = $(Popup._getTopStack().openerElement).parents('.js-swimlane'); @@ -547,7 +547,7 @@ BlazeComponent.extendComponent({ } else if (this.isBoardTemplateSearch) { const boards = board.searchBoards(this.term.get()); boards.forEach((board) => { - subManager.subscribe('board', board.linkedId); + subManager.subscribe('board', board.linkedId, false); }); return boards; } else { @@ -558,7 +558,7 @@ BlazeComponent.extendComponent({ events() { return [{ 'change .js-select-boards'(evt) { - subManager.subscribe('board', $(evt.currentTarget).val()); + subManager.subscribe('board', $(evt.currentTarget).val(), false); this.selectedBoardId.set($(evt.currentTarget).val()); }, 'submit .js-search-term-form'(evt) { diff --git a/client/components/lists/listHeader.jade b/client/components/lists/listHeader.jade index d9644d00..306659b4 100644 --- a/client/components/lists/listHeader.jade +++ b/client/components/lists/listHeader.jade @@ -19,7 +19,7 @@ template(name="listHeader") if showCardsCountForList cards.count | - p.quiet.small {{cardsCount}} {{_ 'cards-count'}} + span(class="cardCount") {{cardsCount}} {{_ 'cards-count'}} if isMiniScreen if currentList if isWatching diff --git a/client/components/sidebar/sidebarArchives.jade b/client/components/sidebar/sidebarArchives.jade index e2f3e395..466d2cb0 100644 --- a/client/components/sidebar/sidebarArchives.jade +++ b/client/components/sidebar/sidebarArchives.jade @@ -1,54 +1,56 @@ template(name="archivesSidebar") - +basicTabs(tabs=tabs) - - +tabContent(slug="cards") - p.quiet - a.js-restore-all-cards {{_ 'restore-all'}} - | - - a.js-delete-all-cards {{_ 'delete-all'}} - each archivedCards - .minicard-wrapper.js-minicard - +minicard(this) - if currentUser.isBoardMember + if isArchiveReady.get + +basicTabs(tabs=tabs) + +tabContent(slug="cards") p.quiet - a.js-restore-card {{_ 'restore'}} + a.js-restore-all-cards {{_ 'restore-all'}} | - - a.js-delete-card {{_ 'delete'}} - if cardIsInArchivedList - p.quiet.small ({{_ 'warn-list-archived'}}) - else - p.no-items-message {{_ 'no-archived-cards'}} - - +tabContent(slug="lists") - p.quiet - a.js-restore-all-lists {{_ 'restore-all'}} - | - - a.js-delete-all-lists {{_ 'delete-all'}} - ul.archived-lists - each archivedLists - li.archived-lists-item - = title + a.js-delete-all-cards {{_ 'delete-all'}} + each archivedCards + .minicard-wrapper.js-minicard + +minicard(this) if currentUser.isBoardMember p.quiet - a.js-restore-list {{_ 'restore'}} + a.js-restore-card {{_ 'restore'}} | - - a.js-delete-list {{_ 'delete'}} - else - li.no-items-message {{_ 'no-archived-lists'}} + a.js-delete-card {{_ 'delete'}} + if cardIsInArchivedList + p.quiet.small ({{_ 'warn-list-archived'}}) + else + p.no-items-message {{_ 'no-archived-cards'}} - +tabContent(slug="swimlanes") - p.quiet - a.js-restore-all-swimlanes {{_ 'restore-all'}} - | - - a.js-delete-all-swimlanes {{_ 'delete-all'}} - ul.archived-lists - each archivedSwimlanes - li.archived-lists-item - = title - if currentUser.isBoardMember - p.quiet - a.js-restore-swimlane {{_ 'restore'}} - | - - a.js-delete-swimlane {{_ 'delete'}} - else - li.no-items-message {{_ 'no-archived-swimlanes'}} + +tabContent(slug="lists") + p.quiet + a.js-restore-all-lists {{_ 'restore-all'}} + | - + a.js-delete-all-lists {{_ 'delete-all'}} + ul.archived-lists + each archivedLists + li.archived-lists-item + = title + if currentUser.isBoardMember + p.quiet + a.js-restore-list {{_ 'restore'}} + | - + a.js-delete-list {{_ 'delete'}} + else + li.no-items-message {{_ 'no-archived-lists'}} + + +tabContent(slug="swimlanes") + p.quiet + a.js-restore-all-swimlanes {{_ 'restore-all'}} + | - + a.js-delete-all-swimlanes {{_ 'delete-all'}} + ul.archived-lists + each archivedSwimlanes + li.archived-lists-item + = title + if currentUser.isBoardMember + p.quiet + a.js-restore-swimlane {{_ 'restore'}} + | - + a.js-delete-swimlane {{_ 'delete'}} + else + li.no-items-message {{_ 'no-archived-swimlanes'}} + else + +spinner diff --git a/client/components/sidebar/sidebarArchives.js b/client/components/sidebar/sidebarArchives.js index b50043fd..546d7e1a 100644 --- a/client/components/sidebar/sidebarArchives.js +++ b/client/components/sidebar/sidebarArchives.js @@ -1,4 +1,26 @@ +const subManager = new SubsManager(); + BlazeComponent.extendComponent({ + onCreated() { + this.isArchiveReady = new ReactiveVar(false); + + // The pattern we use to manually handle data loading is described here: + // https://kadira.io/academy/meteor-routing-guide/content/subscriptions-and-data-management/using-subs-manager + // XXX The boardId should be readed from some sort the component "props", + // unfortunatly, Blaze doesn't have this notion. + this.autorun(() => { + const currentBoardId = Session.get('currentBoard'); + if (!currentBoardId) + return; + const handle = subManager.subscribe('board', currentBoardId, true); + Tracker.nonreactive(() => { + Tracker.autorun(() => { + this.isArchiveReady.set( handle.ready() ); + }); + }); + }); + }, + tabs() { return [ { name: TAPi18n.__('cards'), slug: 'cards' }, diff --git a/i18n/fi.i18n.json b/i18n/fi.i18n.json index f304ef93..3cbb20fe 100644 --- a/i18n/fi.i18n.json +++ b/i18n/fi.i18n.json @@ -83,7 +83,7 @@ "added": "Lisätty", "addMemberPopup-title": "Jäsenet", "admin": "Ylläpitäjä", - "admin-desc": "Voi nähfä ja muokata kortteja, poistaa jäseniä, ja muuttaa taulun asetuksia.", + "admin-desc": "Voi nähdä ja muokata kortteja, poistaa jäseniä, ja muuttaa taulun asetuksia.", "admin-announcement": "Ilmoitus", "admin-announcement-active": "Aktiivinen järjestelmänlaajuinen ilmoitus", "admin-announcement-title": "Ilmoitus ylläpitäjältä", @@ -103,7 +103,7 @@ "archived-items": "Arkisto", "archived-boards": "Taulut Arkistossa", "restore-board": "Palauta taulu", - "no-archived-boards": "Ei tauluja Arkistossa", + "no-archived-boards": "Ei tauluja Arkistossa.", "archives": "Arkisto", "template": "Malli", "templates": "Mallit", @@ -114,7 +114,7 @@ "attachmentDeletePopup-title": "Poista liitetiedosto?", "attachments": "Liitetiedostot", "auto-watch": "Automaattisesti seuraa tauluja kun ne on luotu", - "avatar-too-big": "Profiilikuva on liian suuri (70KB maksimi)", + "avatar-too-big": "Profiilikuva on liian suuri (enintään 70 kt)", "back": "Takaisin", "board-change-color": "Muokkaa väriä", "board-nb-stars": "%s tähteä", @@ -125,9 +125,9 @@ "boardChangeTitlePopup-title": "Nimeä taulu uudelleen", "boardChangeVisibilityPopup-title": "Muokkaa näkyvyyttä", "boardChangeWatchPopup-title": "Muokkaa seuraamista", - "boardMenuPopup-title": "Taulu asetukset", + "boardMenuPopup-title": "Tauluasetukset", "boards": "Taulut", - "board-view": "Taulu näkymä", + "board-view": "Taulunäkymä", "board-view-cal": "Kalenteri", "board-view-swimlanes": "Swimlanet", "board-view-lists": "Listat", @@ -136,8 +136,8 @@ "card-archived": "Tämä kortti on siirretty Arkistoon.", "board-archived": "Tämä taulu on siirretty Arkistoon.", "card-comments-title": "Tässä kortissa on %s kommenttia.", - "card-delete-notice": "Poistaminen on lopullista. Menetät kaikki toimet jotka on liitetty tähän korttiin.", - "card-delete-pop": "Kaikki toimet poistetaan toimintasyötteestä ja et tule pystymään uudelleenavaamaan korttia. Tätä ei voi peruuttaa.", + "card-delete-notice": "Poistaminen on lopullista. Menetät kaikki tähän korttiin liitetyt toimet.", + "card-delete-pop": "Kaikki toimet poistetaan toimintasyötteestä, etkä pysty avata korttia uudelleen. Tätä ei voi peruuttaa.", "card-delete-suggest-archive": "Voit siirtää kortin Arkistoon poistaaksesi sen taululta ja säilyttääksesi toimintalokin.", "card-due": "Erääntyy", "card-due-on": "Erääntyy", @@ -154,14 +154,14 @@ "cardCustomField-datePopup-title": "Muokkaa päivää", "cardCustomFieldsPopup-title": "Muokkaa mukautettuja kenttiä", "cardDeletePopup-title": "Poista kortti?", - "cardDetailsActionsPopup-title": "Kortti toimet", + "cardDetailsActionsPopup-title": "Korttitoimet", "cardLabelsPopup-title": "Tunnisteet", "cardMembersPopup-title": "Jäsenet", "cardMorePopup-title": "Lisää", "cardTemplatePopup-title": "Luo malli", "cards": "Kortit", "cards-count": "korttia", - "casSignIn": "CAS kirjautuminen", + "casSignIn": "CAS-kirjautuminen", "cardType-card": "Kortti", "cardType-linkedCard": "Linkitetty kortti", "cardType-linkedBoard": "Linkitetty taulu", @@ -182,7 +182,7 @@ "clipboard": "Leikepöytä tai raahaa ja pudota", "close": "Sulje", "close-board": "Sulje taulu", - "close-board-pop": "Voit palauttaa taulun klikkaamalla “Arkisto” painiketta taululistan yläpalkista.", + "close-board-pop": "Voit palauttaa taulun klikkaamalla “Arkisto”-painiketta taululistan yläpalkista.", "color-black": "musta", "color-blue": "sininen", "color-crimson": "karmiininpunainen", @@ -216,14 +216,14 @@ "no-comments": "Ei kommentteja", "no-comments-desc": "Ei voi nähdä kommentteja ja toimintaa.", "computer": "Tietokone", - "confirm-subtask-delete-dialog": "Oletko varma että haluat poistaa alitehtävän?", - "confirm-checklist-delete-dialog": "Oletko varma että haluat poistaa tarkistuslistan?", + "confirm-subtask-delete-dialog": "Haluatko varmasti poistaa alitehtävän?", + "confirm-checklist-delete-dialog": "Haluatko varmasti poistaa tarkistuslistan?", "copy-card-link-to-clipboard": "Kopioi kortin linkki leikepöydälle", "linkCardPopup-title": "Linkitä kortti", "searchElementPopup-title": "Etsi", "copyCardPopup-title": "Kopioi kortti", "copyChecklistToManyCardsPopup-title": "Kopioi tarkistuslistan malli monille korteille", - "copyChecklistToManyCardsPopup-instructions": "Kohde korttien otsikot ja kuvaukset JSON muodossa", + "copyChecklistToManyCardsPopup-instructions": "Kohde korttien otsikot ja kuvaukset JSON-muodossa", "copyChecklistToManyCardsPopup-format": "[ {\"title\": \"Ensimmäisen kortin otsikko\", \"description\":\"Ensimmäisen kortin kuvaus\"}, {\"title\":\"Toisen kortin otsikko\",\"description\":\"Toisen kortin kuvaus\"},{\"title\":\"Viimeisen kortin otsikko\",\"description\":\"Viimeisen kortin kuvaus\"} ]", "create": "Luo", "createBoardPopup-title": "Luo taulu", @@ -237,7 +237,7 @@ "custom-field-date": "Päivämäärä", "custom-field-dropdown": "Pudotusvalikko", "custom-field-dropdown-none": "(ei mitään)", - "custom-field-dropdown-options": "Luettelon vaihtoehdot", + "custom-field-dropdown-options": "Listan vaihtoehdot", "custom-field-dropdown-options-placeholder": "Paina Enter lisätäksesi lisää vaihtoehtoja", "custom-field-dropdown-unknown": "(tuntematon)", "custom-field-number": "Numero", @@ -245,13 +245,13 @@ "custom-fields": "Mukautetut kentät", "date": "Päivämäärä", "decline": "Kieltäydy", - "default-avatar": "Oletus profiilikuva", + "default-avatar": "Oletusprofiilikuva", "delete": "Poista", "deleteCustomFieldPopup-title": "Poista mukautettu kenttä?", "deleteLabelPopup-title": "Poista tunniste?", "description": "Kuvaus", - "disambiguateMultiLabelPopup-title": "Yksikäsitteistä tunniste toiminta", - "disambiguateMultiMemberPopup-title": "Yksikäsitteistä jäsen toiminta", + "disambiguateMultiLabelPopup-title": "Yksikäsitteistä tunnistetoiminta", + "disambiguateMultiMemberPopup-title": "Yksikäsitteistä jäsentoiminta", "discard": "Hylkää", "done": "Valmis", "download": "Lataa", @@ -259,7 +259,7 @@ "edit-avatar": "Muokkaa profiilikuvaa", "edit-profile": "Muokkaa profiilia", "edit-wip-limit": "Muokkaa WIP-rajaa", - "soft-wip-limit": "Pehmeä WIP raja", + "soft-wip-limit": "Pehmeä WIP-raja", "editCardStartDatePopup-title": "Muokkaa aloituspäivää", "editCardDueDatePopup-title": "Muokkaa eräpäivää", "editCustomFieldPopup-title": "Muokkaa kenttää", @@ -268,25 +268,25 @@ "editNotificationPopup-title": "Muokkaa ilmoituksia", "editProfilePopup-title": "Muokkaa profiilia", "email": "Sähköposti", - "email-enrollAccount-subject": "An account created for you on __siteName__", - "email-enrollAccount-text": "Hei __user__,\n\nAlkaaksesi käyttämään palvelua, klikkaa allaolevaa linkkiä.\n\n__url__\n\nKiitos.", + "email-enrollAccount-subject": "Sinulle on luotu tili palveluun __siteName__", + "email-enrollAccount-text": "Hei __user__,\n\nKlikkaa alla olevaa linkkiä aloittaaksesi palvelun käytön.\n\n__url__\n\nKiitos.", "email-fail": "Sähköpostin lähettäminen epäonnistui", "email-fail-text": "Virhe yrittäessä lähettää sähköpostia", "email-invalid": "Virheellinen sähköposti", "email-invite": "Kutsu sähköpostilla", "email-invite-subject": "__inviter__ lähetti sinulle kutsun", - "email-invite-text": "Hyvä __user__,\n\n__inviter__ kutsuu sinut liittymään taululle \"__board__\" yhteistyötä varten.\n\nOle hyvä ja seuraa allaolevaa linkkiä:\n\n__url__\n\nKiitos.", - "email-resetPassword-subject": "Reset your password on __siteName__", - "email-resetPassword-text": "Hei __user__,\n\nNollataksesi salasanasi, klikkaa allaolevaa linkkiä.\n\n__url__\n\nKiitos.", + "email-invite-text": "Hyvä __user__,\n\n__inviter__ kutsuu sinut liittymään taululle \"__board__\" yhteistyötä varten.\n\nOle hyvä ja seuraa alla olevaa linkkiä:\n\n__url__\n\nKiitos.", + "email-resetPassword-subject": "Nollaa salasanasi palvelussa __siteName__", + "email-resetPassword-text": "Hei __user__,\n\nNollataksesi salasanasi, klikkaa alla olevaa linkkiä.\n\n__url__\n\nKiitos.", "email-sent": "Sähköposti lähetetty", "email-verifyEmail-subject": "Varmista sähköpostiosoitteesi osoitteessa __url__", - "email-verifyEmail-text": "Hei __user__,\n\nvahvistaaksesi sähköpostiosoitteesi, klikkaa allaolevaa linkkiä.\n\n__url__\n\nKiitos.", + "email-verifyEmail-text": "Hei __user__,\n\nvahvistaaksesi sähköpostiosoitteesi, klikkaa alla olevaa linkkiä.\n\n__url__\n\nKiitos.", "enable-wip-limit": "Ota käyttöön WIP-raja", - "error-board-doesNotExist": "Tämä taulu ei ole olemassa", + "error-board-doesNotExist": "Tätä taulua ei ole olemassa", "error-board-notAdmin": "Tehdäksesi tämän sinun täytyy olla tämän taulun ylläpitäjä", "error-board-notAMember": "Tehdäksesi tämän sinun täytyy olla tämän taulun jäsen", - "error-json-malformed": "Tekstisi ei ole kelvollisessa JSON muodossa", - "error-json-schema": "JSON tietosi ei sisällä oikeaa tietoa oikeassa muodossa", + "error-json-malformed": "Tekstisi ei ole kelvollisessa JSON-muodossa", + "error-json-schema": "JSON-tietosi ei sisällä oikeaa tietoa oikeassa muodossa", "error-list-doesNotExist": "Tätä listaa ei ole olemassa", "error-user-doesNotExist": "Tätä käyttäjää ei ole olemassa", "error-user-notAllowSelf": "Et voi kutsua itseäsi", @@ -316,14 +316,14 @@ "import-board-c": "Tuo taulu", "import-board-title-trello": "Tuo taulu Trellosta", "import-board-title-wekan": "Tuo taulu edellisestä viennistä", - "import-sandstorm-backup-warning": "Älä poista tietoja joita toit alkuperäisestä viennistä tai Trellosta ennenkuin tarkistat onnistuuko sulkea ja avata tämä jyvä uudelleen, vai näkyykö Board not found virhe, joka tarkoittaa tietojen häviämistä.", - "import-sandstorm-warning": "Tuotu taulu poistaa kaikki olemassaolevan taulun tiedot ja korvaa ne tuodulla taululla.", + "import-sandstorm-backup-warning": "Älä poista tietoja joita toit alkuperäisestä viennistä tai Trellosta ennen kuin tarkistat onnistuuko sulkea ja avata tämä jyvä uudelleen, vai näkyykö Board not found -virhe, joka tarkoittaa tietojen häviämistä.", + "import-sandstorm-warning": "Tuotu taulu poistaa kaikki olemassa olevan taulun tiedot ja korvaa ne tuodulla taululla.", "from-trello": "Trellosta", "from-wekan": "Edellisestä viennistä", - "import-board-instruction-trello": "Trello taulullasi, mene 'Menu', sitten 'More', 'Print and Export', 'Export JSON', ja kopioi tuloksena saamasi teksti", + "import-board-instruction-trello": "Mene Trello-taulullasi 'Menu', sitten 'More', 'Print and Export', 'Export JSON', ja kopioi tuloksena saamasi teksti", "import-board-instruction-wekan": "Taulullasi, mene 'Valikko', sitten 'Vie taulu', ja kopioi teksti ladatusta tiedostosta.", "import-board-instruction-about-errors": "Jos virheitä tulee taulua tuotaessa, joskus tuonti silti toimii, ja taulu on Kaikki taulut sivulla.", - "import-json-placeholder": "Liitä kelvollinen JSON tietosi tähän", + "import-json-placeholder": "Liitä kelvollinen JSON-tietosi tähän", "import-map-members": "Vastaavat jäsenet", "import-members-map": "Tuomallasi taululla on muutamia jäseniä. Ole hyvä ja valitse tuomiasi jäseniä vastaavat käyttäjäsi", "import-show-user-mapping": "Tarkasta vastaavat jäsenet", @@ -345,17 +345,17 @@ "last-admin-desc": "Et voi vaihtaa rooleja koska täytyy olla olemassa ainakin yksi ylläpitäjä.", "leave-board": "Jää pois taululta", "leave-board-pop": "Haluatko varmasti poistua taululta __boardTitle__? Sinut poistetaan kaikista tämän taulun korteista.", - "leaveBoardPopup-title": "Jää pois taululta ?", + "leaveBoardPopup-title": "Poistu taululta?", "link-card": "Linkki tähän korttiin", "list-archive-cards": "Siirrä kaikki tämän listan kortit Arkistoon", "list-archive-cards-pop": "Tämä poistaa kaikki tämän listan kortit taululta. Nähdäksesi Arkistossa olevat kortit ja tuodaksesi ne takaisin taululle, klikkaa “Valikko” > “Arkisto”.", "list-move-cards": "Siirrä kaikki kortit tässä listassa", "list-select-cards": "Valitse kaikki kortit tässä listassa", "set-color-list": "Aseta väri", - "listActionPopup-title": "Listaa toimet", - "swimlaneActionPopup-title": "Swimlane toimet", + "listActionPopup-title": "Listatoimet", + "swimlaneActionPopup-title": "Swimlane-toimet", "swimlaneAddPopup-title": "Lisää Swimlane alle", - "listImportCardPopup-title": "Tuo Trello kortti", + "listImportCardPopup-title": "Tuo Trello-kortti", "listMorePopup-title": "Lisää", "link-list": "Linkki tähän listaan", "list-delete-pop": "Kaikki toimet poistetaan toimintasyötteestä ja listan poistaminen on lopullista. Tätä ei pysty peruuttamaan.", @@ -365,7 +365,7 @@ "log-out": "Kirjaudu ulos", "log-in": "Kirjaudu sisään", "loginPopup-title": "Kirjaudu sisään", - "memberMenuPopup-title": "Jäsen asetukset", + "memberMenuPopup-title": "Jäsenasetukset", "members": "Jäsenet", "menu": "Valikko", "move-selection": "Siirrä valinta", @@ -390,7 +390,7 @@ "notify-watch": "Vastaanota päivityksiä kaikilta tauluilta, listoilta tai korteilta joita seuraat.", "optional": "valinnainen", "or": "tai", - "page-maybe-private": "Tämä sivu voi olla yksityinen. Voit ehkä pystyä näkemään sen <a href='%s'>kirjautumalla sisään</a>.", + "page-maybe-private": "Tämä sivu voi olla yksityinen. Saatat nähdä sen <a href='%s'>kirjautumalla sisään</a>.", "page-not-found": "Sivua ei löytynyt.", "password": "Salasana", "paste-or-dragdrop": "liittääksesi, tai vedä & pudota kuvatiedosto siihen (vain kuva)", @@ -407,7 +407,7 @@ "remove-cover": "Poista kansi", "remove-from-board": "Poista taululta", "remove-label": "Poista tunniste", - "listDeletePopup-title": "Poista lista ?", + "listDeletePopup-title": "Poista lista?", "remove-member": "Poista jäsen", "remove-member-from-card": "Poista kortilta", "remove-member-pop": "Poista __name__ (__username__) taululta __boardTitle__? Jäsen poistetaan kaikilta taulun korteilta. Heille lähetetään ilmoitus.", @@ -419,7 +419,7 @@ "search": "Etsi", "rules": "Säännöt", "search-cards": "Etsi korttien otsikoista ja kuvauksista tällä taululla", - "search-example": "Teksti jota etsitään?", + "search-example": "Etsittävä teksti?", "select-color": "Valitse väri", "set-wip-limit-value": "Aseta tämän listan tehtävien enimmäismäärä", "setWipLimitPopup-title": "Aseta WIP-raja", @@ -429,9 +429,9 @@ "shortcut-clear-filters": "Poista kaikki suodattimet", "shortcut-close-dialog": "Sulje valintaikkuna", "shortcut-filter-my-cards": "Suodata korttini", - "shortcut-show-shortcuts": "Tuo esiin tämä pikavalinta lista", - "shortcut-toggle-filterbar": "Muokkaa suodatus sivupalkin näkyvyyttä", - "shortcut-toggle-sidebar": "Muokkaa taulu sivupalkin näkyvyyttä", + "shortcut-show-shortcuts": "Tuo esiin tämä pikavalintalista", + "shortcut-toggle-filterbar": "Muokkaa suodatussivupalkin näkyvyyttä", + "shortcut-toggle-sidebar": "Muokkaa taulusivupalkin näkyvyyttä", "show-cards-minimum-count": "Näytä korttien lukumäärä jos lista sisältää enemmän kuin", "sidebar-open": "Avaa sivupalkki", "sidebar-close": "Sulje sivupalkki", @@ -446,8 +446,8 @@ "spent-time-hours": "Käytetty aika (tuntia)", "overtime-hours": "Ylityö (tuntia)", "overtime": "Ylityö", - "has-overtime-cards": "Sisältää ylityö kortteja", - "has-spenttime-cards": "Sisältää käytetty aika kortteja", + "has-overtime-cards": "Sisältää ylityökortteja", + "has-spenttime-cards": "Sisältää käytetty aika -kortteja", "time": "Aika", "title": "Otsikko", "tracking": "Ilmoitukset", @@ -465,13 +465,13 @@ "watch": "Seuraa", "watching": "Seurataan", "watching-info": "Sinulle ilmoitetaan tämän taulun muutoksista", - "welcome-board": "Tervetuloa taulu", + "welcome-board": "Tervetuloa-taulu", "welcome-swimlane": "Merkkipaalu 1", "welcome-list1": "Perusasiat", "welcome-list2": "Edistynyt", - "card-templates-swimlane": "Kortti mallit", - "list-templates-swimlane": "Lista mallit", - "board-templates-swimlane": "Taulu mallit", + "card-templates-swimlane": "Korttimallit", + "list-templates-swimlane": "Listamallit", + "board-templates-swimlane": "Taulumallit", "what-to-do": "Mitä haluat tehdä?", "wipLimitErrorPopup-title": "Virheellinen WIP-raja", "wipLimitErrorPopup-dialog-pt1": "Tässä listassa olevien tehtävien määrä on korkeampi kuin asettamasi WIP-raja.", @@ -480,36 +480,36 @@ "settings": "Asetukset", "people": "Ihmiset", "registration": "Rekisteröinti", - "disable-self-registration": "Poista käytöstä itse-rekisteröityminen", + "disable-self-registration": "Poista käytöstä itserekisteröityminen", "invite": "Kutsu", "invite-people": "Kutsu ihmisiä", "to-boards": "Taulu(i)lle", "email-addresses": "Sähköpostiosoite", - "smtp-host-description": "SMTP palvelimen osoite jolla sähköpostit lähetetään.", - "smtp-port-description": "Portti jota STMP palvelimesi käyttää lähteville sähköposteille.", - "smtp-tls-description": "Ota käyttöön TLS tuki SMTP palvelimelle", - "smtp-host": "SMTP isäntä", - "smtp-port": "SMTP portti", + "smtp-host-description": "SMTP-palvelimen osoite jolla sähköpostit lähetetään.", + "smtp-port-description": "STMP-palvelimesi käyttämä lähteville sähköposteille tarkoitettu portti.", + "smtp-tls-description": "Ota käyttöön TLS-tuki SMTP-palvelimelle", + "smtp-host": "SMTP-isäntä", + "smtp-port": "SMTP-portti", "smtp-username": "Käyttäjätunnus", "smtp-password": "Salasana", - "smtp-tls": "TLS tuki", + "smtp-tls": "TLS-tuki", "send-from": "Lähettäjä", - "send-smtp-test": "Lähetä testi sähköposti itsellesi", + "send-smtp-test": "Lähetä testisähköposti itsellesi", "invitation-code": "Kutsukoodi", "email-invite-register-subject": "__inviter__ lähetti sinulle kutsun", - "email-invite-register-text": "Hei __user__,\n\n__inviter__ kutsuu sinut mukaan kanban taulun käyttöön.\n\nOle hyvä ja seuraa allaolevaa linkkiä:\n__url__\n\nJa kutsukoodisi on: __icode__\n\nKiitos.", - "email-smtp-test-subject": "SMTP testi sähköposti", + "email-invite-register-text": "Hei __user__,\n\n__inviter__ kutsuu sinut mukaan kanban-taulun käyttöön.\n\nOle hyvä ja seuraa alla olevaa linkkiä:\n__url__\n\nKutsukoodisi on: __icode__\n\nKiitos.", + "email-smtp-test-subject": "SMTP-testisähköposti", "email-smtp-test-text": "Olet onnistuneesti lähettänyt sähköpostin", - "error-invitation-code-not-exist": "Kutsukoodi ei ole olemassa", + "error-invitation-code-not-exist": "Kutsukoodia ei ole olemassa", "error-notAuthorized": "Sinulla ei ole oikeutta tarkastella tätä sivua.", "outgoing-webhooks": "Lähtevät Webkoukut", "outgoingWebhooksPopup-title": "Lähtevät Webkoukut", - "boardCardTitlePopup-title": "Kortin otsikko suodatin", + "boardCardTitlePopup-title": "Kortin otsikkosuodatin", "new-outgoing-webhook": "Uusi lähtevä Webkoukku", "no-name": "(Tuntematon)", - "Node_version": "Node versio", + "Node_version": "Node-versio", "OS_Arch": "Käyttöjärjestelmän arkkitehtuuri", - "OS_Cpus": "Käyttöjärjestelmän CPU määrä", + "OS_Cpus": "Käyttöjärjestelmän CPU-määrä", "OS_Freemem": "Käyttöjärjestelmän vapaa muisti", "OS_Loadavg": "Käyttöjärjestelmän kuorman keskiarvo", "OS_Platform": "Käyttöjärjestelmäalusta", @@ -548,13 +548,13 @@ "delete-board-confirm-popup": "Kaikki listat, kortit, tunnisteet ja toimet poistetaan ja et pysty palauttamaan taulun sisältöä. Tätä ei voi peruuttaa.", "boardDeletePopup-title": "Poista taulu?", "delete-board": "Poista taulu", - "default-subtasks-board": "Alitehtävät __board__ taululle", + "default-subtasks-board": "Alitehtävät taululle __board__", "default": "Oletus", "queue": "Jono", - "subtask-settings": "Alitehtävä asetukset", - "boardSubtaskSettingsPopup-title": "Taulu alitehtävien asetukset", + "subtask-settings": "Alitehtävä-asetukset", + "boardSubtaskSettingsPopup-title": "Taulualitehtävien asetukset", "show-subtasks-field": "Korteilla voi olla alitehtäviä", - "deposit-subtasks-board": "Tallenta alitehtävät tälle taululle:", + "deposit-subtasks-board": "Talleta alitehtävät tälle taululle:", "deposit-subtasks-list": "Laskeutumislista alatehtäville tallennettu tänne:", "show-parent-in-minicard": "Näytä ylätehtävä minikortilla:", "prefix-with-full-path": "Etuliite koko polulla", @@ -562,7 +562,7 @@ "subtext-with-full-path": "Aliteksti koko polulla", "subtext-with-parent": "Aliteksti ylätehtävällä", "change-card-parent": "Muuta kortin ylätehtävää", - "parent-card": "Ylätehtävä kortti", + "parent-card": "Ylätehtäväkortti", "source-board": "Lähdetaulu", "no-parent": "Älä näytä ylätehtävää", "activity-added-label": "lisätty tunniste '%s' kohteeseen %s", @@ -576,7 +576,7 @@ "r-rule": "Sääntö", "r-add-trigger": "Lisää liipaisin", "r-add-action": "Lisää toimi", - "r-board-rules": "Taulu säännöt", + "r-board-rules": "Taulusäännöt", "r-add-rule": "Lisää sääntö", "r-view-rule": "Näytä sääntö", "r-delete-rule": "Poista sääntö", @@ -682,10 +682,10 @@ "error-undefined": "Jotain meni pieleen", "error-ldap-login": "Virhe tapahtui yrittäessä kirjautua sisään", "display-authentication-method": "Näytä kirjautumistapa", - "default-authentication-method": "Oletus kirjautumistapa", + "default-authentication-method": "Oletuskirjautumistapa", "duplicate-board": "Tee kaksoiskappale taulusta", "people-number": "Ihmisten määrä on:", - "swimlaneDeletePopup-title": "Poista Swimlane ?", + "swimlaneDeletePopup-title": "Poista Swimlane?", "swimlane-delete-pop": "Kaikki toimet poistetaan toimintasyötteestä ja swimlanen poistaminen on lopullista. Tätä ei pysty peruuttamaan.", "restore-all": "Palauta kaikki", "delete-all": "Poista kaikki", diff --git a/models/export.js b/models/export.js index 4f17d727..8e5ce786 100644 --- a/models/export.js +++ b/models/export.js @@ -6,27 +6,34 @@ if (Meteor.isServer) { // `ApiRoutes.path('boards/export', boardId)`` // on the client instead of copy/pasting the route path manually between the // client and the server. - /* - * This route is used to export the board FROM THE APPLICATION. - * If user is already logged-in, pass loginToken as param "authToken": - * '/api/boards/:boardId/export?authToken=:token' + /** + * @operation export + * @tag Boards + * + * @summary This route is used to export the board. + * + * @description If user is already logged-in, pass loginToken as param + * "authToken": '/api/boards/:boardId/export?authToken=:token' * * See https://blog.kayla.com.au/server-side-route-authentication-in-meteor/ * for detailed explanations + * + * @param {string} boardId the ID of the board we are exporting + * @param {string} authToken the loginToken */ - - JsonRoutes.add('get', '/api/boards/:boardId/export', function(req, res) { const boardId = req.params.boardId; let user = null; - // todo XXX for real API, first look for token in Authentication: header - // then fallback to parameter + const loginToken = req.query.authToken; if (loginToken) { const hashToken = Accounts._hashLoginToken(loginToken); user = Meteor.users.findOne({ 'services.resume.loginTokens.hashedToken': hashToken, }); + } else if (!Meteor.settings.public.sandstorm) { + Authentication.checkUserId(req.userId); + user = Users.findOne({ _id: req.userId, isAdmin: true }); } const exporter = new Exporter(boardId); diff --git a/openapi/generate_openapi.py b/openapi/generate_openapi.py index 2a898f0e..1bf04c15 100644 --- a/openapi/generate_openapi.py +++ b/openapi/generate_openapi.py @@ -678,7 +678,7 @@ def parse_schemas(schemas_dir): data = ''.join(f.readlines()) try: # if the file failed, it's likely it doesn't contain a schema - program = esprima.parseScript(data, options={'comment': True, 'loc': True}) + program = esprima.parseModule(data, options={'comment': True, 'loc': True}) except: continue diff --git a/package.json b/package.json index 1d7c4a5b..a238b96a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "wekan", - "version": "v2.72.0", + "version": "v2.73.0", "description": "Open-Source kanban", "private": true, "scripts": { diff --git a/sandstorm-pkgdef.capnp b/sandstorm-pkgdef.capnp index 4df6c74d..25baa88d 100644 --- a/sandstorm-pkgdef.capnp +++ b/sandstorm-pkgdef.capnp @@ -22,10 +22,10 @@ const pkgdef :Spk.PackageDefinition = ( appTitle = (defaultText = "Wekan"), # The name of the app as it is displayed to the user. - appVersion = 274, + appVersion = 275, # Increment this for every release. - appMarketingVersion = (defaultText = "2.72.0~2019-05-13"), + appMarketingVersion = (defaultText = "2.73.0~2019-05-14"), # Human-readable presentation of the app version. minUpgradableAppVersion = 0, diff --git a/server/publications/boards.js b/server/publications/boards.js index 52940739..cec03858 100644 --- a/server/publications/boards.js +++ b/server/publications/boards.js @@ -59,9 +59,12 @@ Meteor.publish('archivedBoards', function() { }); }); -Meteor.publishRelations('board', function(boardId) { +// If isArchived = false, this will only return board elements which are not archived. +// If isArchived = true, this will only return board elements which are archived. +Meteor.publishRelations('board', function(boardId, isArchived) { this.unblock(); check(boardId, String); + check(isArchived, Boolean); const thisUserId = this.userId; this.cursor(Boards.find({ @@ -75,8 +78,8 @@ Meteor.publishRelations('board', function(boardId) { ], // Sort required to ensure oplog usage }, { limit: 1, sort: { _id: 1 } }), function(boardId, board) { - this.cursor(Lists.find({ boardId })); - this.cursor(Swimlanes.find({ boardId })); + this.cursor(Lists.find({ boardId, archived: isArchived })); + this.cursor(Swimlanes.find({ boardId, archived: isArchived })); this.cursor(Integrations.find({ boardId })); this.cursor(CustomFields.find({ boardIds: {$in: [boardId]} }, { sort: { name: 1 } })); @@ -115,8 +118,9 @@ Meteor.publishRelations('board', function(boardId) { parentCards.selector = (_ids) => ({ parentId: _ids }); const boards = this.join(Boards); const subCards = this.join(Cards); + subCards.selector = (_ids) => ({ archived: isArchived }); - this.cursor(Cards.find({ boardId: {$in: [boardId, board.subtasksDefaultBoardId]}}), function(cardId, card) { + this.cursor(Cards.find({ boardId: {$in: [boardId, board.subtasksDefaultBoardId]}, archived: isArchived }), function(cardId, card) { if (card.type === 'cardType-linkedCard') { const impCardId = card.linkedId; subCards.push(impCardId); diff --git a/server/publications/fast-render.js b/server/publications/fast-render.js index 7c54c686..4829ad57 100644 --- a/server/publications/fast-render.js +++ b/server/publications/fast-render.js @@ -5,5 +5,5 @@ FastRender.onAllRoutes(function() { }); FastRender.route('/b/:id/:slug', function({ id }) { - this.subscribe('board', id); + this.subscribe('board', id, false); }); |