summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--client/components/activities/activities.js4
-rw-r--r--client/components/boards/boardHeader.jade2
-rw-r--r--client/components/boards/boardHeader.js2
-rw-r--r--client/components/cards/cardDetails.jade15
-rw-r--r--client/components/cards/cardDetails.js15
-rw-r--r--client/components/sidebar/sidebar.js2
-rw-r--r--client/components/sidebar/sidebar.styl61
-rw-r--r--client/components/sidebar/sidebarCustomFields.jade44
-rw-r--r--client/components/sidebar/sidebarCustomFields.js36
-rw-r--r--i18n/en.i18n.json17
-rw-r--r--models/boards.js4
-rw-r--r--models/customFields.js21
-rw-r--r--server/publications/boards.js1
13 files changed, 157 insertions, 67 deletions
diff --git a/client/components/activities/activities.js b/client/components/activities/activities.js
index 81645a51..95699961 100644
--- a/client/components/activities/activities.js
+++ b/client/components/activities/activities.js
@@ -92,8 +92,8 @@ BlazeComponent.extendComponent({
},
customField() {
- const customField = this.currentData().customFieldId;
- return customField;
+ const customField = this.currentData().customField();
+ return customField.name;
},
events() {
diff --git a/client/components/boards/boardHeader.jade b/client/components/boards/boardHeader.jade
index 67acdc9e..9d16b10a 100644
--- a/client/components/boards/boardHeader.jade
+++ b/client/components/boards/boardHeader.jade
@@ -103,7 +103,7 @@ template(name="boardHeaderBar")
template(name="boardMenuPopup")
ul.pop-over-list
- li: a.js-custom-fields {{_ 'custom-fields'}}
+ li: a.js-configure-custom-fields {{_ 'configure-custom-fields'}}
li: a.js-open-archives {{_ 'archived-items'}}
if currentUser.isBoardAdmin
li: a.js-change-board-color {{_ 'board-change-color'}}
diff --git a/client/components/boards/boardHeader.js b/client/components/boards/boardHeader.js
index 8983c722..61cdb149 100644
--- a/client/components/boards/boardHeader.js
+++ b/client/components/boards/boardHeader.js
@@ -1,6 +1,6 @@
Template.boardMenuPopup.events({
'click .js-rename-board': Popup.open('boardChangeTitle'),
- 'click .js-custom-fields'() {
+ 'click .js-configure-custom-fields'() {
Sidebar.setView('customFields');
Popup.close();
},
diff --git a/client/components/cards/cardDetails.jade b/client/components/cards/cardDetails.jade
index 09e0532c..ccb3ae97 100644
--- a/client/components/cards/cardDetails.jade
+++ b/client/components/cards/cardDetails.jade
@@ -107,6 +107,7 @@ 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-custom-fields {{_ 'card-edit-custom-fields'}}
li: a.js-start-date {{_ 'editCardStartDatePopup-title'}}
li: a.js-due-date {{_ 'editCardDueDatePopup-title'}}
hr
@@ -143,6 +144,20 @@ template(name="cardMembersPopup")
if isCardMember
i.fa.fa-check
+template(name="cardCustomFieldsPopup")
+ ul.pop-over-list
+ each board.customFields
+ li.item(class="")
+ a.name.js-select-field(href="#")
+ span.full-name
+ = name
+ if isCardMember
+ i.fa.fa-check
+ hr
+ a.quiet-button.full.js-configure-custom-fields
+ i.fa.fa-cog
+ span {{_ 'configure-custom-fields'}}
+
template(name="cardMorePopup")
p.quiet
span.clearfix
diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js
index 7c6c3ce7..f972424f 100644
--- a/client/components/cards/cardDetails.js
+++ b/client/components/cards/cardDetails.js
@@ -154,6 +154,7 @@ Template.cardDetailsActionsPopup.events({
'click .js-members': Popup.open('cardMembers'),
'click .js-labels': Popup.open('cardLabels'),
'click .js-attachments': Popup.open('cardAttachments'),
+ 'click .js-custom-fields': Popup.open('cardCustomFields'),
'click .js-start-date': Popup.open('editCardStartDate'),
'click .js-due-date': Popup.open('editCardDueDate'),
'click .js-move-card': Popup.open('moveCard'),
@@ -196,6 +197,20 @@ Template.editCardTitleForm.events({
},
});
+Template.cardCustomFieldsPopup.events({
+ 'click .js-select-field'(evt) {
+ const card = Cards.findOne(Session.get('currentCard'));
+ const customFieldId = this.customFieldId;
+ card.toggleCustomField(customFieldId);
+ evt.preventDefault();
+ },
+ 'click .js-configure-custom-fields'(evt) {
+ EscapeActions.executeUpTo('detailsPane');
+ Sidebar.setView('customFields');
+ evt.preventDefault();
+ }
+});
+
Template.moveCardPopup.events({
'click .js-select-list' () {
// XXX We should *not* get the currentCard from the global state, but
diff --git a/client/components/sidebar/sidebar.js b/client/components/sidebar/sidebar.js
index 59a2b42c..0ff73215 100644
--- a/client/components/sidebar/sidebar.js
+++ b/client/components/sidebar/sidebar.js
@@ -5,7 +5,7 @@ const defaultView = 'home';
const viewTitles = {
filter: 'filter-cards',
multiselection: 'multi-selection',
- customFields: 'custom-fields',
+ customFields: 'configure-custom-fields',
archives: 'archives',
};
diff --git a/client/components/sidebar/sidebar.styl b/client/components/sidebar/sidebar.styl
index 8f2f493e..740186b5 100644
--- a/client/components/sidebar/sidebar.styl
+++ b/client/components/sidebar/sidebar.styl
@@ -45,28 +45,45 @@
display: flex
flex-direction: column
- li > a
- display: flex
- height: 30px
- margin: 0
- padding: 4px
- border-radius: 3px
- align-items: center
-
- &:hover
- &, i, .quiet
- color white
-
- .member, .card-label
- margin-right: 7px
- margin-top: 5px
-
- .sidebar-list-item-description
- flex: 1
- overflow: ellipsis
-
- .fa.fa-check
- margin: 0 4px
+ li
+ & > a
+ display: flex
+ height: 30px
+ margin: 0
+ padding: 4px
+ border-radius: 3px
+ align-items: center
+
+ &:hover
+ &, i, .quiet
+ color white
+
+ .member, .card-label
+ margin-right: 7px
+ margin-top: 5px
+
+ .minicard-edit-button
+ float: right
+ padding: 8px
+ border-radius: 3px
+
+ .sidebar-list-item-description
+ flex: 1
+ overflow: ellipsis
+
+ .fa.fa-check
+ margin: 0 4px
+
+ .minicard
+ padding: 6px 8px 4px
+
+ .minicard-edit-button
+ float: right
+ padding: 4px
+ border-radius: 3px
+
+ &:hover
+ background: #dbdbdb
.sidebar-btn
display: block
diff --git a/client/components/sidebar/sidebarCustomFields.jade b/client/components/sidebar/sidebarCustomFields.jade
index 33688441..e17bb75d 100644
--- a/client/components/sidebar/sidebarCustomFields.jade
+++ b/client/components/sidebar/sidebarCustomFields.jade
@@ -1,31 +1,49 @@
template(name="customFieldsSidebar")
ul.sidebar-list
- each customsFields
+ each customFields
li
- a.name
- span.sidebar-list-item-description
- {{_ 'some name'}}
+ div.minicard-wrapper.js-minicard
+ div.minicard
+ a.fa.fa-pencil.js-edit-custom-field.minicard-edit-button
+ div.minicard-title
+ | {{ name }} ({{ type }})
+
if currentUser.isBoardMember
hr
a.sidebar-btn.js-open-create-custom-field
i.fa.fa-plus
- span {{_ 'Create Custom Field'}}
+ span {{_ 'createCustomField'}}
template(name="createCustomFieldPopup")
form
label
| {{_ 'name'}}
- input.js-field-name(type="text" name="field-name" autofocus)
+ unless _id
+ input.js-field-name(type="text" name="field-name" autofocus)
+ else
+ input.js-field-name(type="text" name="field-name" value=name)
+
label
| {{_ 'type'}}
- select.js-field-type(name="field-type")
- option(value="string") String
- option(value="number") Number
- option(value="checkbox") Checkbox
- option(value="date") Date
- option(value="DropdownList") Dropdown List
+ select.js-field-type(name="field-type" disabled="{{#if _id}}disabled{{/if}}")
+ each types
+ if selected
+ option(value=type selected="selected") {{name}}
+ else
+ option(value=type) {{name}}
a.flex.js-field-show-on-card
.materialCheckBox(class="{{#if showOnCard}}is-checked{{/if}}")
span {{_ 'show-field-on-card'}}
- input.primary.wide(type="submit" value="{{_ 'save'}}") \ No newline at end of file
+ button.primary.wide.left(type="submit")
+ | {{_ 'save'}}
+ if _id
+ button.negate.wide.right.js-delete-custom-field
+ | {{_ 'delete'}}
+
+template(name="editCustomFieldPopup")
+ | {{> createCustomFieldPopup}}
+
+template(name="deleteCustomFieldPopup")
+ p {{_ "custom-field-delete-pop"}}
+ button.js-confirm.negate.full(type="submit") {{_ 'delete'}} \ No newline at end of file
diff --git a/client/components/sidebar/sidebarCustomFields.js b/client/components/sidebar/sidebarCustomFields.js
index da03f484..6ddd466e 100644
--- a/client/components/sidebar/sidebarCustomFields.js
+++ b/client/components/sidebar/sidebarCustomFields.js
@@ -9,21 +9,22 @@ BlazeComponent.extendComponent({
events() {
return [{
'click .js-open-create-custom-field': Popup.open('createCustomField'),
- 'click .js-edit-custom-field'() {
- // todo
- },
- 'click .js-delete-custom-field': Popup.afterConfirm('customFieldDelete', function() {
- const customFieldId = this._id;
- CustomFields.remove(customFieldId);
- Popup.close();
- }),
+ 'click .js-edit-custom-field': Popup.open('editCustomField'),
}];
},
}).register('customFieldsSidebar');
Template.createCustomFieldPopup.helpers({
-
+ types() {
+ var currentType = this.type;
+ return ['text', 'number', 'checkbox', 'date', 'dropdown'].
+ map(type => {return {
+ type: type,
+ name: TAPi18n.__('custom-field-' + type),
+ selected: type == currentType,
+ }});
+ },
});
Template.createCustomFieldPopup.events({
@@ -41,7 +42,7 @@ Template.createCustomFieldPopup.events({
const name = tpl.find('.js-field-name').value.trim();
const type = tpl.find('.js-field-type').value.trim();
const showOnCard = tpl.find('.js-field-show-on-card.is-checked') != null;
- //console.log("Create",name,type,showOnCard);
+ //console.log('Create',name,type,showOnCard);
CustomFields.insert({
boardId: Session.get('currentBoard'),
@@ -52,4 +53,17 @@ Template.createCustomFieldPopup.events({
Popup.back();
},
-}); \ No newline at end of file
+ 'click .js-delete-custom-field': Popup.afterConfirm('deleteCustomField', function() {
+ const customFieldId = this._id;
+ CustomFields.remove(customFieldId);
+ Popup.close();
+ }),
+});
+
+/*Template.deleteCustomFieldPopup.events({
+ 'submit'(evt) {
+ const customFieldId = this._id;
+ CustomFields.remove(customFieldId);
+ Popup.close();
+ }
+});*/ \ No newline at end of file
diff --git a/i18n/en.i18n.json b/i18n/en.i18n.json
index d7b9a48b..1039d3c6 100644
--- a/i18n/en.i18n.json
+++ b/i18n/en.i18n.json
@@ -103,6 +103,7 @@
"card-due": "Due",
"card-due-on": "Due on",
"card-edit-attachments": "Edit attachments",
+ "card-edit-custom-fields": "Edit custom fields",
"card-edit-labels": "Edit labels",
"card-edit-members": "Edit members",
"card-labels-title": "Change the labels for the card.",
@@ -110,6 +111,7 @@
"card-start": "Start",
"card-start-on": "Starts on",
"cardAttachmentsPopup-title": "Attach From",
+ "cardCustomFieldsPopup-title": "Edit custom fields",
"cardDeletePopup-title": "Delete Card?",
"cardDetailsActionsPopup-title": "Card Actions",
"cardLabelsPopup-title": "Labels",
@@ -153,16 +155,22 @@
"create": "Create",
"createBoardPopup-title": "Create Board",
"chooseBoardSourcePopup-title": "Import board",
+ "configure-custom-fields": "Configure Custom Fields",
"createLabelPopup-title": "Create Label",
- "createCustomField": "Create Custom Field",
- "createCustomFieldPopup-title": "Create Custom Field",
+ "createCustomField": "Create Field",
+ "createCustomFieldPopup-title": "Create Field",
"current": "current",
- "custom-fields": "Custom Fields",
- "customFieldDeletePopup-title": "Delete Card?",
+ "custom-field-delete-pop": "There is no undo. This will remove this custom field from all cards and destroy its history.",
+ "custom-field-checkbox": "Checkbox",
+ "custom-field-date": "Date",
+ "custom-field-dropdown": "Dropdown List",
+ "custom-field-number": "Number",
+ "custom-field-text": "Text",
"date": "Date",
"decline": "Decline",
"default-avatar": "Default avatar",
"delete": "Delete",
+ "deleteCustomFieldPopup-title": "Delete Custom Field?",
"deleteLabelPopup-title": "Delete Label?",
"description": "Description",
"disambiguateMultiLabelPopup-title": "Disambiguate Label Action",
@@ -175,6 +183,7 @@
"edit-profile": "Edit Profile",
"editCardStartDatePopup-title": "Change start date",
"editCardDueDatePopup-title": "Change due date",
+ "editCustomFieldPopup-title": "Edit Field",
"editLabelPopup-title": "Change Label",
"editNotificationPopup-title": "Edit Notification",
"editProfilePopup-title": "Edit Profile",
diff --git a/models/boards.js b/models/boards.js
index 8a7844e2..98c0e46d 100644
--- a/models/boards.js
+++ b/models/boards.js
@@ -235,6 +235,10 @@ Boards.helpers({
return `board-color-${this.color}`;
},
+ customFields() {
+ return CustomFields.find({ boardId: this._id }, { sort: { name: 1 } });
+ },
+
// XXX currently mutations return no value so we have an issue when using addLabel in import
// XXX waiting on https://github.com/mquandalle/meteor-collection-mutations/issues/1 to remove...
pushLabel(name, color) {
diff --git a/models/customFields.js b/models/customFields.js
index 75ee55e8..5e76db35 100644
--- a/models/customFields.js
+++ b/models/customFields.js
@@ -25,7 +25,7 @@ CustomFields.allow({
remove(userId, doc) {
return allowIsBoardMember(userId, Boards.findOne(doc.boardId));
},
- fetch: ['boardId'],
+ fetch: ['userId', 'boardId'],
});
// not sure if we need this?
@@ -41,21 +41,18 @@ function customFieldCreation(userId, doc){
}
if (Meteor.isServer) {
- // Comments are often fetched within a card, so we create an index to make these
- // queries more efficient.
- Meteor.startup(() => {
- CardComments._collection._ensureIndex({ cardId: 1, createdAt: -1 });
- });
+ /*Meteor.startup(() => {
+ CustomFields._collection._ensureIndex({ boardId: 1});
+ });*/
CustomFields.after.insert((userId, doc) => {
customFieldCreation(userId, doc);
});
CustomFields.after.remove((userId, doc) => {
- const activity = Activities.findOne({ customFieldId: doc._id });
- if (activity) {
- Activities.remove(activity._id);
- }
+ Activities.remove({
+ customFieldId: doc._id,
+ });
});
}
@@ -70,7 +67,7 @@ if (Meteor.isServer) {
});
});
- JsonRoutes.add('GET', '/api/boards/:boardId/comments/:customFieldId', function (req, res, next) {
+ JsonRoutes.add('GET', '/api/boards/:boardId/custom-fields/:customFieldId', function (req, res, next) {
Authentication.checkUserId( req.userId);
const paramBoardId = req.params.boardId;
const paramCustomFieldId = req.params.customFieldId;
@@ -90,7 +87,7 @@ if (Meteor.isServer) {
boardId: paramBoardId,
});
- const customField = CustomFields.findOne({_id: id, cardId:paramCardId, boardId: paramBoardId });
+ const customField = CustomFields.findOne({_id: id, boardId: paramBoardId });
customFieldCreation(req.body.authorId, customField);
JsonRoutes.sendResult(res, {
diff --git a/server/publications/boards.js b/server/publications/boards.js
index f482f619..7cadf0c6 100644
--- a/server/publications/boards.js
+++ b/server/publications/boards.js
@@ -74,6 +74,7 @@ Meteor.publishRelations('board', function(boardId) {
}, { limit: 1 }), function(boardId, board) {
this.cursor(Lists.find({ boardId }));
this.cursor(Integrations.find({ boardId }));
+ this.cursor(CustomFields.find({ boardId }, { sort: { name: 1 } }));
// Cards and cards comments
// XXX Originally we were publishing the card documents as a child of the