summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.eslintrc.json1
-rw-r--r--.github/ISSUE_TEMPLATE.md15
-rw-r--r--CHANGELOG.md9
-rw-r--r--client/components/cards/cardDate.js126
-rw-r--r--client/components/cards/cardDate.styl10
-rw-r--r--client/components/cards/cardDetails.jade45
-rw-r--r--client/components/cards/cardDetails.js52
-rw-r--r--client/components/cards/cardDetails.styl4
-rw-r--r--client/components/cards/checklists.jade41
-rw-r--r--client/components/cards/checklists.js110
-rw-r--r--client/components/cards/checklists.styl82
-rw-r--r--client/lib/utils.js31
-rw-r--r--i18n/ar.i18n.json8
-rw-r--r--i18n/bg.i18n.json8
-rw-r--r--i18n/br.i18n.json8
-rw-r--r--i18n/ca.i18n.json8
-rw-r--r--i18n/cs.i18n.json8
-rw-r--r--i18n/de.i18n.json8
-rw-r--r--i18n/el.i18n.json8
-rw-r--r--i18n/en-GB.i18n.json8
-rw-r--r--i18n/en.i18n.json8
-rw-r--r--i18n/eo.i18n.json8
-rw-r--r--i18n/es-AR.i18n.json8
-rw-r--r--i18n/es.i18n.json8
-rw-r--r--i18n/eu.i18n.json8
-rw-r--r--i18n/fa.i18n.json8
-rw-r--r--i18n/fi.i18n.json8
-rw-r--r--i18n/fr.i18n.json12
-rw-r--r--i18n/gl.i18n.json8
-rw-r--r--i18n/he.i18n.json8
-rw-r--r--i18n/hu.i18n.json8
-rw-r--r--i18n/hy.i18n.json8
-rw-r--r--i18n/id.i18n.json8
-rw-r--r--i18n/ig.i18n.json8
-rw-r--r--i18n/it.i18n.json8
-rw-r--r--i18n/ja.i18n.json8
-rw-r--r--i18n/lv.i18n.json8
-rw-r--r--i18n/mn.i18n.json8
-rw-r--r--i18n/nb.i18n.json8
-rw-r--r--i18n/nl.i18n.json64
-rw-r--r--i18n/pl.i18n.json8
-rw-r--r--i18n/pt-BR.i18n.json22
-rw-r--r--i18n/pt.i18n.json8
-rw-r--r--i18n/ro.i18n.json8
-rw-r--r--i18n/ru.i18n.json8
-rw-r--r--i18n/sr.i18n.json8
-rw-r--r--i18n/sv.i18n.json8
-rw-r--r--i18n/ta.i18n.json8
-rw-r--r--i18n/th.i18n.json8
-rw-r--r--i18n/tr.i18n.json8
-rw-r--r--i18n/uk.i18n.json8
-rw-r--r--i18n/vi.i18n.json8
-rw-r--r--i18n/zh-CN.i18n.json8
-rw-r--r--i18n/zh-TW.i18n.json8
-rw-r--r--models/activities.js2
-rw-r--r--models/cards.js26
-rw-r--r--models/checklistItems.js95
-rw-r--r--models/checklists.js173
-rw-r--r--server/migrations.js21
-rw-r--r--server/publications/boards.js1
-rwxr-xr-xsnap-src/bin/config2
-rw-r--r--snapcraft.yaml2
62 files changed, 892 insertions, 366 deletions
diff --git a/.eslintrc.json b/.eslintrc.json
index 8bd678b3..0a9f3c90 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -131,6 +131,7 @@
"AccountSettings": true,
"Announcements": true,
"Swimlanes": true,
+ "ChecklistItems": true,
"Npm": true
}
}
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index a9e08009..b95928c6 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -1,16 +1,23 @@
## Issue
-**Impacted version**: xxxx
+**DO NOT ADD ISSUES ABOUT DOCKER**
+
+* [Docker destroys your data](https://github.com/wekan/wekan-mongodb/issues/9)
+* Docker Hub image is broken. Quay image has problems too.
+* If you would like for Docker to work, please add fix as pull request to devel branch
+
+**Impacted version**:
**Server Setup Information**:
* Operating System:
-* Deployment Method(tar/sandstorm/snap/docker/etc /http frontend (nginx, httpd, ...)):
+* Deployment Method(snap/sandstorm/mongodb bundle):
+* Http frontend (Caddy, Nginx, Apache, see config examples from Wekan GitHub wiki first):
* Node Version:
* MongoDB Version:
-* ROOT_URL environment variable (Is there a subfolder?):
+* ROOT_URL environment variable http(s)://(subdomain).example.com(/suburl):
**Problem description**:
- *be as explicit as you can*
- *describe the problem and its symptoms*
- *explain how to reproduce*
-- *attach whatever information that can help understanding the context (screen capture, log files)*
+- *attach whatever information that can help understanding the context (screen capture, log files in .zip file)*
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7883cfa3..5cb97d4a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,12 @@
+# Upcoming Wekan release
+
+This release adds the following new features:
+
+- [Checklist items sort fix, and checklist sort capability](https://github.com/wekan/wekan/pull/1543);
+- [Add Received Date and End Date. Between them is already existing Start and Due Date](https://github.com/wekan/wekan/pull/1550).
+
+Thanks to GitHub users andresmanelli and rjevnikar for their contributions.
+
# v0.78 2018-03-17 Wekan release
This release adds the following new features:
diff --git a/client/components/cards/cardDate.js b/client/components/cards/cardDate.js
index abf6a42b..7c0ad6ab 100644
--- a/client/components/cards/cardDate.js
+++ b/client/components/cards/cardDate.js
@@ -1,4 +1,4 @@
-// Edit start & due dates
+// Edit received, start, due & end dates
const EditCardDate = BlazeComponent.extendComponent({
template() {
return 'editCardDate';
@@ -92,6 +92,23 @@ Template.dateBadge.helpers({
},
});
+// editCardReceivedDatePopup
+(class extends EditCardDate {
+ onCreated() {
+ super.onCreated();
+ this.data().receivedAt && this.date.set(moment(this.data().receivedAt));
+ }
+
+ _storeDate(date) {
+ this.card.setReceived(date);
+ }
+
+ _deleteDate() {
+ this.card.unsetReceived();
+ }
+}).register('editCardReceivedDatePopup');
+
+
// editCardStartDatePopup
(class extends EditCardDate {
onCreated() {
@@ -99,6 +116,13 @@ Template.dateBadge.helpers({
this.data().startAt && this.date.set(moment(this.data().startAt));
}
+ onRendered() {
+ super.onRendered();
+ if (moment.isDate(this.card.receivedAt)) {
+ this.$('.js-datepicker').datepicker('setStartDate', this.card.receivedAt);
+ }
+ }
+
_storeDate(date) {
this.card.setStart(date);
}
@@ -131,8 +155,31 @@ Template.dateBadge.helpers({
}
}).register('editCardDueDatePopup');
+// editCardEndDatePopup
+(class extends EditCardDate {
+ onCreated() {
+ super.onCreated();
+ this.data().endAt && this.date.set(moment(this.data().endAt));
+ }
+
+ onRendered() {
+ super.onRendered();
+ if (moment.isDate(this.card.startAt)) {
+ this.$('.js-datepicker').datepicker('setStartDate', this.card.startAt);
+ }
+ }
+
+ _storeDate(date) {
+ this.card.setEnd(date);
+ }
+
+ _deleteDate() {
+ this.card.unsetEnd();
+ }
+}).register('editCardEndDatePopup');
+
-// Display start & due dates
+// Display received, start, due & end dates
const CardDate = BlazeComponent.extendComponent({
template() {
return 'dateBadge';
@@ -161,6 +208,36 @@ const CardDate = BlazeComponent.extendComponent({
},
});
+class CardReceivedDate extends CardDate {
+ onCreated() {
+ super.onCreated();
+ const self = this;
+ self.autorun(() => {
+ self.date.set(moment(self.data().receivedAt));
+ });
+ }
+
+ classes() {
+ let classes = 'received-date' + ' ';
+ if (this.date.get().isBefore(this.now.get(), 'minute') &&
+ this.now.get().isBefore(this.data().dueAt)) {
+ classes += 'current';
+ }
+ return classes;
+ }
+
+ showTitle() {
+ return `${TAPi18n.__('card-received-on')} ${this.date.get().format('LLLL')}`;
+ }
+
+ events() {
+ return super.events().concat({
+ 'click .js-edit-date': Popup.open('editCardReceivedDate'),
+ });
+ }
+}
+CardReceivedDate.register('cardReceivedDate');
+
class CardStartDate extends CardDate {
onCreated() {
super.onCreated();
@@ -223,6 +300,44 @@ class CardDueDate extends CardDate {
}
CardDueDate.register('cardDueDate');
+class CardEndDate extends CardDate {
+ onCreated() {
+ super.onCreated();
+ const self = this;
+ self.autorun(() => {
+ self.date.set(moment(self.data().endAt));
+ });
+ }
+
+ classes() {
+ let classes = 'end-date' + ' ';
+ if (this.data.dueAt.diff(this.date.get(), 'days') >= 2)
+ classes += 'long-overdue';
+ else if (this.data.dueAt.diff(this.date.get(), 'days') >= 0)
+ classes += 'due';
+ else if (this.data.dueAt.diff(this.date.get(), 'days') >= -2)
+ classes += 'almost-due';
+ return classes;
+ }
+
+ showTitle() {
+ return `${TAPi18n.__('card-end-on')} ${this.date.get().format('LLLL')}`;
+ }
+
+ events() {
+ return super.events().concat({
+ 'click .js-edit-date': Popup.open('editCardEndDate'),
+ });
+ }
+}
+CardEndDate.register('cardEndDate');
+
+(class extends CardReceivedDate {
+ showDate() {
+ return this.date.get().format('l');
+ }
+}).register('minicardReceivedDate');
+
(class extends CardStartDate {
showDate() {
return this.date.get().format('l');
@@ -234,3 +349,10 @@ CardDueDate.register('cardDueDate');
return this.date.get().format('l');
}
}).register('minicardDueDate');
+
+(class extends CardEndDate {
+ showDate() {
+ return this.date.get().format('l');
+ }
+}).register('minicardEndDate');
+
diff --git a/client/components/cards/cardDate.styl b/client/components/cards/cardDate.styl
index e0c3fc9e..1ad3adb3 100644
--- a/client/components/cards/cardDate.styl
+++ b/client/components/cards/cardDate.styl
@@ -49,6 +49,11 @@
&:hover, &.is-active
background-color: darken(#fd5d47, 7)
+ &.end-date
+ time
+ &::before
+ content: "\f253" // symbol: fa-hourglass-end
+
&.due-date
time
&::before
@@ -59,6 +64,11 @@
&::before
content: "\f08b" // symbol: fa-sign-out
+ &.received-date
+ time
+ &::before
+ content: "\f251" // symbol: fa-hourglass-start
+
time
&::before
font: normal normal normal 14px/1 FontAwesome
diff --git a/client/components/cards/cardDetails.jade b/client/components/cards/cardDetails.jade
index cc95ca38..3e73071a 100644
--- a/client/components/cards/cardDetails.jade
+++ b/client/components/cards/cardDetails.jade
@@ -18,6 +18,35 @@ template(name="cardDetails")
p.warning {{_ 'card-archived'}}
.card-details-items
+ .card-details-item.card-details-item-received
+ h3.card-details-item-title {{_ 'card-received'}}
+ if receivedAt
+ +cardReceivedDate
+ else
+ a.js-received-date {{_ 'add'}}
+
+ .card-details-item.card-details-item-start
+ h3.card-details-item-title {{_ 'card-start'}}
+ if startAt
+ +cardStartDate
+ else
+ a.js-start-date {{_ 'add'}}
+
+ .card-details-item.card-details-item-due
+ h3.card-details-item-title {{_ 'card-due'}}
+ if dueAt
+ +cardDueDate
+ else
+ a.js-due-date {{_ 'add'}}
+
+ .card-details-item.card-details-item-end
+ h3.card-details-item-title {{_ 'card-end'}}
+ if endAt
+ +cardEndDate
+ else
+ a.js-end-date {{_ 'add'}}
+
+ .card-details-items
.card-details-item.card-details-item-members
h3.card-details-item-title {{_ 'members'}}
each members
@@ -36,16 +65,6 @@ template(name="cardDetails")
a.card-label.add-label.js-add-labels(title="{{_ 'card-labels-title'}}")
i.fa.fa-plus
- if startAt
- .card-details-item.card-details-item-start
- h3.card-details-item-title {{_ 'card-start'}}
- +cardStartDate
-
- if dueAt
- .card-details-item.card-details-item-due
- h3.card-details-item-title {{_ 'card-due'}}
- +cardDueDate
-
.card-details-items
if spentTime
.card-details-item.card-details-item-spent
@@ -86,7 +105,7 @@ template(name="cardDetails")
+checklists(cardId = _id)
hr
- h2
+ h3
i.fa.fa-paperclip
| {{_ 'attachments'}}
@@ -94,7 +113,7 @@ template(name="cardDetails")
hr
.activity-title
- h2 {{ _ 'activity'}}
+ h3 {{ _ 'activity'}}
if currentUser.isBoardMember
.material-toggle-switch
span.toggle-switch-title {{_ 'hide-system-messages'}}
@@ -124,8 +143,10 @@ template(name="cardDetailsActionsPopup")
li: a.js-members {{_ 'card-edit-members'}}
li: a.js-labels {{_ 'card-edit-labels'}}
li: a.js-attachments {{_ 'card-edit-attachments'}}
+ li: a.js-received-date {{_ 'editCardReceivedDatePopup-title'}}
li: a.js-start-date {{_ 'editCardStartDatePopup-title'}}
li: a.js-due-date {{_ 'editCardDueDatePopup-title'}}
+ li: a.js-end-date {{_ 'editCardEndDatePopup-title'}}
li: a.js-spent-time {{_ 'editCardSpentTimePopup-title'}}
hr
ul.pop-over-list
diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js
index ab8a6288..421cef53 100644
--- a/client/components/cards/cardDetails.js
+++ b/client/components/cards/cardDetails.js
@@ -1,4 +1,5 @@
const subManager = new SubsManager();
+const { calculateIndexData } = Utils;
BlazeComponent.extendComponent({
mixins() {
@@ -66,6 +67,51 @@ BlazeComponent.extendComponent({
onRendered() {
if (!Utils.isMiniScreen()) this.scrollParentContainer();
+ const $checklistsDom = this.$('.card-checklist-items');
+
+ $checklistsDom.sortable({
+ tolerance: 'pointer',
+ helper: 'clone',
+ handle: '.checklist-title',
+ items: '.js-checklist',
+ placeholder: 'checklist placeholder',
+ distance: 7,
+ start(evt, ui) {
+ ui.placeholder.height(ui.helper.height());
+ EscapeActions.executeUpTo('popup-close');
+ },
+ stop(evt, ui) {
+ let prevChecklist = ui.item.prev('.js-checklist').get(0);
+ if (prevChecklist) {
+ prevChecklist = Blaze.getData(prevChecklist).checklist;
+ }
+ let nextChecklist = ui.item.next('.js-checklist').get(0);
+ if (nextChecklist) {
+ nextChecklist = Blaze.getData(nextChecklist).checklist;
+ }
+ const sortIndex = calculateIndexData(prevChecklist, nextChecklist, 1);
+
+ $checklistsDom.sortable('cancel');
+ const checklist = Blaze.getData(ui.item.get(0)).checklist;
+
+ Checklists.update(checklist._id, {
+ $set: {
+ sort: sortIndex.base,
+ },
+ });
+ },
+ });
+
+ function userIsMember() {
+ return Meteor.user() && Meteor.user().isBoardMember();
+ }
+
+ // Disable sorting if the current user is not a board member
+ this.autorun(() => {
+ if ($checklistsDom.data('sortable')) {
+ $checklistsDom.sortable('option', 'disabled', !userIsMember());
+ }
+ });
},
onDestroyed() {
@@ -103,6 +149,10 @@ BlazeComponent.extendComponent({
'click .js-member': Popup.open('cardMember'),
'click .js-add-members': Popup.open('cardMembers'),
'click .js-add-labels': Popup.open('cardLabels'),
+ 'click .js-received-date': Popup.open('editCardReceivedDate'),
+ 'click .js-start-date': Popup.open('editCardStartDate'),
+ 'click .js-due-date': Popup.open('editCardDueDate'),
+ 'click .js-end-date': Popup.open('editCardEndDate'),
'mouseenter .js-card-details' () {
this.parentComponent().parentComponent().showOverlay.set(true);
this.parentComponent().parentComponent().mouseHasEnterCardDetails = true;
@@ -165,8 +215,10 @@ Template.cardDetailsActionsPopup.events({
'click .js-members': Popup.open('cardMembers'),
'click .js-labels': Popup.open('cardLabels'),
'click .js-attachments': Popup.open('cardAttachments'),
+ 'click .js-received-date': Popup.open('editCardReceivedDate'),
'click .js-start-date': Popup.open('editCardStartDate'),
'click .js-due-date': Popup.open('editCardDueDate'),
+ 'click .js-end-date': Popup.open('editCardEndDate'),
'click .js-spent-time': Popup.open('editCardSpentTime'),
'click .js-move-card': Popup.open('moveCard'),
'click .js-copy-card': Popup.open('copyCard'),
diff --git a/client/components/cards/cardDetails.styl b/client/components/cards/cardDetails.styl
index c67522d1..a1e0f5c3 100644
--- a/client/components/cards/cardDetails.styl
+++ b/client/components/cards/cardDetails.styl
@@ -77,8 +77,10 @@
margin-right: 0
&.card-details-item-labels,
&.card-details-item-members,
+ &.card-details-item-received,
&.card-details-item-start,
- &.card-details-item-due
+ &.card-details-item-due,
+ &.card-details-item-end
width: 50%
flex-shrink: 1
diff --git a/client/components/cards/checklists.jade b/client/components/cards/checklists.jade
index 42fe3bd4..5a7c7473 100644
--- a/client/components/cards/checklists.jade
+++ b/client/components/cards/checklists.jade
@@ -1,5 +1,5 @@
template(name="checklists")
- h2 {{_ 'checklists'}}
+ h3 {{_ 'checklists'}}
if toggleDeleteDialog.get
.board-overlay#card-details-overlay
+checklistDeleteDialog(checklist = checklistToDelete)
@@ -18,24 +18,25 @@ template(name="checklists")
| {{_ 'add-checklist'}}...
template(name="checklistDetail")
- +inlinedForm(classNames="js-edit-checklist-title" checklist = checklist)
- +editChecklistItemForm(checklist = checklist)
- else
- .checklist-title
- .checkbox.fa.fa-check-square-o
- if canModifyCard
- a.js-delete-checklist.toggle-delete-checklist-dialog {{_ "delete"}}...
-
- span.checklist-stat(class="{{#if checklist.isFinished}}is-finished{{/if}}") {{checklist.finishedCount}}/{{checklist.itemCount}}
- if canModifyCard
- h2.title.js-open-inlined-form.is-editable
- +viewer
- = checklist.title
- else
- h2.title
- +viewer
+ .js-checklist.checklist
+ +inlinedForm(classNames="js-edit-checklist-title" checklist = checklist)
+ +editChecklistItemForm(checklist = checklist)
+ else
+ .checklist-title
+ .checkbox.fa.fa-check-square-o
+ if canModifyCard
+ a.js-delete-checklist.toggle-delete-checklist-dialog {{_ "delete"}}...
+
+ span.checklist-stat(class="{{#if checklist.isFinished}}is-finished{{/if}}") {{checklist.finishedCount}}/{{checklist.itemCount}}
+ if canModifyCard
+ h2.title.js-open-inlined-form.is-editable
+ +viewer
= checklist.title
- +checklistItems(checklist = checklist)
+ else
+ h2.title
+ +viewer
+ = checklist.title
+ +checklistItems(checklist = checklist)
template(name="checklistDeleteDialog")
.js-confirm-checklist-delete
@@ -70,7 +71,7 @@ template(name="editChecklistItemForm")
template(name="checklistItems")
.checklist-items.js-checklist-items
- each item in checklist.getItemsSorted
+ each item in checklist.items
+inlinedForm(classNames="js-edit-checklist-item" item = item checklist = checklist)
+editChecklistItemForm(type = 'item' item = item checklist = checklist)
else
@@ -84,7 +85,7 @@ template(name="checklistItems")
| {{_ 'add-checklist-item'}}...
template(name='itemDetail')
- .item.js-checklist-item
+ .js-checklist-item.checklist-item
if canModifyCard
.check-box.materialCheckBox(class="{{#if item.isFinished }}is-checked{{/if}}")
.item-title.js-open-inlined-form.is-editable(class="{{#if item.isFinished }}is-checked{{/if}}")
diff --git a/client/components/cards/checklists.js b/client/components/cards/checklists.js
index 5c0e3d2e..1f05aded 100644
--- a/client/components/cards/checklists.js
+++ b/client/components/cards/checklists.js
@@ -1,11 +1,14 @@
+const { calculateIndexData } = Utils;
+
function initSorting(items) {
items.sortable({
tolerance: 'pointer',
helper: 'clone',
items: '.js-checklist-item:not(.placeholder)',
- axis: 'y',
+ connectWith: '.js-checklist-items',
+ appendTo: '.board-canvas',
distance: 7,
- placeholder: 'placeholder',
+ placeholder: 'checklist-item placeholder',
scroll: false,
start(evt, ui) {
ui.placeholder.height(ui.helper.height());
@@ -13,57 +16,54 @@ function initSorting(items) {
},
stop(evt, ui) {
const parent = ui.item.parents('.js-checklist-items');
- const orderedItems = [];
- parent.find('.js-checklist-item').each(function(i, item) {
- const checklistItem = Blaze.getData(item).item;
- orderedItems.push(checklistItem._id);
- });
- items.sortable('cancel');
- const formerParent = ui.item.parents('.js-checklist-items');
- const checklist = Blaze.getData(parent.get(0)).checklist;
- const oldChecklist = Blaze.getData(formerParent.get(0)).checklist;
- if (oldChecklist._id !== checklist._id) {
- const currentItem = Blaze.getData(ui.item.get(0)).item;
- for (let i = 0; i < orderedItems.length; i++) {
- const itemId = orderedItems[i];
- if (itemId !== currentItem._id) continue;
- const newItem = {
- _id: checklist.getNewItemId(),
- title: currentItem.title,
- sort: i,
- isFinished: currentItem.isFinished,
- };
- checklist.addFullItem(newItem);
- orderedItems[i] = currentItem._id;
- oldChecklist.removeItem(itemId);
- }
- } else {
- checklist.sortItems(orderedItems);
+ const checklistId = Blaze.getData(parent.get(0)).checklist._id;
+ let prevItem = ui.item.prev('.js-checklist-item').get(0);
+ if (prevItem) {
+ prevItem = Blaze.getData(prevItem).item;
+ }
+ let nextItem = ui.item.next('.js-checklist-item').get(0);
+ if (nextItem) {
+ nextItem = Blaze.getData(nextItem).item;
}
+ const nItems = 1;
+ const sortIndex = calculateIndexData(prevItem, nextItem, nItems);
+ const checklistDomElement = ui.item.get(0);
+ const checklistData = Blaze.getData(checklistDomElement);
+ const checklistItem = checklistData.item;
+
+ items.sortable('cancel');
+
+ checklistItem.move(checklistId, sortIndex.base);
},
});
}
-Template.checklists.onRendered(function () {
- const self = BlazeComponent.getComponentForElement(this.firstNode);
- self.itemsDom = this.$('.card-checklist-items');
- initSorting(self.itemsDom);
- self.itemsDom.mousedown(function(evt) {
- evt.stopPropagation();
- });
+BlazeComponent.extendComponent({
+ onRendered() {
+ const self = this;
+ self.itemsDom = this.$('.js-checklist-items');
+ initSorting(self.itemsDom);
+ self.itemsDom.mousedown(function(evt) {
+ evt.stopPropagation();
+ });
+
+ function userIsMember() {
+ return Meteor.user() && Meteor.user().isBoardMember();
+ }
- function userIsMember() {
- return Meteor.user() && Meteor.user().isBoardMember();
- }
+ // Disable sorting if the current user is not a board member
+ self.autorun(() => {
+ const $itemsDom = $(self.itemsDom);
+ if ($itemsDom.data('sortable')) {
+ $(self.itemsDom).sortable('option', 'disabled', !userIsMember());
+ }
+ });
+ },
- // Disable sorting if the current user is not a board member
- self.autorun(() => {
- const $itemsDom = $(self.itemsDom);
- if ($itemsDom.data('sortable')) {
- $(self.itemsDom).sortable('option', 'disabled', !userIsMember());
- }
- });
-});
+ canModifyCard() {
+ return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
+ },
+}).register('checklistDetail');
BlazeComponent.extendComponent({
@@ -95,7 +95,12 @@ BlazeComponent.extendComponent({
const checklist = this.currentData().checklist;
if (title) {
- checklist.addItem(title);
+ ChecklistItems.insert({
+ title,
+ checklistId: checklist._id,
+ cardId: checklist.cardId,
+ sort: checklist.itemCount(),
+ });
}
// We keep the form opened, empty it.
textarea.value = '';
@@ -118,7 +123,7 @@ BlazeComponent.extendComponent({
const checklist = this.currentData().checklist;
const item = this.currentData().item;
if (checklist && item && item._id) {
- checklist.removeItem(item._id);
+ ChecklistItems.remove(item._id);
}
},
@@ -135,9 +140,8 @@ BlazeComponent.extendComponent({
const textarea = this.find('textarea.js-edit-checklist-item');
const title = textarea.value.trim();
- const itemId = this.currentData().item._id;
- const checklist = this.currentData().checklist;
- checklist.editItem(itemId, title);
+ const item = this.currentData().item;
+ item.setTitle(title);
},
onCreated() {
@@ -211,12 +215,12 @@ BlazeComponent.extendComponent({
const checklist = this.currentData().checklist;
const item = this.currentData().item;
if (checklist && item && item._id) {
- checklist.toggleItem(item._id);
+ item.toggleItem();
}
},
events() {
return [{
- 'click .item .check-box': this.toggleItem,
+ 'click .js-checklist-item .check-box': this.toggleItem,
}];
},
}).register('itemDetail');
diff --git a/client/components/cards/checklists.styl b/client/components/cards/checklists.styl
index d4776397..7b35488f 100644
--- a/client/components/cards/checklists.styl
+++ b/client/components/cards/checklists.styl
@@ -78,34 +78,60 @@ textarea.js-add-checklist-item, textarea.js-edit-checklist-item
bottom: -600px
right: 0
-.checklist-items
+.checklist
+ background: darken(white, 3%)
+
+ &.placeholder
+ background: darken(white, 20%)
+ border-radius: 2px
+
+ &.ui-sortable-helper
+ box-shadow: -2px 2px 8px rgba(0, 0, 0, .3),
+ 0 0 1px rgba(0, 0, 0, .5)
+ transform: rotate(4deg)
+ cursor: grabbing
+
+
+.checklist-item
margin: 0 0 0.5em 1.33em
+ line-height: 25px
+ font-size: 1.1em
+ margin-top: 3px
+ display: flex
+ background: darken(white, 3%)
+
+ &.placeholder
+ background: darken(white, 20%)
+ border-radius: 2px
+
+ &.ui-sortable-helper
+ box-shadow: -2px 2px 8px rgba(0, 0, 0, .3),
+ 0 0 1px rgba(0, 0, 0, .5)
+ transform: rotate(4deg)
+ cursor: grabbing
- .item
- line-height: 25px
- font-size: 1.1em
- margin-top: 3px
- display: flex
- &:hover
- background-color: darken(white, 8%)
-
- .check-box
- margin-top: 5px
- &.is-checked
- border-bottom: 2px solid #3cb500
- border-right: 2px solid #3cb500
-
- .item-title
- flex: 1
- padding-left: 10px;
- &.is-checked
- color: #8c8c8c
- font-style: italic
-
- .js-delete-checklist-item
- @extends .delete-text
- padding: 12px 0 0 0
+ &:hover
+ background-color: darken(white, 8%)
+
+ .check-box
+ margin-top: 5px
+ &.is-checked
+ border-bottom: 2px solid #3cb500
+ border-right: 2px solid #3cb500
+
+ .item-title
+ flex: 1
+ padding-left: 10px;
+ &.is-checked
+ color: #8c8c8c
+ font-style: italic
+
+.js-delete-checklist-item
+ margin: 0 0 0.5em 1.33em
+ @extends .delete-text
+ padding: 12px 0 0 0
- .add-checklist-item
- padding-top: 0.5em
- display: inline-block
+.add-checklist-item
+ margin: 0 0 0.5em 1.33em
+ padding-top: 0.5em
+ display: inline-block
diff --git a/client/lib/utils.js b/client/lib/utils.js
index 9a9ff654..1f44c60d 100644
--- a/client/lib/utils.js
+++ b/client/lib/utils.js
@@ -33,6 +33,37 @@ Utils = {
return $(window).width() <= 800;
},
+ calculateIndexData(prevData, nextData, nItems = 1) {
+ let base, increment;
+ // If we drop the card to an empty column
+ if (!prevData && !nextData) {
+ base = 0;
+ increment = 1;
+ // If we drop the card in the first position
+ } else if (!prevData) {
+ base = nextData.sort - 1;
+ increment = -1;
+ // If we drop the card in the last position
+ } else if (!nextData) {
+ base = prevData.sort + 1;
+ increment = 1;
+ }
+ // In the general case take the average of the previous and next element
+ // sort indexes.
+ else {
+ const prevSortIndex = prevData.sort;
+ const nextSortIndex = nextData.sort;
+ increment = (nextSortIndex - prevSortIndex) / (nItems + 1);
+ base = prevSortIndex + increment;
+ }
+ // XXX Return a generator that yield values instead of a base with a
+ // increment number.
+ return {
+ base,
+ increment,
+ };
+ },
+
// Determine the new sort index
calculateIndex(prevCardDomElement, nextCardDomElement, nCards = 1) {
let base, increment;
diff --git a/i18n/ar.i18n.json b/i18n/ar.i18n.json
index 738743fe..a9c0af06 100644
--- a/i18n/ar.i18n.json
+++ b/i18n/ar.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "السماح بتغيير البريد الإلكتروني",
"createdAt": "Created at",
"verified": "Verified",
- "active": "Active"
+ "active": "Active",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/bg.i18n.json b/i18n/bg.i18n.json
index 568bd458..8899510d 100644
--- a/i18n/bg.i18n.json
+++ b/i18n/bg.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "Разреши промяна на имейла",
"createdAt": "Създаден на",
"verified": "Потвърден",
- "active": "Активен"
+ "active": "Активен",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/br.i18n.json b/i18n/br.i18n.json
index 824f2a5b..bf4a8ac5 100644
--- a/i18n/br.i18n.json
+++ b/i18n/br.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "Allow Email Change",
"createdAt": "Created at",
"verified": "Verified",
- "active": "Active"
+ "active": "Active",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/ca.i18n.json b/i18n/ca.i18n.json
index bf3f7a03..44edf12d 100644
--- a/i18n/ca.i18n.json
+++ b/i18n/ca.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "Permet modificar correu electrònic",
"createdAt": "Creat ",
"verified": "Verificat",
- "active": "Actiu"
+ "active": "Actiu",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/cs.i18n.json b/i18n/cs.i18n.json
index 26df3797..eac9ff4e 100644
--- a/i18n/cs.i18n.json
+++ b/i18n/cs.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "Povolit změnu Emailu",
"createdAt": "Created at",
"verified": "Verified",
- "active": "Active"
+ "active": "Active",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/de.i18n.json b/i18n/de.i18n.json
index d275e4be..3ced5f15 100644
--- a/i18n/de.i18n.json
+++ b/i18n/de.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "Ändern der E-Mailadresse zulassen",
"createdAt": "Erstellt am",
"verified": "Geprüft",
- "active": "Aktiv"
+ "active": "Aktiv",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/el.i18n.json b/i18n/el.i18n.json
index 85e0df22..91419ae3 100644
--- a/i18n/el.i18n.json
+++ b/i18n/el.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "Allow Email Change",
"createdAt": "Created at",
"verified": "Verified",
- "active": "Active"
+ "active": "Active",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/en-GB.i18n.json b/i18n/en-GB.i18n.json
index 5e64ae5e..ee5a57bf 100644
--- a/i18n/en-GB.i18n.json
+++ b/i18n/en-GB.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "Allow Email Change",
"createdAt": "Created at",
"verified": "Verified",
- "active": "Active"
+ "active": "Active",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/en.i18n.json b/i18n/en.i18n.json
index de07b943..02bd4c28 100644
--- a/i18n/en.i18n.json
+++ b/i18n/en.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "Allow Email Change",
"createdAt": "Created at",
"verified": "Verified",
- "active": "Active"
+ "active": "Active",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
}
diff --git a/i18n/eo.i18n.json b/i18n/eo.i18n.json
index f180ec4c..4f7fcbd1 100644
--- a/i18n/eo.i18n.json
+++ b/i18n/eo.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "Allow Email Change",
"createdAt": "Created at",
"verified": "Verified",
- "active": "Active"
+ "active": "Active",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/es-AR.i18n.json b/i18n/es-AR.i18n.json
index d131c253..04f91ae8 100644
--- a/i18n/es-AR.i18n.json
+++ b/i18n/es-AR.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "Permitir Cambio de Email",
"createdAt": "Creado en",
"verified": "Verificado",
- "active": "Activo"
+ "active": "Activo",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/es.i18n.json b/i18n/es.i18n.json
index 30762488..116dfb7a 100644
--- a/i18n/es.i18n.json
+++ b/i18n/es.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "Permitir cambiar el correo electrónico",
"createdAt": "Creado en",
"verified": "Verificado",
- "active": "Activo"
+ "active": "Activo",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/eu.i18n.json b/i18n/eu.i18n.json
index c147c51c..f997533a 100644
--- a/i18n/eu.i18n.json
+++ b/i18n/eu.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "Baimendu e-mail aldaketa",
"createdAt": "Noiz sortua",
"verified": "Egiaztatuta",
- "active": "Gaituta"
+ "active": "Gaituta",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/fa.i18n.json b/i18n/fa.i18n.json
index 74d8f1f6..169559b0 100644
--- a/i18n/fa.i18n.json
+++ b/i18n/fa.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "اجازه تغییر رایانامه",
"createdAt": "ساخته شده در",
"verified": "معتبر",
- "active": "فعال"
+ "active": "فعال",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/fi.i18n.json b/i18n/fi.i18n.json
index fafe2dd5..fad0327a 100644
--- a/i18n/fi.i18n.json
+++ b/i18n/fi.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "Salli sähköpostiosoitteen muuttaminen",
"createdAt": "Luotu",
"verified": "Varmistettu",
- "active": "Aktiivinen"
+ "active": "Aktiivinen",
+ "card-received": "Vastaanotettu",
+ "card-received-on": "Vastaanotettu",
+ "card-end": "Loppuu",
+ "card-end-on": "Loppuu",
+ "editCardReceivedDatePopup-title": "Vaihda vastaanottamispäivää",
+ "editCardEndDatePopup-title": "Vaihda loppumispäivää"
} \ No newline at end of file
diff --git a/i18n/fr.i18n.json b/i18n/fr.i18n.json
index 1fbe1867..091e589a 100644
--- a/i18n/fr.i18n.json
+++ b/i18n/fr.i18n.json
@@ -40,7 +40,7 @@
"activity-sent": "a envoyé %s vers %s",
"activity-unjoined": "a quitté %s",
"activity-checklist-added": "a ajouté une checklist à %s",
- "activity-checklist-item-added": "a ajouté une checklist à '%s' dans %s",
+ "activity-checklist-item-added": "a ajouté un élément à la checklist '%s' dans %s",
"add": "Ajouter",
"add-attachment": "Ajouter une pièce jointe",
"add-board": "Ajouter un tableau",
@@ -156,7 +156,7 @@
"comment-only": "Commentaire uniquement",
"comment-only-desc": "Ne peut que commenter des cartes.",
"computer": "Ordinateur",
- "confirm-checklist-delete-dialog": "Êtes-vous sûr de vouloir supprimer cette checklist ?",
+ "confirm-checklist-delete-dialog": "Êtes-vous sûr de vouloir supprimer la checklist",
"copy-card-link-to-clipboard": "Copier le lien vers la carte dans le presse-papier",
"copyCardPopup-title": "Copier la carte",
"copyChecklistToManyCardsPopup-title": "Copier le modèle de checklist vers plusieurs cartes",
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "Autoriser le changement d'adresse mail",
"createdAt": "Créé à",
"verified": "Vérifié",
- "active": "Actif"
+ "active": "Actif",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/gl.i18n.json b/i18n/gl.i18n.json
index ac5d9c0a..cc6bee40 100644
--- a/i18n/gl.i18n.json
+++ b/i18n/gl.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "Allow Email Change",
"createdAt": "Created at",
"verified": "Verified",
- "active": "Active"
+ "active": "Active",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/he.i18n.json b/i18n/he.i18n.json
index adbd5f43..9261ba0c 100644
--- a/i18n/he.i18n.json
+++ b/i18n/he.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "אפשר שינוי דוא\"ל",
"createdAt": "נוצר ב",
"verified": "עבר אימות",
- "active": "פעיל"
+ "active": "פעיל",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/hu.i18n.json b/i18n/hu.i18n.json
index 4428fe58..c4bd24b8 100644
--- a/i18n/hu.i18n.json
+++ b/i18n/hu.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "E-mail megváltoztatásának engedélyezése",
"createdAt": "Létrehozva",
"verified": "Ellenőrizve",
- "active": "Aktív"
+ "active": "Aktív",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/hy.i18n.json b/i18n/hy.i18n.json
index 2b23b1b4..f24a1e9a 100644
--- a/i18n/hy.i18n.json
+++ b/i18n/hy.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "Allow Email Change",
"createdAt": "Created at",
"verified": "Verified",
- "active": "Active"
+ "active": "Active",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/id.i18n.json b/i18n/id.i18n.json
index 1f5aa45b..c32dcedf 100644
--- a/i18n/id.i18n.json
+++ b/i18n/id.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "Allow Email Change",
"createdAt": "Created at",
"verified": "Verified",
- "active": "Active"
+ "active": "Active",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/ig.i18n.json b/i18n/ig.i18n.json
index 326528f0..80942393 100644
--- a/i18n/ig.i18n.json
+++ b/i18n/ig.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "Allow Email Change",
"createdAt": "Ekere na",
"verified": "Verified",
- "active": "Active"
+ "active": "Active",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/it.i18n.json b/i18n/it.i18n.json
index 58579442..61becc94 100644
--- a/i18n/it.i18n.json
+++ b/i18n/it.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "Permetti modifica dell'email",
"createdAt": "creato alle",
"verified": "Verificato",
- "active": "Attivo"
+ "active": "Attivo",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/ja.i18n.json b/i18n/ja.i18n.json
index d0c606f0..e3c47226 100644
--- a/i18n/ja.i18n.json
+++ b/i18n/ja.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "メールアドレスの変更を許可",
"createdAt": "Created at",
"verified": "Verified",
- "active": "Active"
+ "active": "Active",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/lv.i18n.json b/i18n/lv.i18n.json
index 896ae201..b54c7533 100644
--- a/i18n/lv.i18n.json
+++ b/i18n/lv.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "Allow Email Change",
"createdAt": "Created at",
"verified": "Verified",
- "active": "Active"
+ "active": "Active",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/mn.i18n.json b/i18n/mn.i18n.json
index 43418301..b06306db 100644
--- a/i18n/mn.i18n.json
+++ b/i18n/mn.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "Allow Email Change",
"createdAt": "Created at",
"verified": "Verified",
- "active": "Active"
+ "active": "Active",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/nb.i18n.json b/i18n/nb.i18n.json
index d3fd2676..3905d577 100644
--- a/i18n/nb.i18n.json
+++ b/i18n/nb.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "Allow Email Change",
"createdAt": "Created at",
"verified": "Verified",
- "active": "Active"
+ "active": "Active",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/nl.i18n.json b/i18n/nl.i18n.json
index 7177e032..3bc86342 100644
--- a/i18n/nl.i18n.json
+++ b/i18n/nl.i18n.json
@@ -5,22 +5,22 @@
"act-addChecklist": "__checklist__ toegevoegd aan __card__",
"act-addChecklistItem": "__checklistItem__ aan checklist toegevoegd aan __checklist__ op __card__",
"act-addComment": "gereageerd op __card__:__comment__",
- "act-createBoard": "aangemaakte__bord__",
- "act-createCard": "toegevoegd__kaart__aan__lijst__",
- "act-createList": "toegevoegd__lijst__aan_bord__",
- "act-addBoardMember": "__member__to__board__ toegevoegd",
- "act-archivedBoard": "gearchiveerd __board__",
- "act-archivedCard": "gearchiveerd __card__",
- "act-archivedList": "gearchiveerd __list__",
- "act-archivedSwimlane": "archived __swimlane__",
+ "act-createBoard": "aangemaakte __bord__",
+ "act-createCard": "toegevoegd __kaart__ aan __lijst__",
+ "act-createList": "toegevoegd __lijst__ aan __bord__",
+ "act-addBoardMember": "__member__ aan __board__ toegevoegd",
+ "act-archivedBoard": "__board__ gearchiveerd",
+ "act-archivedCard": "__card__ gearchiveerd",
+ "act-archivedList": "__list__ gearchiveerd",
+ "act-archivedSwimlane": "__swimlane__ gearchiveerd",
"act-importBoard": " __board__ geïmporteerd",
- "act-importCard": "__card__ geimporteerd",
- "act-importList": "__list__ geimporteerd",
- "act-joinMember": "toegevoegd __member__to__card__",
- "act-moveCard": "verplaatst __card__from__oldList__to__list__",
- "act-removeBoardMember": "verwijderd __member__from__board__",
- "act-restoredCard": "hersteld __card__to__board__",
- "act-unjoinMember": "verwijderd __member__from__card__",
+ "act-importCard": "__card__ geïmporteerd",
+ "act-importList": "__list__ geïmporteerd",
+ "act-joinMember": "__member__ aan __card__ toegevoegd",
+ "act-moveCard": "verplaatst __card__ van __oldList__ naar __list__",
+ "act-removeBoardMember": "verwijderd __member__ van __board__",
+ "act-restoredCard": "hersteld __card__ naar __board__",
+ "act-unjoinMember": "verwijderd __member__ van __card__",
"act-withBoardTitle": "[Wekan] __board__",
"act-withCardTitle": "[__board__] __card__",
"actions": "Acties",
@@ -45,7 +45,7 @@
"add-attachment": "Voeg Bijlage Toe",
"add-board": "Voeg Bord Toe",
"add-card": "Voeg Kaart Toe",
- "add-swimlane": "Add Swimlane",
+ "add-swimlane": "Swimlane Toevoegen",
"add-checklist": "Voeg Checklist Toe",
"add-checklist-item": "Voeg item toe aan checklist",
"add-cover": "Voeg Cover Toe",
@@ -69,7 +69,7 @@
"archive-board": "Archiveer Bord",
"archive-card": "Archiveer Kaart",
"archive-list": "Archiveer Lijst",
- "archive-swimlane": "Archive Swimlane",
+ "archive-swimlane": "Swimlane Archiveren",
"archive-selection": "Archiveer Selectie",
"archiveBoardPopup-title": "Archiveer Bord?",
"archived-items": "Gearchiveerde Items",
@@ -97,7 +97,7 @@
"boardChangeWatchPopup-title": "Verander naar 'Watch'",
"boardMenuPopup-title": "Bord menu",
"boards": "Borden",
- "board-view": "Board View",
+ "board-view": "Bord overzicht",
"board-view-swimlanes": "Swimlanes",
"board-view-lists": "Lijsten",
"bucket-example": "Zoals \"Bucket List\" bijvoorbeeld",
@@ -159,9 +159,9 @@
"confirm-checklist-delete-dialog": "Weet u zeker dat u de checklist wilt verwijderen",
"copy-card-link-to-clipboard": "Kopieer kaart link naar klembord",
"copyCardPopup-title": "Kopieer kaart",
- "copyChecklistToManyCardsPopup-title": "Copy Checklist Template to Many Cards",
- "copyChecklistToManyCardsPopup-instructions": "Destination Card Titles and Descriptions in this JSON format",
- "copyChecklistToManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]",
+ "copyChecklistToManyCardsPopup-title": "Checklist sjabloon kopiëren naar meerdere kaarten",
+ "copyChecklistToManyCardsPopup-instructions": "Doel kaart titels en omschrijvingen in dit JSON formaat",
+ "copyChecklistToManyCardsPopup-format": "[ {\"title\": \"Titel eerste kaart\", \"description\":\"Omschrijving eerste kaart\"}, {\"title\":\"Titel tweede kaart\",\"description\":\"Omschrijving tweede kaart\"},{\"title\":\"Titel laatste kaart\",\"description\":\"Omschrijving laatste kaart\"} ]",
"create": "Aanmaken",
"createBoardPopup-title": "Bord aanmaken",
"chooseBoardSourcePopup-title": "Importeer bord",
@@ -268,7 +268,7 @@
"list-move-cards": "Verplaats alle kaarten in deze lijst",
"list-select-cards": "Selecteer alle kaarten in deze lijst",
"listActionPopup-title": "Lijst acties",
- "swimlaneActionPopup-title": "Swimlane Actions",
+ "swimlaneActionPopup-title": "Swimlane handelingen",
"listImportCardPopup-title": "Importeer een Trello kaart",
"listMorePopup-title": "Meer",
"link-list": "Link naar deze lijst",
@@ -280,7 +280,7 @@
"log-in": "Inloggen",
"loginPopup-title": "Inloggen",
"memberMenuPopup-title": "Instellingen van leden",
- "members": "Lede",
+ "members": "Leden",
"menu": "Menu",
"move-selection": "Verplaats selectie",
"moveCardPopup-title": "Verplaats kaart",
@@ -295,7 +295,7 @@
"name": "Naam",
"no-archived-cards": "Geen gearchiveerde kaarten.",
"no-archived-lists": "Geen gearchiveerde lijsten.",
- "no-archived-swimlanes": "No archived swimlanes.",
+ "no-archived-swimlanes": "Geen gearchiveerde swimlanes.",
"no-results": "Geen resultaten",
"normal": "Normaal",
"normal-desc": "Kan de kaarten zien en wijzigen. Kan de instellingen niet wijzigen.",
@@ -331,8 +331,8 @@
"restore": "Herstel",
"save": "Opslaan",
"search": "Zoek",
- "search-cards": "Search from card titles and descriptions on this board",
- "search-example": "Text to search for?",
+ "search-cards": "Zoeken in kaart titels en omschrijvingen op dit bord",
+ "search-example": "Tekst om naar te zoeken?",
"select-color": "Selecteer kleur",
"set-wip-limit-value": "Zet een limiet voor het maximaal aantal taken in deze lijst",
"setWipLimitPopup-title": "Zet een WIP limiet",
@@ -360,7 +360,7 @@
"overtime-hours": "Overwerk (in uren)",
"overtime": "Overwerk",
"has-overtime-cards": "Heeft kaarten met overwerk",
- "has-spenttime-cards": "Has spent time cards",
+ "has-spenttime-cards": "Heeft tijd besteed aan kaarten",
"time": "Tijd",
"title": "Titel",
"tracking": "Volgen",
@@ -378,7 +378,7 @@
"watching": "Bekijken",
"watching-info": "Je zal op de hoogte worden gesteld als er een verandering gebeurt op dit bord.",
"welcome-board": "Welkom Bord",
- "welcome-swimlane": "Milestone 1",
+ "welcome-swimlane": "Mijlpaal 1",
"welcome-list1": "Basis",
"welcome-list2": "Geadvanceerd",
"what-to-do": "Wat wil je doen?",
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "Sta E-mailadres wijzigingen toe",
"createdAt": "Gemaakt op",
"verified": "Geverifieerd",
- "active": "Actief"
+ "active": "Actief",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/pl.i18n.json b/i18n/pl.i18n.json
index 26404fdd..5d1a3391 100644
--- a/i18n/pl.i18n.json
+++ b/i18n/pl.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "Zezwól na zmianę adresu email",
"createdAt": "Stworzono o",
"verified": "Zweryfikowane",
- "active": "Aktywny"
+ "active": "Aktywny",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/pt-BR.i18n.json b/i18n/pt-BR.i18n.json
index 03e22f68..32820a9d 100644
--- a/i18n/pt-BR.i18n.json
+++ b/i18n/pt-BR.i18n.json
@@ -97,7 +97,7 @@
"boardChangeWatchPopup-title": "Alterar observação",
"boardMenuPopup-title": "Menu do Quadro",
"boards": "Quadros",
- "board-view": "Board View",
+ "board-view": "Visão de quadro",
"board-view-swimlanes": "Swimlanes",
"board-view-lists": "Listas",
"bucket-example": "\"Bucket List\", por exemplo",
@@ -159,9 +159,9 @@
"confirm-checklist-delete-dialog": "Tem a certeza de que pretende eliminar lista de verificação",
"copy-card-link-to-clipboard": "Copiar link do cartão para a área de transferência",
"copyCardPopup-title": "Copiar o cartão",
- "copyChecklistToManyCardsPopup-title": "Copy Checklist Template to Many Cards",
- "copyChecklistToManyCardsPopup-instructions": "Destination Card Titles and Descriptions in this JSON format",
- "copyChecklistToManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]",
+ "copyChecklistToManyCardsPopup-title": "Copiar modelo de checklist para vários cartões",
+ "copyChecklistToManyCardsPopup-instructions": "Títulos e descrições do cartão de destino neste formato JSON",
+ "copyChecklistToManyCardsPopup-format": "[ {\"title\": \"Título do primeiro cartão\", \"description\":\"Descrição do primeiro cartão\"}, {\"title\":\"Título do segundo cartão\",\"description\":\"Descrição do segundo cartão\"},{\"title\":\"Título do último cartão\",\"description\":\"Descrição do último cartão\"} ]",
"create": "Criar",
"createBoardPopup-title": "Criar Quadro",
"chooseBoardSourcePopup-title": "Importar quadro",
@@ -182,7 +182,7 @@
"edit-avatar": "Alterar Avatar",
"edit-profile": "Editar Perfil",
"edit-wip-limit": "Editar Limite WIP",
- "soft-wip-limit": "Soft WIP Limit",
+ "soft-wip-limit": "Limite de WIP",
"editCardStartDatePopup-title": "Altera data de início",
"editCardDueDatePopup-title": "Altera data fim",
"editCardSpentTimePopup-title": "Editar tempo gasto",
@@ -331,8 +331,8 @@
"restore": "Restaurar",
"save": "Salvar",
"search": "Buscar",
- "search-cards": "Search from card titles and descriptions on this board",
- "search-example": "Text to search for?",
+ "search-cards": "Pesquisa em títulos e descrições de cartões neste quadro",
+ "search-example": "Texto para procurar",
"select-color": "Selecionar Cor",
"set-wip-limit-value": "Defina um limite máximo para o número de tarefas nesta lista",
"setWipLimitPopup-title": "Definir Limite WIP",
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "Permitir Mudança de Email",
"createdAt": "Criado em",
"verified": "Verificado",
- "active": "Ativo"
+ "active": "Ativo",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/pt.i18n.json b/i18n/pt.i18n.json
index b81455bb..038a2c85 100644
--- a/i18n/pt.i18n.json
+++ b/i18n/pt.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "Allow Email Change",
"createdAt": "Created at",
"verified": "Verificado",
- "active": "Ativo"
+ "active": "Ativo",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/ro.i18n.json b/i18n/ro.i18n.json
index 75fc9e95..b2290528 100644
--- a/i18n/ro.i18n.json
+++ b/i18n/ro.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "Allow Email Change",
"createdAt": "Created at",
"verified": "Verified",
- "active": "Active"
+ "active": "Active",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/ru.i18n.json b/i18n/ru.i18n.json
index 68be9d9a..388c2156 100644
--- a/i18n/ru.i18n.json
+++ b/i18n/ru.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "Разрешить изменение электронной почты",
"createdAt": "Создано на",
"verified": "Проверено",
- "active": "Действующий"
+ "active": "Действующий",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/sr.i18n.json b/i18n/sr.i18n.json
index 67effbdc..334bc9a0 100644
--- a/i18n/sr.i18n.json
+++ b/i18n/sr.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "Allow Email Change",
"createdAt": "Created at",
"verified": "Verified",
- "active": "Active"
+ "active": "Active",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/sv.i18n.json b/i18n/sv.i18n.json
index cb864379..3244a084 100644
--- a/i18n/sv.i18n.json
+++ b/i18n/sv.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "Tillåt e-poständring",
"createdAt": "Skapad vid",
"verified": "Verifierad",
- "active": "Aktiv"
+ "active": "Aktiv",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/ta.i18n.json b/i18n/ta.i18n.json
index 4f60c04e..d1a7ccbf 100644
--- a/i18n/ta.i18n.json
+++ b/i18n/ta.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "Allow Email Change",
"createdAt": "Created at",
"verified": "Verified",
- "active": "Active"
+ "active": "Active",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/th.i18n.json b/i18n/th.i18n.json
index 8543372a..96542721 100644
--- a/i18n/th.i18n.json
+++ b/i18n/th.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "Allow Email Change",
"createdAt": "Created at",
"verified": "Verified",
- "active": "Active"
+ "active": "Active",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/tr.i18n.json b/i18n/tr.i18n.json
index 642a4bd9..81bb2008 100644
--- a/i18n/tr.i18n.json
+++ b/i18n/tr.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "E-posta Değiştirmeye İzin Ver",
"createdAt": "Oluşturulma tarihi",
"verified": "Doğrulanmış",
- "active": "Aktif"
+ "active": "Aktif",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/uk.i18n.json b/i18n/uk.i18n.json
index 38bef7df..47bfeea7 100644
--- a/i18n/uk.i18n.json
+++ b/i18n/uk.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "Allow Email Change",
"createdAt": "Created at",
"verified": "Verified",
- "active": "Active"
+ "active": "Active",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/vi.i18n.json b/i18n/vi.i18n.json
index 7a7ab781..2581d859 100644
--- a/i18n/vi.i18n.json
+++ b/i18n/vi.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "Allow Email Change",
"createdAt": "Created at",
"verified": "Verified",
- "active": "Active"
+ "active": "Active",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/zh-CN.i18n.json b/i18n/zh-CN.i18n.json
index 37bbeb92..6df88c9d 100644
--- a/i18n/zh-CN.i18n.json
+++ b/i18n/zh-CN.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "允许邮箱变更",
"createdAt": "创建于",
"verified": "已验证",
- "active": "活跃"
+ "active": "活跃",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/i18n/zh-TW.i18n.json b/i18n/zh-TW.i18n.json
index cff408ac..7a6068c2 100644
--- a/i18n/zh-TW.i18n.json
+++ b/i18n/zh-TW.i18n.json
@@ -435,5 +435,11 @@
"accounts-allowEmailChange": "准許變更電子信箱",
"createdAt": "Created at",
"verified": "Verified",
- "active": "Active"
+ "active": "Active",
+ "card-received": "Received",
+ "card-received-on": "Received on",
+ "card-end": "End",
+ "card-end-on": "Ends on",
+ "editCardReceivedDatePopup-title": "Change received date",
+ "editCardEndDatePopup-title": "Change end date"
} \ No newline at end of file
diff --git a/models/activities.js b/models/activities.js
index bd33303a..3f1d28ae 100644
--- a/models/activities.js
+++ b/models/activities.js
@@ -42,7 +42,7 @@ Activities.helpers({
return Checklists.findOne(this.checklistId);
},
checklistItem() {
- return Checklists.findOne(this.checklistId).getItem(this.checklistItemId);
+ return ChecklistItems.findOne(this.checklistItemId);
},
});
diff --git a/models/cards.js b/models/cards.js
index 544afca5..4a662953 100644
--- a/models/cards.js
+++ b/models/cards.js
@@ -59,6 +59,10 @@ Cards.attachSchema(new SimpleSchema({
type: [String],
optional: true,
},
+ receivedAt: {
+ type: Date,
+ optional: true,
+ },
startAt: {
type: Date,
optional: true,
@@ -67,6 +71,10 @@ Cards.attachSchema(new SimpleSchema({
type: Date,
optional: true,
},
+ endAt: {
+ type: Date,
+ optional: true,
+ },
spentTime: {
type: Number,
decimal: true,
@@ -155,7 +163,7 @@ Cards.helpers({
},
checklists() {
- return Checklists.find({cardId: this._id}, {sort: {createdAt: 1}});
+ return Checklists.find({cardId: this._id}, {sort: { sort: 1 } });
},
checklistItemCount() {
@@ -271,6 +279,14 @@ Cards.mutations({
return {$unset: {coverId: ''}};
},
+ setReceived(receivedAt) {
+ return {$set: {receivedAt}};
+ },
+
+ unsetReceived() {
+ return {$unset: {receivedAt: ''}};
+ },
+
setStart(startAt) {
return {$set: {startAt}};
},
@@ -287,6 +303,14 @@ Cards.mutations({
return {$unset: {dueAt: ''}};
},
+ setEnd(endAt) {
+ return {$set: {endAt}};
+ },
+
+ unsetEnd() {
+ return {$unset: {endAt: ''}};
+ },
+
setOvertime(isOvertime) {
return {$set: {isOvertime}};
},
diff --git a/models/checklistItems.js b/models/checklistItems.js
new file mode 100644
index 00000000..3c01d476
--- /dev/null
+++ b/models/checklistItems.js
@@ -0,0 +1,95 @@
+ChecklistItems = new Mongo.Collection('checklistItems');
+
+ChecklistItems.attachSchema(new SimpleSchema({
+ title: {
+ type: String,
+ },
+ sort: {
+ type: Number,
+ decimal: true,
+ },
+ isFinished: {
+ type: Boolean,
+ defaultValue: false,
+ },
+ checklistId: {
+ type: String,
+ },
+ cardId: {
+ type: String,
+ },
+}));
+
+ChecklistItems.allow({
+ insert(userId, doc) {
+ return allowIsBoardMemberByCard(userId, Cards.findOne(doc.cardId));
+ },
+ update(userId, doc) {
+ return allowIsBoardMemberByCard(userId, Cards.findOne(doc.cardId));
+ },
+ remove(userId, doc) {
+ return allowIsBoardMemberByCard(userId, Cards.findOne(doc.cardId));
+ },
+ fetch: ['userId', 'cardId'],
+});
+
+ChecklistItems.before.insert((userId, doc) => {
+ if (!doc.userId) {
+ doc.userId = userId;
+ }
+});
+
+// Mutations
+ChecklistItems.mutations({
+ setTitle(title) {
+ return { $set: { title } };
+ },
+ toggleItem() {
+ return { $set: { isFinished: !this.isFinished } };
+ },
+ move(checklistId, sortIndex) {
+ const cardId = Checklists.findOne(checklistId).cardId;
+ const mutatedFields = {
+ cardId,
+ checklistId,
+ sort: sortIndex,
+ };
+
+ return {$set: mutatedFields};
+ },
+});
+
+// Activities helper
+function itemCreation(userId, doc) {
+ const card = Cards.findOne(doc.cardId);
+ const boardId = card.boardId;
+ Activities.insert({
+ userId,
+ activityType: 'addChecklistItem',
+ cardId: doc.cardId,
+ boardId,
+ checklistId: doc.checklistId,
+ checklistItemId: doc._id,
+ });
+}
+
+function itemRemover(userId, doc) {
+ Activities.remove({
+ checklistItemId: doc._id,
+ });
+}
+
+// Activities
+if (Meteor.isServer) {
+ Meteor.startup(() => {
+ ChecklistItems._collection._ensureIndex({ checklistId: 1 });
+ });
+
+ ChecklistItems.after.insert((userId, doc) => {
+ itemCreation(userId, doc);
+ });
+
+ ChecklistItems.after.remove((userId, doc) => {
+ itemRemover(userId, doc);
+ });
+}
diff --git a/models/checklists.js b/models/checklists.js
index 7eb0a24f..9946f98e 100644
--- a/models/checklists.js
+++ b/models/checklists.js
@@ -6,24 +6,7 @@ Checklists.attachSchema(new SimpleSchema({
},
title: {
type: String,
- },
- items: {
- type: [Object],
- defaultValue: [],
- },
- 'items.$._id': {
- type: String,
- },
- 'items.$.title': {
- type: String,
- },
- 'items.$.sort': {
- type: Number,
- decimal: true,
- },
- 'items.$.isFinished': {
- type: Boolean,
- defaultValue: false,
+ defaultValue: 'Checklist',
},
finishedAt: {
type: Date,
@@ -46,40 +29,28 @@ Checklists.attachSchema(new SimpleSchema({
},
}));
-const self = Checklists;
-
Checklists.helpers({
itemCount() {
- return this.items.length;
+ return ChecklistItems.find({ checklistId: this._id }).count();
},
- getItemsSorted() {
- return _.sortBy(this.items, 'sort');
+ items() {
+ return ChecklistItems.find(Filter.mongoSelector({
+ checklistId: this._id,
+ }), { sort: ['sort'] });
},
finishedCount() {
- return this.items.filter((item) => {
- return item.isFinished;
- }).length;
+ return ChecklistItems.find({
+ checklistId: this._id,
+ isFinished: true,
+ }).count();
},
isFinished() {
return 0 !== this.itemCount() && this.itemCount() === this.finishedCount();
},
- getItem(_id) {
- return _.findWhere(this.items, { _id });
- },
itemIndex(itemId) {
const items = self.findOne({_id : this._id}).items;
return _.pluck(items, '_id').indexOf(itemId);
},
- getNewItemId() {
- const itemCount = this.itemCount();
- let idx = 0;
- if (itemCount > 0) {
- const lastId = this.items[itemCount - 1]._id;
- const lastIdSuffix = lastId.substr(this._id.length);
- idx = parseInt(lastIdSuffix, 10) + 1;
- }
- return `${this._id}${idx}`;
- },
});
Checklists.allow({
@@ -103,108 +74,9 @@ Checklists.before.insert((userId, doc) => {
});
Checklists.mutations({
- //for checklist itself
setTitle(title) {
return { $set: { title } };
},
- //for items in checklist
- addItem(title) {
- const _id = this.getNewItemId();
- return {
- $addToSet: {
- items: {
- _id, title,
- isFinished: false,
- sort: this.itemCount(),
- },
- },
- };
- },
- addFullItem(item) {
- const itemsUpdate = {};
- this.items.forEach(function(iterItem, index) {
- if (iterItem.sort >= item.sort) {
- itemsUpdate[`items.${index}.sort`] = iterItem.sort + 1;
- }
- });
- if (!_.isEmpty(itemsUpdate)) {
- self.direct.update({ _id: this._id }, { $set: itemsUpdate });
- }
- return { $addToSet: { items: item } };
- },
- removeItem(itemId) {
- const item = this.getItem(itemId);
- const itemsUpdate = {};
- this.items.forEach(function(iterItem, index) {
- if (iterItem.sort > item.sort) {
- itemsUpdate[`items.${index}.sort`] = iterItem.sort - 1;
- }
- });
- if (!_.isEmpty(itemsUpdate)) {
- self.direct.update({ _id: this._id }, { $set: itemsUpdate });
- }
- return { $pull: { items: { _id: itemId } } };
- },
- editItem(itemId, title) {
- if (this.getItem(itemId)) {
- const itemIndex = this.itemIndex(itemId);
- return {
- $set: {
- [`items.${itemIndex}.title`]: title,
- },
- };
- }
- return {};
- },
- finishItem(itemId) {
- if (this.getItem(itemId)) {
- const itemIndex = this.itemIndex(itemId);
- return {
- $set: {
- [`items.${itemIndex}.isFinished`]: true,
- },
- };
- }
- return {};
- },
- resumeItem(itemId) {
- if (this.getItem(itemId)) {
- const itemIndex = this.itemIndex(itemId);
- return {
- $set: {
- [`items.${itemIndex}.isFinished`]: false,
- },
- };
- }
- return {};
- },
- toggleItem(itemId) {
- const item = this.getItem(itemId);
- if (item) {
- const itemIndex = this.itemIndex(itemId);
- return {
- $set: {
- [`items.${itemIndex}.isFinished`]: !item.isFinished,
- },
- };
- }
- return {};
- },
- sortItems(itemIDs) {
- const validItems = [];
- itemIDs.forEach((itemID) => {
- if (this.getItem(itemID)) {
- validItems.push(this.itemIndex(itemID));
- }
- });
- const modifiedValues = {};
- for (let i = 0; i < validItems.length; i++) {
- modifiedValues[`items.${validItems[i]}.sort`] = i;
- }
- return {
- $set: modifiedValues,
- };
- },
});
if (Meteor.isServer) {
@@ -222,30 +94,6 @@ if (Meteor.isServer) {
});
});
- //TODO: so there will be no activity for adding item into checklist, maybe will be implemented in the future.
- // The future is now
- Checklists.after.update((userId, doc, fieldNames, modifier) => {
- if (fieldNames.includes('items')) {
- if (modifier.$addToSet) {
- Activities.insert({
- userId,
- activityType: 'addChecklistItem',
- cardId: doc.cardId,
- boardId: Cards.findOne(doc.cardId).boardId,
- checklistId: doc._id,
- checklistItemId: modifier.$addToSet.items._id,
- });
- } else if (modifier.$pull) {
- const activity = Activities.findOne({
- checklistItemId: modifier.$pull.items._id,
- });
- if (activity) {
- Activities.remove(activity._id);
- }
- }
- }
- });
-
Checklists.before.remove((userId, doc) => {
const activities = Activities.find({ checklistId: doc._id });
if (activities) {
@@ -256,7 +104,6 @@ if (Meteor.isServer) {
});
}
-//CARD COMMENT REST API
if (Meteor.isServer) {
JsonRoutes.add('GET', '/api/boards/:boardId/cards/:cardId/checklists', function (req, res) {
try {
diff --git a/server/migrations.js b/server/migrations.js
index f2cb124b..a1bdd487 100644
--- a/server/migrations.js
+++ b/server/migrations.js
@@ -187,3 +187,24 @@ Migrations.add('add-views', () => {
}
});
});
+
+Migrations.add('add-checklist-items', () => {
+ Checklists.find().forEach((checklist) => {
+ // Create new items
+ _.sortBy(checklist.items, 'sort').forEach((item, index) => {
+ ChecklistItems.direct.insert({
+ title: item.title,
+ sort: index,
+ isFinished: item.isFinished,
+ checklistId: checklist._id,
+ cardId: checklist.cardId,
+ });
+ });
+
+ // Delete old ones
+ Checklists.direct.update({ _id: checklist._id },
+ { $unset: { items : 1 } },
+ noValidate
+ );
+ });
+});
diff --git a/server/publications/boards.js b/server/publications/boards.js
index 889bd177..17d87f3a 100644
--- a/server/publications/boards.js
+++ b/server/publications/boards.js
@@ -101,6 +101,7 @@ Meteor.publishRelations('board', function(boardId) {
this.cursor(CardComments.find({ cardId }));
this.cursor(Attachments.find({ cardId }));
this.cursor(Checklists.find({ cardId }));
+ this.cursor(ChecklistItems.find({ cardId }));
});
if (board.members) {
diff --git a/snap-src/bin/config b/snap-src/bin/config
index da2ee5cd..813c3d3f 100755
--- a/snap-src/bin/config
+++ b/snap-src/bin/config
@@ -40,7 +40,7 @@ DESCRIPTION_DISABLE_MONGODB="Disable mongodb service: use only if binding to dat
DEFAULT_DISABLE_MONGODB="false"
KEY_DISABLE_MONGODB="disable-mongodb"
-DESCRIPTION_CADDY_ENABLED="Enable caddy service (caddy - Every Site on HTTPS). Set to 'true' to enable caddy\n\t\tcaddy settings are handled through $SNAP_COMMON/Caddyfile"
+DESCRIPTION_CADDY_ENABLED="Enable caddy service (caddy - Every Site on HTTPS) personal license for non-commercial use only, see https://caddyserver.com/products/licenses . Set to 'true' to enable caddy\n\t\tcaddy settings are handled through $SNAP_COMMON/Caddyfile"
DEFAULT_CADDY_ENABLED="false"
KEY_CADDY_ENABLED="caddy-enabled"
diff --git a/snapcraft.yaml b/snapcraft.yaml
index e28987db..657e7bc8 100644
--- a/snapcraft.yaml
+++ b/snapcraft.yaml
@@ -140,7 +140,7 @@ parts:
caddy:
plugin: dump
- source: https://caddyserver.com/download/linux/amd64?plugins=
+ source: https://caddyserver.com/download/linux/amd64?license=personal&plugins=
source-type: tar
organize:
caddy: bin/caddy