mirror of
https://github.com/wekan/wekan.git
synced 2025-12-16 15:30:13 +01:00
dropdown items
This commit is contained in:
parent
caad952bc1
commit
3753337d60
10 changed files with 211 additions and 70 deletions
|
|
@ -103,7 +103,7 @@ template(name="boardHeaderBar")
|
||||||
|
|
||||||
template(name="boardMenuPopup")
|
template(name="boardMenuPopup")
|
||||||
ul.pop-over-list
|
ul.pop-over-list
|
||||||
li: a.js-configure-custom-fields {{_ 'configure-custom-fields'}}
|
li: a.js-custom-fields {{_ 'custom-fields'}}
|
||||||
li: a.js-open-archives {{_ 'archived-items'}}
|
li: a.js-open-archives {{_ 'archived-items'}}
|
||||||
if currentUser.isBoardAdmin
|
if currentUser.isBoardAdmin
|
||||||
li: a.js-change-board-color {{_ 'board-change-color'}}
|
li: a.js-change-board-color {{_ 'board-change-color'}}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
Template.boardMenuPopup.events({
|
Template.boardMenuPopup.events({
|
||||||
'click .js-rename-board': Popup.open('boardChangeTitle'),
|
'click .js-rename-board': Popup.open('boardChangeTitle'),
|
||||||
'click .js-configure-custom-fields'() {
|
'click .js-custom-fields'() {
|
||||||
Sidebar.setView('customFields');
|
Sidebar.setView('customFields');
|
||||||
Popup.close();
|
Popup.close();
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -8,11 +8,14 @@ template(name="cardCustomFieldsPopup")
|
||||||
if hasCustomField
|
if hasCustomField
|
||||||
i.fa.fa-check
|
i.fa.fa-check
|
||||||
hr
|
hr
|
||||||
a.quiet-button.full.js-configure-custom-fields
|
a.quiet-button.full.js-settings
|
||||||
i.fa.fa-cog
|
i.fa.fa-cog
|
||||||
span {{_ 'configure-custom-fields'}}
|
span {{_ 'settings'}}
|
||||||
|
|
||||||
template(name="cardCustomFieldText")
|
template(name="cardCustomField")
|
||||||
|
+Template.dynamic(template=getTemplate)
|
||||||
|
|
||||||
|
template(name="cardCustomField-text")
|
||||||
if canModifyCard
|
if canModifyCard
|
||||||
+inlinedForm(classNames="js-card-customfield-text")
|
+inlinedForm(classNames="js-card-customfield-text")
|
||||||
+editor(autofocus=true)
|
+editor(autofocus=true)
|
||||||
|
|
@ -25,5 +28,25 @@ template(name="cardCustomFieldText")
|
||||||
if value
|
if value
|
||||||
+viewer
|
+viewer
|
||||||
= value
|
= value
|
||||||
|
else
|
||||||
|
| {{_ 'edit'}}
|
||||||
|
|
||||||
|
template(name="cardCustomField-dropdown")
|
||||||
|
if canModifyCard
|
||||||
|
+inlinedForm(classNames="js-card-customfield-dropdown")
|
||||||
|
select.inline
|
||||||
|
each items
|
||||||
|
if($eq data.value this._id)
|
||||||
|
option(value=_id selected="selected") {{name}}
|
||||||
|
else
|
||||||
|
option(value=_id) {{name}}
|
||||||
|
.edit-controls.clearfix
|
||||||
|
button.primary(type="submit") {{_ 'save'}}
|
||||||
|
a.fa.fa-times-thin.js-close-inlined-form
|
||||||
|
else
|
||||||
|
a.js-open-inlined-form
|
||||||
|
if value
|
||||||
|
+viewer
|
||||||
|
= selectedItem
|
||||||
else
|
else
|
||||||
| {{_ 'edit'}}
|
| {{_ 'edit'}}
|
||||||
|
|
@ -13,7 +13,7 @@ Template.cardCustomFieldsPopup.events({
|
||||||
card.toggleCustomField(customFieldId);
|
card.toggleCustomField(customFieldId);
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
},
|
},
|
||||||
'click .js-configure-custom-fields'(evt) {
|
'click .js-settings'(evt) {
|
||||||
EscapeActions.executeUpTo('detailsPane');
|
EscapeActions.executeUpTo('detailsPane');
|
||||||
Sidebar.setView('customFields');
|
Sidebar.setView('customFields');
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
|
|
@ -21,23 +21,25 @@ Template.cardCustomFieldsPopup.events({
|
||||||
});
|
});
|
||||||
|
|
||||||
const CardCustomField = BlazeComponent.extendComponent({
|
const CardCustomField = BlazeComponent.extendComponent({
|
||||||
template() {
|
|
||||||
return 'cardCustomFieldText';
|
getTemplate() {
|
||||||
|
return 'cardCustomField-' + this.data().definition.type;
|
||||||
},
|
},
|
||||||
|
|
||||||
onCreated() {
|
onCreated() {
|
||||||
const self = this;
|
const self = this;
|
||||||
self.date = ReactiveVar();
|
|
||||||
self.now = ReactiveVar(moment());
|
|
||||||
},
|
},
|
||||||
|
|
||||||
value() {
|
canModifyCard() {
|
||||||
return this.data().value;
|
return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
|
||||||
},
|
},
|
||||||
|
});
|
||||||
|
CardCustomField.register('cardCustomField');
|
||||||
|
|
||||||
showISODate() {
|
(class extends CardCustomField {
|
||||||
return this.date.get().toISOString();
|
|
||||||
},
|
onCreated() {
|
||||||
|
}
|
||||||
|
|
||||||
events() {
|
events() {
|
||||||
return [{
|
return [{
|
||||||
|
|
@ -48,13 +50,39 @@ const CardCustomField = BlazeComponent.extendComponent({
|
||||||
const value = this.currentComponent().getValue();
|
const value = this.currentComponent().getValue();
|
||||||
card.setCustomField(customFieldId,value);
|
card.setCustomField(customFieldId,value);
|
||||||
},
|
},
|
||||||
'click .js-edit-date': Popup.open('editCardStartDate'),
|
|
||||||
}];
|
}];
|
||||||
},
|
}
|
||||||
|
|
||||||
canModifyCard() {
|
}).register('cardCustomField-text');
|
||||||
return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
CardCustomField.register('cardCustomField');
|
(class extends CardCustomField {
|
||||||
|
|
||||||
|
onCreated() {
|
||||||
|
this._items = this.data().definition.settings.dropdownItems;
|
||||||
|
this.items = this._items.slice(0);
|
||||||
|
this.items.unshift({
|
||||||
|
_id: "",
|
||||||
|
name: TAPi18n.__('custom-field-dropdown-none')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedItem() {
|
||||||
|
const selected = this._items.find((item) => {
|
||||||
|
return item._id == this.data().value;
|
||||||
|
});
|
||||||
|
return (selected) ? selected.name : TAPi18n.__('custom-field-dropdown-unknown');
|
||||||
|
}
|
||||||
|
|
||||||
|
events() {
|
||||||
|
return [{
|
||||||
|
'submit .js-card-customfield-dropdown'(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
const card = Cards.findOne(Session.get('currentCard'));
|
||||||
|
const customFieldId = this.data()._id;
|
||||||
|
const value = this.find('select').value;
|
||||||
|
card.setCustomField(customFieldId,value);
|
||||||
|
},
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
}).register('cardCustomField-dropdown');
|
||||||
|
|
@ -85,6 +85,9 @@ select
|
||||||
width: 256px
|
width: 256px
|
||||||
margin-bottom: 8px
|
margin-bottom: 8px
|
||||||
|
|
||||||
|
&.inline
|
||||||
|
width: 100%
|
||||||
|
|
||||||
option[disabled]
|
option[disabled]
|
||||||
color: #8c8c8c
|
color: #8c8c8c
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ const defaultView = 'home';
|
||||||
const viewTitles = {
|
const viewTitles = {
|
||||||
filter: 'filter-cards',
|
filter: 'filter-cards',
|
||||||
multiselection: 'multi-selection',
|
multiselection: 'multi-selection',
|
||||||
customFields: 'configure-custom-fields',
|
customFields: 'custom-fields',
|
||||||
archives: 'archives',
|
archives: 'archives',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,31 +19,34 @@ template(name="createCustomFieldPopup")
|
||||||
label
|
label
|
||||||
| {{_ 'name'}}
|
| {{_ 'name'}}
|
||||||
unless _id
|
unless _id
|
||||||
input.js-field-name(type="text" name="field-name" autofocus)
|
input.js-field-name(type="text" autofocus)
|
||||||
else
|
else
|
||||||
input.js-field-name(type="text" name="field-name" value=name)
|
input.js-field-name(type="text" value=name)
|
||||||
|
|
||||||
label
|
label
|
||||||
| {{_ 'type'}}
|
| {{_ 'type'}}
|
||||||
select.js-field-type(name="field-type" disabled="{{#if _id}}disabled{{/if}}")
|
select.js-field-type(disabled="{{#if _id}}disabled{{/if}}")
|
||||||
each types
|
each types
|
||||||
if selected
|
if selected
|
||||||
option(value=type selected="selected") {{name}}
|
option(value=value selected="selected") {{name}}
|
||||||
else
|
else
|
||||||
option(value=type) {{name}}
|
option(value=value) {{name}}
|
||||||
|
div.js-field-settings.js-field-settings-dropdown(class="{{#if isTypeNotSelected 'dropdown'}}hide{{/if}}")
|
||||||
|
label
|
||||||
|
| {{_ 'custom-field-dropdown-options'}}
|
||||||
|
each dropdownItems.get
|
||||||
|
input.js-dropdown-item(type="text" value=name placeholder="")
|
||||||
|
input.js-dropdown-item.last(type="text" value="" placeholder="{{_ 'custom-field-dropdown-options-placeholder'}}")
|
||||||
a.flex.js-field-show-on-card
|
a.flex.js-field-show-on-card
|
||||||
.materialCheckBox(class="{{#if showOnCard}}is-checked{{/if}}")
|
.materialCheckBox(class="{{#if showOnCard}}is-checked{{/if}}")
|
||||||
|
|
||||||
span {{_ 'show-field-on-card'}}
|
span {{_ 'show-field-on-card'}}
|
||||||
button.primary.wide.left(type="submit")
|
button.primary.wide.left(type="button")
|
||||||
| {{_ 'save'}}
|
| {{_ 'save'}}
|
||||||
if _id
|
if _id
|
||||||
button.negate.wide.right.js-delete-custom-field
|
button.negate.wide.right.js-delete-custom-field(type="button")
|
||||||
| {{_ 'delete'}}
|
| {{_ 'delete'}}
|
||||||
|
|
||||||
template(name="editCustomFieldPopup")
|
|
||||||
| {{> createCustomFieldPopup}}
|
|
||||||
|
|
||||||
template(name="deleteCustomFieldPopup")
|
template(name="deleteCustomFieldPopup")
|
||||||
p {{_ "custom-field-delete-pop"}}
|
p {{_ "custom-field-delete-pop"}}
|
||||||
button.js-confirm.negate.full(type="submit") {{_ 'delete'}}
|
button.js-confirm.negate.full(type="submit") {{_ 'delete'}}
|
||||||
|
|
@ -15,50 +15,111 @@ BlazeComponent.extendComponent({
|
||||||
|
|
||||||
}).register('customFieldsSidebar');
|
}).register('customFieldsSidebar');
|
||||||
|
|
||||||
Template.createCustomFieldPopup.helpers({
|
const CreateCustomFieldPopup = BlazeComponent.extendComponent({
|
||||||
|
|
||||||
|
_types: ['text', 'number', 'checkbox', 'date', 'dropdown'],
|
||||||
|
|
||||||
|
onCreated() {
|
||||||
|
this.type = new ReactiveVar((this.data().type) ? this.data().type : this._types[0]);
|
||||||
|
this.dropdownItems = new ReactiveVar((this.data().settings && this.data().settings.dropdownItems) ? this.data().settings.dropdownItems : []);
|
||||||
|
},
|
||||||
|
|
||||||
types() {
|
types() {
|
||||||
var currentType = this.type;
|
const currentType = this.data().type;
|
||||||
return ['text', 'number', 'checkbox', 'date', 'dropdown'].
|
return this._types.
|
||||||
map(type => {return {
|
map(type => {return {
|
||||||
type: type,
|
value: type,
|
||||||
name: TAPi18n.__('custom-field-' + type),
|
name: TAPi18n.__('custom-field-' + type),
|
||||||
selected: type == currentType,
|
selected: type == currentType,
|
||||||
}});
|
}});
|
||||||
},
|
},
|
||||||
});
|
|
||||||
|
|
||||||
Template.createCustomFieldPopup.events({
|
isTypeNotSelected(type) {
|
||||||
'click .js-field-show-on-card'(event) {
|
return this.type.get() !== type;
|
||||||
let $target = $(event.target);
|
|
||||||
if(!$target.hasClass('js-field-show-on-card')){
|
|
||||||
$target = $target.parent();
|
|
||||||
}
|
|
||||||
$target.find('.materialCheckBox').toggleClass('is-checked');
|
|
||||||
$target.toggleClass('is-checked');
|
|
||||||
},
|
},
|
||||||
'submit'(evt, tpl) {
|
|
||||||
evt.preventDefault();
|
|
||||||
|
|
||||||
const name = tpl.find('.js-field-name').value.trim();
|
getDropdownItems() {
|
||||||
const type = tpl.find('.js-field-type').value.trim();
|
var items = this.dropdownItems.get();
|
||||||
const showOnCard = tpl.find('.js-field-show-on-card.is-checked') != null;
|
Array.from(this.findAll('.js-field-settings-dropdown input')).forEach((el, index) => {
|
||||||
//console.log('Create',name,type,showOnCard);
|
//console.log('each item!', index, el.value);
|
||||||
|
if (!items[index]) items[index] = {
|
||||||
CustomFields.insert({
|
_id: Random.id(6),
|
||||||
boardId: Session.get('currentBoard'),
|
};
|
||||||
name: name,
|
items[index].name = el.value.trim();
|
||||||
type: type,
|
|
||||||
showOnCard: showOnCard
|
|
||||||
});
|
});
|
||||||
|
return items;
|
||||||
Popup.back();
|
|
||||||
},
|
},
|
||||||
'click .js-delete-custom-field': Popup.afterConfirm('deleteCustomField', function() {
|
|
||||||
const customFieldId = this._id;
|
getSettings() {
|
||||||
CustomFields.remove(customFieldId);
|
let settings = {};
|
||||||
Popup.close();
|
switch (this.type.get()) {
|
||||||
}),
|
case 'dropdown':
|
||||||
|
let dropdownItems = this.getDropdownItems().filter(item => !!item.name.trim());
|
||||||
|
settings.dropdownItems = dropdownItems;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return settings;
|
||||||
|
},
|
||||||
|
|
||||||
|
events() {
|
||||||
|
return [{
|
||||||
|
'change .js-field-type'(evt) {
|
||||||
|
const value = evt.target.value;
|
||||||
|
this.type.set(value);
|
||||||
|
},
|
||||||
|
'keydown .js-dropdown-item.last'(evt) {
|
||||||
|
if (evt.target.value.trim() && evt.keyCode === 13) {
|
||||||
|
let items = this.getDropdownItems();
|
||||||
|
this.dropdownItems.set(items);
|
||||||
|
evt.target.value = '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'click .js-field-show-on-card'(evt) {
|
||||||
|
let $target = $(evt.target);
|
||||||
|
if(!$target.hasClass('js-field-show-on-card')){
|
||||||
|
$target = $target.parent();
|
||||||
|
}
|
||||||
|
$target.find('.materialCheckBox').toggleClass('is-checked');
|
||||||
|
$target.toggleClass('is-checked');
|
||||||
|
},
|
||||||
|
'click .primary'(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
boardId: Session.get('currentBoard'),
|
||||||
|
name: this.find('.js-field-name').value.trim(),
|
||||||
|
type: this.type.get(),
|
||||||
|
settings: this.getSettings(),
|
||||||
|
showOnCard: this.find('.js-field-show-on-card.is-checked') != null
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert or update
|
||||||
|
if (!this.data()._id) {
|
||||||
|
CustomFields.insert(data);
|
||||||
|
} else {
|
||||||
|
CustomFields.update(this.data()._id, {$set: data});
|
||||||
|
}
|
||||||
|
|
||||||
|
Popup.back();
|
||||||
|
},
|
||||||
|
'click .js-delete-custom-field': Popup.afterConfirm('deleteCustomField', function() {
|
||||||
|
const customFieldId = this._id;
|
||||||
|
CustomFields.remove(customFieldId);
|
||||||
|
Popup.close();
|
||||||
|
}),
|
||||||
|
}];
|
||||||
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
|
CreateCustomFieldPopup.register('createCustomFieldPopup');
|
||||||
|
|
||||||
|
(class extends CreateCustomFieldPopup {
|
||||||
|
|
||||||
|
template() {
|
||||||
|
return 'createCustomFieldPopup';
|
||||||
|
}
|
||||||
|
|
||||||
|
}).register('editCustomFieldPopup');
|
||||||
|
|
||||||
/*Template.deleteCustomFieldPopup.events({
|
/*Template.deleteCustomFieldPopup.events({
|
||||||
'submit'(evt) {
|
'submit'(evt) {
|
||||||
|
|
|
||||||
|
|
@ -155,7 +155,6 @@
|
||||||
"create": "Create",
|
"create": "Create",
|
||||||
"createBoardPopup-title": "Create Board",
|
"createBoardPopup-title": "Create Board",
|
||||||
"chooseBoardSourcePopup-title": "Import board",
|
"chooseBoardSourcePopup-title": "Import board",
|
||||||
"configure-custom-fields": "Configure Custom Fields",
|
|
||||||
"createLabelPopup-title": "Create Label",
|
"createLabelPopup-title": "Create Label",
|
||||||
"createCustomField": "Create Field",
|
"createCustomField": "Create Field",
|
||||||
"createCustomFieldPopup-title": "Create Field",
|
"createCustomFieldPopup-title": "Create Field",
|
||||||
|
|
@ -164,8 +163,13 @@
|
||||||
"custom-field-checkbox": "Checkbox",
|
"custom-field-checkbox": "Checkbox",
|
||||||
"custom-field-date": "Date",
|
"custom-field-date": "Date",
|
||||||
"custom-field-dropdown": "Dropdown List",
|
"custom-field-dropdown": "Dropdown List",
|
||||||
|
"custom-field-dropdown-none": "(none)",
|
||||||
|
"custom-field-dropdown-options": "List Options",
|
||||||
|
"custom-field-dropdown-options-placeholder": "Press enter to add more options",
|
||||||
|
"custom-field-dropdown-unknown": "(unknown)",
|
||||||
"custom-field-number": "Number",
|
"custom-field-number": "Number",
|
||||||
"custom-field-text": "Text",
|
"custom-field-text": "Text",
|
||||||
|
"custom-fields": "Custom Fields",
|
||||||
"date": "Date",
|
"date": "Date",
|
||||||
"decline": "Decline",
|
"decline": "Decline",
|
||||||
"default-avatar": "Default avatar",
|
"default-avatar": "Default avatar",
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,24 @@ CustomFields.attachSchema(new SimpleSchema({
|
||||||
},
|
},
|
||||||
type: {
|
type: {
|
||||||
type: String,
|
type: String,
|
||||||
|
allowedValues: ['text', 'number', 'checkbox', 'date', 'dropdown']
|
||||||
|
},
|
||||||
|
settings: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
'settings.dropdownItems': {
|
||||||
|
type: [Object],
|
||||||
|
optional: true
|
||||||
|
},
|
||||||
|
'settings.dropdownItems.$': {
|
||||||
|
type: new SimpleSchema({
|
||||||
|
_id: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
})
|
||||||
},
|
},
|
||||||
showOnCard: {
|
showOnCard: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
|
|
@ -83,6 +101,7 @@ if (Meteor.isServer) {
|
||||||
const id = CustomFields.direct.insert({
|
const id = CustomFields.direct.insert({
|
||||||
name: req.body.name,
|
name: req.body.name,
|
||||||
type: req.body.type,
|
type: req.body.type,
|
||||||
|
settings: req.body.settings,
|
||||||
showOnCard: req.body.showOnCard,
|
showOnCard: req.body.showOnCard,
|
||||||
boardId: paramBoardId,
|
boardId: paramBoardId,
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue