Merge branch 'edge' into meteor-1.8

This commit is contained in:
Lauri Ojansivu 2019-05-14 16:56:35 +03:00
commit 4903f3a814
18 changed files with 209 additions and 153 deletions

View file

@ -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:

View file

@ -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 && \

View file

@ -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

View file

@ -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());

View file

@ -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();
},

View file

@ -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);
}

View file

@ -99,6 +99,10 @@
.highlight
color: #ce1414
.cardCount
color: #8c8c8c
font-size: 0.8em
.list-body
flex: 1 1 auto
flex-direction: column

View file

@ -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) {

View file

@ -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

View file

@ -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

View file

@ -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' },

View file

@ -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",

View file

@ -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);

View file

@ -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

View file

@ -1,6 +1,6 @@
{
"name": "wekan",
"version": "v2.72.0",
"version": "v2.73.0",
"description": "Open-Source kanban",
"private": true,
"scripts": {

View file

@ -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,

View file

@ -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);

View file

@ -5,5 +5,5 @@ FastRender.onAllRoutes(function() {
});
FastRender.route('/b/:id/:slug', function({ id }) {
this.subscribe('board', id);
this.subscribe('board', id, false);
});