summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js/views
diff options
context:
space:
mode:
authorAaron Bohy <aab@odoo.com>2017-03-14 10:30:10 +0100
committerAaron Bohy <aab@odoo.com>2017-04-11 19:44:38 +0200
commitd4fdbad99a776052340d0ea941cac8e85cdfebc5 (patch)
tree9efd0335f0f3e5cbb52d527a52228eb2db64b55a /addons/web/static/src/js/views
parentc369b6ec2c6f9c489f116ebf29393316775c25a2 (diff)
[REF] web: kanban: adapt code to new style
This commit adapts some kanban files to the new style and guidelines.
Diffstat (limited to 'addons/web/static/src/js/views')
-rw-r--r--addons/web/static/src/js/views/kanban/kanban_column.js243
-rw-r--r--addons/web/static/src/js/views/kanban/kanban_controller.js18
-rw-r--r--addons/web/static/src/js/views/kanban/kanban_model.js174
-rw-r--r--addons/web/static/src/js/views/kanban/kanban_record.js4
-rw-r--r--addons/web/static/src/js/views/kanban/kanban_renderer.js201
5 files changed, 402 insertions, 238 deletions
diff --git a/addons/web/static/src/js/views/kanban/kanban_column.js b/addons/web/static/src/js/views/kanban/kanban_column.js
index b93f75cd9df..9dab04aa4fc 100644
--- a/addons/web/static/src/js/views/kanban/kanban_column.js
+++ b/addons/web/static/src/js/views/kanban/kanban_column.js
@@ -4,36 +4,33 @@ odoo.define('web.KanbanColumn', function (require) {
var config = require('web.config');
var core = require('web.core');
var Dialog = require('web.Dialog');
-var view_dialogs = require('web.view_dialogs');
-var quick_create = require('web.kanban_quick_create');
+var kanban_quick_create = require('web.kanban_quick_create');
var KanbanRecord = require('web.KanbanRecord');
+var view_dialogs = require('web.view_dialogs');
var Widget = require('web.Widget');
var _t = core._t;
var QWeb = core.qweb;
-var RecordQuickCreate = quick_create.RecordQuickCreate;
+var RecordQuickCreate = kanban_quick_create.RecordQuickCreate;
var KanbanColumn = Widget.extend({
- template: "KanbanView.Group",
- events: {
- 'click .o_column_edit': 'edit_column',
- 'click .o_column_delete': 'delete_column',
- 'click .o_column_archive': 'archive_records',
- 'click .o_column_unarchive': 'unarchive_records',
- 'click .o_kanban_quick_add': 'add_quick_create',
- 'click .o_kanban_load_more': 'load_more',
- 'click .o_kanban_toggle_fold': 'toggle_fold',
- },
+ template: 'KanbanView.Group',
custom_events: {
- 'kanban_record_delete': 'delete_record',
- 'cancel_quick_create': 'cancel_quick_create',
- 'quick_create_add_record': 'quick_create_add_record',
+ cancel_quick_create: '_onCancelQuickCreate',
+ kanban_record_delete: '_onDeleteRecord',
+ quick_create_add_record: '_onQuickCreateAddRecord',
+ },
+ events: {
+ 'click .o_column_edit': '_onEditColumn',
+ 'click .o_column_delete': '_onDeleteColumn',
+ 'click .o_column_archive': '_onArchiveRecords',
+ 'click .o_column_unarchive': '_onUnarchiveRecords',
+ 'click .o_kanban_quick_add': '_onAddQuickCreate',
+ 'click .o_kanban_load_more': '_onLoadMore',
+ 'click .o_kanban_toggle_fold': '_onToggleFold',
},
/**
- * @param {any} parent
- * @param {any} data
- * @param {any} options
- * @param {any} recordOptions
+ * @override
*/
init: function (parent, data, options, recordOptions) {
this._super(parent);
@@ -81,14 +78,14 @@ var KanbanColumn = Widget.extend({
}
},
/**
- * @returns {Deferred}
+ * @override
*/
start: function () {
var self = this;
this.$header = this.$('.o_kanban_header');
for (var i = 0; i < this.data_records.length; i++) {
- this.add_record(this.data_records[i], {no_update: true});
+ this.addRecord(this.data_records[i], {no_update: true});
}
this.$header.tooltip();
@@ -105,7 +102,7 @@ var KanbanColumn = Widget.extend({
cursor: 'move',
over: function () {
self.$el.addClass('o_kanban_hover');
- self.update_column();
+ self._update();
},
out: function () {
self.$el.removeClass('o_kanban_hover');
@@ -118,34 +115,61 @@ var KanbanColumn = Widget.extend({
if (index >= 0) {
if ($.contains(self.$el[0], record.$el[0])) {
// resequencing records
- self.trigger_up('kanban_column_resequence', {ids: self.get_ids()});
+ self.trigger_up('kanban_column_resequence', {ids: self._getIDs()});
}
} else {
// adding record to this column
- self.trigger_up('kanban_column_add_record', {record: record, ids: self.get_ids()});
+ self.trigger_up('kanban_column_add_record', {record: record, ids: self._getIDs()});
}
}
});
}
this.$el.click(function (event) {
if (self.folded) {
- self.toggle_fold(event);
+ self._onToggleFold(event);
}
});
- this.update_column();
+ this._update();
return this._super.apply(this, arguments);
},
- is_empty: function () {
- return !this.records.length;
- },
+ //--------------------------------------------------------------------------
+ // Public
+ //--------------------------------------------------------------------------
- add_record: function (data, options) {
- var record = new KanbanRecord(this, data, this.record_options);
+ /**
+ * Adds the quick create record to the top of the column.
+ */
+ addQuickCreate: function () {
+ if (this.quickCreateWidget) {
+ return;
+ }
+ var self = this;
+ var width = this.records.length ? this.records[0].$el.innerWidth() : this.$el.width() - 8;
+ this.quickCreateWidget = new RecordQuickCreate(this, width);
+ this.quickCreateWidget.insertAfter(this.$header);
+ this.quickCreateWidget.$el.focusout(function () {
+ var hasFocus = (self.quickCreateWidget.$(':focus').length > 0);
+ if (! hasFocus && self.quickCreateWidget) {
+ self._cancelQuickCreate();
+ }
+ });
+ },
+ /**
+ * Adds a record in the column.
+ *
+ * @param {Object} recordState
+ * @param {Object} options
+ * @params {string} options.position 'before' to add the record at the top,
+ * added at the bottom by default
+ * @params {Boolean} options.no_update set to true not to update the column
+ */
+ addRecord: function (recordState, options) {
+ var record = new KanbanRecord(this, recordState, this.record_options);
this.records.push(record);
if (options.position === 'before') {
- record.insertAfter(this.quick_create_widget ? this.quick_create_widget.$el : this.$header);
+ record.insertAfter(this.quickCreateWidget ? this.quickCreateWidget.$el : this.$header);
} else {
var $load_more = this.$('.o_kanban_load_more');
if ($load_more.length) {
@@ -155,19 +179,43 @@ var KanbanColumn = Widget.extend({
}
}
if (!options.no_update) {
- this.update_column();
+ this._update();
}
},
+ /**
+ * @returns {Boolean} true iff the column is empty
+ */
+ isEmpty: function () {
+ return !this.records.length;
+ },
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
- get_ids: function () {
+ /**
+ * Destroys the QuickCreate widget.
+ *
+ * @private
+ */
+ _cancelQuickCreate: function () {
+ this.quickCreateWidget.destroy();
+ this.quickCreateWidget = undefined;
+ },
+ /**
+ * @returns {integer[]} the res_ids of the records in the column
+ */
+ _getIDs: function () {
var ids = [];
this.$('.o_kanban_record').each(function (index, r) {
ids.push($(r).data('record').id);
});
return ids;
},
-
- update_column: function () {
+ /**
+ * @private
+ */
+ _update: function () {
var title = this.folded ? this.title + ' (' + this.size + ')' : this.title;
this.$header.find('.o_column_title').text(title);
this.$header.find('.o-kanban-count').text(this.records.length);
@@ -183,29 +231,42 @@ var KanbanColumn = Widget.extend({
}
},
- archive_records: function (event) {
- event.preventDefault();
- this.trigger_up('kanban_column_archive_records', {archive: true});
- },
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
- unarchive_records: function (event) {
- event.preventDefault();
- this.trigger_up('kanban_column_archive_records', {archive: false});
+ /**
+ * @private
+ */
+ _onAddQuickCreate: function () {
+ this.addQuickCreate();
},
-
- toggle_fold: function (event) {
+ /**
+ * @private
+ * @param {MouseEvent} event
+ */
+ _onArchiveRecords: function (event) {
event.preventDefault();
- this.trigger_up('column_toggle_fold');
+ this.trigger_up('kanban_column_archive_records', {archive: true});
},
-
- delete_column: function (event) {
+ /**
+ * @private
+ */
+ _onCancelQuickCreate: function () {
+ this.cancelQuickCreate();
+ },
+ /**
+ * @private
+ * @param {MouseEvent} event
+ */
+ _onDeleteColumn: function (event) {
event.preventDefault();
var buttons = [
{
text: _t("Ok"),
classes: 'btn-primary',
close: true,
- click: this.trigger_up.bind(this, 'kanban_column_delete')
+ click: this.trigger_up.bind(this, 'kanban_column_delete'),
},
{text: _t("Cancel"), close: true}
];
@@ -217,57 +278,63 @@ var KanbanColumn = Widget.extend({
}),
}).open();
},
-
- edit_column: function (event) {
- event.preventDefault();
- new view_dialogs.FormViewDialog(this, {
- res_model: this.relation,
- res_id: this.id,
- title: _t("Edit Column"),
- on_saved: this.trigger_up.bind(this, 'reload'),
- }).open();
- },
-
- delete_record: function (event) {
+ /**
+ * @private
+ * @param {OdooEvent} event
+ */
+ _onDeleteRecord: function (event) {
var self = this;
event.data.parent_id = this.db_id;
event.data.after = function cleanup() {
var index = self.records.indexOf(event.data.record);
self.records.splice(index, 1);
- self.update_column();
+ self._update();
};
},
-
- add_quick_create: function () {
- if (this.quick_create_widget) {
- return;
- }
- var self = this;
- var width = this.records.length ? this.records[0].$el.innerWidth() : this.$el.width() - 8;
- this.quick_create_widget = new RecordQuickCreate(this, width);
- this.quick_create_widget.insertAfter(this.$header);
- this.quick_create_widget.$el.focusout(function () {
- var hasFocus = (self.quick_create_widget.$(':focus').length > 0);
- if (! hasFocus && self.quick_create_widget) {
- self.cancel_quick_create();
- }
- });
+ /**
+ * @private
+ * @param {MouseEvent} event
+ */
+ _onEditColumn: function (event) {
+ event.preventDefault();
+ new view_dialogs.FormViewDialog(this, {
+ res_model: this.relation,
+ res_id: this.id,
+ title: _t("Edit Column"),
+ on_saved: this.trigger_up.bind(this, 'reload'),
+ }).open();
},
-
- cancel_quick_create: function () {
- this.quick_create_widget.destroy();
- this.quick_create_widget = undefined;
+ /**
+ * @private
+ * @param {MouseEvent} event
+ */
+ _onLoadMore: function (event) {
+ event.preventDefault();
+ this.trigger_up('kanban_load_more');
},
-
- quick_create_add_record: function (event) {
+ /**
+ * @private
+ * @param {OdooEvent} event
+ */
+ _onQuickCreateAddRecord: function (event) {
this.trigger_up('quick_create_record', event.data);
},
-
- load_more: function (event) {
+ /**
+ * @private
+ * @param {MouseEvent} event
+ */
+ _onToggleFold: function (event) {
event.preventDefault();
- this.trigger_up('kanban_load_more');
+ this.trigger_up('column_toggle_fold');
+ },
+ /**
+ * @private
+ * @param {MouseEvent} event
+ */
+ _onUnarchiveRecords: function (event) {
+ event.preventDefault();
+ this.trigger_up('kanban_column_archive_records', {archive: false});
},
-
});
return KanbanColumn;
diff --git a/addons/web/static/src/js/views/kanban/kanban_controller.js b/addons/web/static/src/js/views/kanban/kanban_controller.js
index 6061ef436b7..c00cbc568d2 100644
--- a/addons/web/static/src/js/views/kanban/kanban_controller.js
+++ b/addons/web/static/src/js/views/kanban/kanban_controller.js
@@ -59,7 +59,7 @@ var KanbanController = BasicController.extend({
var data = self.model.get(self.handle, {raw: true});
if (data.groupedBy.length > 0 && data.count > 0 && self.on_create === 'quick_create') {
// Activate the quick create in the first column
- self.renderer.add_quick_create();
+ self.renderer.addQuickCreate();
} else if (self.on_create && self.on_create !== 'quick_create') {
// Execute the given action
self.do_action(self.on_create, {
@@ -101,7 +101,7 @@ var KanbanController = BasicController.extend({
* @param {string} id local id from the basic record data
*/
_confirmSave: function (id) {
- this.renderer.update_record(this.model.get(id));
+ this.renderer.updateRecord(this.model.get(id));
},
/**
* @todo this is dead code right now. resurrect this?
@@ -181,7 +181,7 @@ var KanbanController = BasicController.extend({
.then(function () {
_.each(column_db_ids, function (db_id) {
var data = self.model.get(db_id);
- self.renderer.update_column(db_id, data);
+ self.renderer.updateColumn(db_id, data);
});
});
}).fail(this.reload.bind(this));
@@ -207,7 +207,7 @@ var KanbanController = BasicController.extend({
.toggleActive(record_ids, active_value, column.db_id)
.then(function (db_id) {
var data = self.model.get(db_id);
- self.renderer.update_column(db_id, data);
+ self.renderer.updateColumn(db_id, data);
});
}
},
@@ -228,8 +228,8 @@ var KanbanController = BasicController.extend({
this.model
.deleteRecords([column.db_id], relatedModelName, this.handle)
.done(function () {
- if (column.is_empty()) {
- self.renderer.remove_widget(column);
+ if (column.isEmpty()) {
+ self.renderer.removeWidget(column);
self._updateButtons();
} else {
self.reload();
@@ -255,7 +255,7 @@ var KanbanController = BasicController.extend({
var column = event.target;
this.model.load_more(column.db_id).then(function (db_id) {
var data = self.model.get(db_id);
- self.renderer.update_column(db_id, data);
+ self.renderer.updateColumn(db_id, data);
});
},
/**
@@ -297,7 +297,7 @@ var KanbanController = BasicController.extend({
return self.model
.addRecordToGroup(data.id, records[0])
.then(function (db_id) {
- column.add_record(self.model.get(db_id), {position: 'before'});
+ column.addRecord(self.model.get(db_id), {position: 'before'});
});
}
data.context['default_' + data.groupedBy[0]] = column.id;
@@ -347,7 +347,7 @@ var KanbanController = BasicController.extend({
var column = event.target;
this.model.toggleGroup(column.db_id).then(function (db_id) {
var data = self.model.get(db_id);
- self.renderer.update_column(db_id, data);
+ self.renderer.updateColumn(db_id, data);
});
},
/**
diff --git a/addons/web/static/src/js/views/kanban/kanban_model.js b/addons/web/static/src/js/views/kanban/kanban_model.js
index 780039edacc..2bfe117829d 100644
--- a/addons/web/static/src/js/views/kanban/kanban_model.js
+++ b/addons/web/static/src/js/views/kanban/kanban_model.js
@@ -1,26 +1,30 @@
odoo.define('web.KanbanModel', function (require) {
"use strict";
+/**
+ * The KanbanModel extends the BasicModel to add Kanban specific features like
+ * moving a record from a group to another, resequencing records...
+ */
+
var BasicModel = require('web.BasicModel');
-return BasicModel.extend({
- load: function (params) {
- this.defaultGroupedBy = params.groupBy;
- params.groupedBy = params.groupedBy.length ? params.groupedBy : this.defaultGroupedBy;
- return this._super(params);
- },
- reload: function (id, options) {
- // if the groupBy is given in the options and if it is an empty array,
- // fallback on the default groupBy
- if (options && options.groupBy && !options.groupBy.length) {
- options.groupBy = this.defaultGroupedBy;
- }
- return this._super(id, options);
- },
- addRecordToGroup: function (group_id, res_id) {
- var group = this.localData[group_id];
+var KanbanModel = BasicModel.extend({
+
+ //--------------------------------------------------------------------------
+ // Public
+ //--------------------------------------------------------------------------
+
+ /**
+ * Adds a record to a group in the localData, and fetch the record.
+ *
+ * @param {string} groupID localID of the group
+ * @param {integer} resId id of the record
+ * @returns {Deferred<string>} resolves to the local id of the new record
+ */
+ addRecordToGroup: function (groupID, resId) {
+ var group = this.localData[groupID];
var new_record = this._makeDataPoint({
- res_id: res_id,
+ res_id: resId,
modelName: group.model,
fields: group.fields,
fieldNames: group.fieldNames,
@@ -34,10 +38,66 @@ return BasicModel.extend({
return result.id;
});
},
- moveRecord: function (record_id, group_id, parent_id) {
+ /**
+ * Creates a new group from a name (performs a name_create).
+ *
+ * @param {string} name
+ * @param {string} parentID localID of the parent of the group
+ * @returns {Deferred<string>} resolves to the local id of the new group
+ */
+ createGroup: function (name, parentID) {
var self = this;
- var parent = this.localData[parent_id];
- var new_group = this.localData[group_id];
+ var parent = this.localData[parentID];
+ var groupBy = parent.groupedBy[0];
+ var groupByField = parent.fields[groupBy];
+ if (!groupByField || groupByField.type !== 'many2one') {
+ return $.Deferred().reject(); // only supported when grouped on m2o
+ }
+ return this._rpc(groupByField.relation, 'name_create')
+ .args([name])
+ .withContext(parent.context) // todo: combine with view context
+ .exec()
+ .then(function (result) {
+ var newGroup = self._makeDataPoint({
+ modelName: parent.model,
+ context: parent.context,
+ domain: parent.domain.concat([[groupBy,"=",result[0]]]),
+ fields: parent.fields,
+ fieldNames: parent.fieldNames,
+ groupedBy: parent.groupedBy,
+ isOpen: true,
+ limit: parent.limit,
+ openGroupByDefault: true,
+ orderedBy: parent.orderedBy,
+ value: result,
+ });
+
+ // newGroup.is_open = true;
+ parent.data.push(newGroup.id);
+ parent.count++;
+ return newGroup.id;
+ });
+ },
+ /**
+ * @override
+ */
+ load: function (params) {
+ this.defaultGroupedBy = params.groupBy;
+ params.groupedBy = params.groupedBy.length ? params.groupedBy : this.defaultGroupedBy;
+ return this._super(params);
+ },
+ /**
+ * Moves a record from a group to another.
+ *
+ * @param {string} recordID localID of the record
+ * @param {string} groupID localID of the new group of the record
+ * @param {string} parentID localID of the parent
+ * @returns {Deferred<string[]>} resolves to a pair [oldGroupID, newGroupID]
+ */
+ moveRecord: function (recordID, groupID, parentID) {
+ var self = this;
+ var parent = this.localData[parentID];
+ var new_group = this.localData[groupID];
var changes = {};
var groupedFieldName = parent.groupedBy[0];
var groupedField = parent.fields[groupedFieldName];
@@ -49,14 +109,14 @@ return BasicModel.extend({
} else {
changes[groupedFieldName] = new_group.value;
}
- return this.notifyChanges(record_id, changes).then(function () {
- return self.save(record_id);
+ return this.notifyChanges(recordID, changes).then(function () {
+ return self.save(recordID);
}).then(function (result) {
// Remove record from its current group
var old_group;
for (var i = 0; i < parent.count; i++) {
old_group = self.localData[parent.data[i]];
- var index = _.indexOf(old_group.data, record_id);
+ var index = _.indexOf(old_group.data, recordID);
if (index >= 0) {
old_group.data.splice(index, 1);
old_group.count--;
@@ -69,58 +129,46 @@ return BasicModel.extend({
return [old_group.id, new_group.id];
});
},
- resequence: function (modelName, res_ids, parent_id) {
- if ((res_ids.length <= 1)) {
- return $.when(parent_id); // there is nothing to sort
+ /**
+ * @override
+ */
+ reload: function (id, options) {
+ // if the groupBy is given in the options and if it is an empty array,
+ // fallback on the default groupBy
+ if (options && options.groupBy && !options.groupBy.length) {
+ options.groupBy = this.defaultGroupedBy;
+ }
+ return this._super(id, options);
+ },
+ /**
+ * Resequences records.
+ *
+ * @param {string} modelName
+ * @param {Array[integer]} resIDs the new sequence of ids
+ * @param {string]} parentID the localID of the parent
+ * @returns {Deferred<string>} resolves to the local id of the parent
+ */
+ resequence: function (modelName, resIDs, parentID) {
+ if ((resIDs.length <= 1)) {
+ return $.when(parentID); // there is nothing to sort
}
var self = this;
- var data = self.localData[parent_id];
+ var data = self.localData[parentID];
var def;
if (data.fields.sequence) {
def = this._rpc('/web/dataset/resequence')
- .params({model: modelName, ids: res_ids})
+ .params({model: modelName, ids: resIDs})
.exec();
}
return $.when(def).then(function () {
data.data = _.sortBy(data.data, function (d) {
- return _.indexOf(res_ids, d.res_id);
+ return _.indexOf(resIDs, d.res_id);
});
- return parent_id;
+ return parentID;
});
},
- createGroup: function (name, parentID) {
- var self = this;
- var parent = this.localData[parentID];
- var groupBy = parent.groupedBy[0];
- var groupByField = parent.fields[groupBy];
- if (!groupByField || groupByField.type !== 'many2one') {
- return $.Deferred().reject(); // only supported when grouped on m2o
- }
- return this._rpc(groupByField.relation, 'name_create')
- .args([name])
- .withContext(parent.context) // todo: combine with view context
- .exec()
- .then(function (result) {
- var newGroup = self._makeDataPoint({
- modelName: parent.model,
- context: parent.context,
- domain: parent.domain.concat([[groupBy,"=",result[0]]]),
- fields: parent.fields,
- fieldNames: parent.fieldNames,
- groupedBy: parent.groupedBy,
- isOpen: true,
- limit: parent.limit,
- openGroupByDefault: true,
- orderedBy: parent.orderedBy,
- value: result,
- });
-
- // newGroup.is_open = true;
- parent.data.push(newGroup.id);
- parent.count++;
- return newGroup.id;
- });
- },
});
+return KanbanModel;
+
});
diff --git a/addons/web/static/src/js/views/kanban/kanban_record.js b/addons/web/static/src/js/views/kanban/kanban_record.js
index d82c79b592b..2aeff18867b 100644
--- a/addons/web/static/src/js/views/kanban/kanban_record.js
+++ b/addons/web/static/src/js/views/kanban/kanban_record.js
@@ -14,14 +14,12 @@ var _t = core._t;
var KanbanRecord = Widget.extend({
template: 'KanbanView.record',
-
events: {
'click .oe_kanban_action': 'on_kanban_action_clicked',
'click .o_kanban_manage_toggle_button': 'toggle_manage_pane',
},
-
custom_events: {
- 'kanban_update_record': 'update_record',
+ kanban_update_record: 'update_record',
},
init: function (parent, state, options) {
diff --git a/addons/web/static/src/js/views/kanban/kanban_renderer.js b/addons/web/static/src/js/views/kanban/kanban_renderer.js
index fd6bc6b6419..faeb08d72bc 100644
--- a/addons/web/static/src/js/views/kanban/kanban_renderer.js
+++ b/addons/web/static/src/js/views/kanban/kanban_renderer.js
@@ -15,7 +15,7 @@ var ColumnQuickCreate = quick_create.ColumnQuickCreate;
var qweb = core.qweb;
-function find_in_node(node, predicate) {
+function findInNode(node, predicate) {
if (predicate(node)) {
return node;
}
@@ -23,25 +23,25 @@ function find_in_node(node, predicate) {
return undefined;
}
for (var i = 0; i < node.children.length; i++) {
- if (find_in_node(node.children[i], predicate)) {
+ if (findInNode(node.children[i], predicate)) {
return node.children[i];
}
}
}
-function qweb_add_if(node, condition) {
+function qwebAddIf(node, condition) {
if (node.attrs[qweb.prefix + '-if']) {
condition = _.str.sprintf("(%s) and (%s)", node.attrs[qweb.prefix + '-if'], condition);
}
node.attrs[qweb.prefix + '-if'] = condition;
}
-function transform_qweb_template(node, fields) {
+function transformQwebTemplate(node, fields) {
// Process modifiers
if (node.tag && node.attrs.modifiers) {
var modifiers = JSON.parse(node.attrs.modifiers || "{}");
if (modifiers.invisible) {
- qweb_add_if(node, _.str.sprintf("!kanban_compute_domain(%s)", JSON.stringify(modifiers.invisible)));
+ qwebAddIf(node, _.str.sprintf("!kanban_compute_domain(%s)", JSON.stringify(modifiers.invisible)));
}
}
switch (node.tag) {
@@ -108,116 +108,136 @@ function transform_qweb_template(node, fields) {
}
if (node.children) {
for (var i = 0, ii = node.children.length; i < ii; i++) {
- transform_qweb_template(node.children[i], fields);
+ transformQwebTemplate(node.children[i], fields);
}
}
}
-return BasicRenderer.extend({
- className: "o_kanban_view",
+var KanbanRenderer = BasicRenderer.extend({
+ className: 'o_kanban_view',
+ /**
+ * @override
+ */
init: function (parent, state, params) {
this._super.apply(this, arguments);
this.qweb = new QWeb(session.debug, {_s: session.origin});
- var templates = find_in_node(this.arch, function (n) { return n.tag === 'templates';});
- transform_qweb_template(templates, state.fields);
+ var templates = findInNode(this.arch, function (n) { return n.tag === 'templates';});
+ transformQwebTemplate(templates, state.fields);
this.qweb.add_template(utils.json_node_to_xml(templates));
- this.record_options = _.extend({}, params.record_options, { qweb: this.qweb });
- this.column_options = _.extend({}, params.column_options, { qweb: this.qweb });
+ this.recordOptions = _.extend({}, params.record_options, { qweb: this.qweb });
+ this.columnOptions = _.extend({}, params.column_options, { qweb: this.qweb });
},
- update: function (state, fields) {
- this.fields = fields;
- return this._super(state);
+
+ //--------------------------------------------------------------------------
+ // Public
+ //--------------------------------------------------------------------------
+
+ /**
+ * Displays the quick create record in the first column.
+ */
+ addQuickCreate: function () {
+ this.widgets[0].addQuickCreate();
+ },
+ /**
+ * Removes a widget (record if ungrouped, column if grouped) from the view.
+ *
+ * @param {Widget} widget the instance of the widget to remove
+ */
+ removeWidget: function (widget) {
+ this.widgets.splice(this.widgets.indexOf(widget), 1);
+ widget.destroy();
+ },
+ /**
+ * Updates a given column with its new state.
+ *
+ * @param {string} localID the column id
+ * @param {Object} columnState
+ *
+ * @returns {Deferred}
+ */
+ updateColumn: function (localID, columnState) {
+ var column = _.findWhere(this.widgets, {db_id: localID});
+ this.widgets.splice(_.indexOf(this.widgets, column), 1); // remove column from widgets' list
+ var newColumn = new KanbanColumn(this, columnState, this.columnOptions, this.recordOptions);
+ this.widgets.push(newColumn);
+ return newColumn.insertAfter(column.$el).then(column.destroy.bind(column));
},
- update_record: function (record_state) {
- var is_grouped = !!this.state.groupedBy.length;
+ /**
+ * Updates a given record with its new state.
+ *
+ * @param {Object} recordState
+ */
+ updateRecord: function (recordState) {
+ var isGrouped = !!this.state.groupedBy.length;
var record;
- if (is_grouped) {
- // if grouped, this.widgets are kanban columns
- // so we need to find the kanban record inside
+ if (isGrouped) {
+ // if grouped, this.widgets are kanban columns so we need to find
+ // the kanban record inside
_.each(this.widgets, function (widget) {
- record = record || _.findWhere(widget.records, {db_id: record_state.id});
+ record = record || _.findWhere(widget.records, {
+ db_id: recordState.id,
+ });
});
} else {
- record = _.findWhere(this.widgets, {db_id: record_state.id});
+ record = _.findWhere(this.widgets, {db_id: recordState.id});
}
if (record) {
- record.update(record_state);
+ record.update(recordState);
}
},
- update_column: function (column_db_id, data) {
- var column = _.findWhere(this.widgets, {db_id: column_db_id});
- this.widgets.splice(_.indexOf(this.widgets, column), 1); // remove column from widgets' list
- var new_column = new KanbanColumn(this, data, this.column_options, this.record_options);
- this.widgets.push(new_column);
- return new_column.insertAfter(column.$el).then(column.destroy.bind(column));
- },
- _renderView: function () {
- var is_grouped = !!this.state.groupedBy.length;
- this.$el.toggleClass('o_kanban_grouped', is_grouped);
- this.$el.toggleClass('o_kanban_ungrouped', !is_grouped);
- this.$el.empty();
- var fragment = document.createDocumentFragment();
- if (is_grouped) {
- this._renderGrouped(fragment);
- } else {
- this._render_ungrouped(fragment);
- }
- this.$el.append(fragment);
- return this._super.apply(this, arguments);
- },
- _render_ungrouped: function (fragment) {
- var self = this;
- _.each(this.state.data, function (record) {
- var kanban_record = new KanbanRecord(self, record, self.record_options);
- self.widgets.push(kanban_record);
- kanban_record.appendTo(fragment);
- });
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
- // append ghost divs to ensure that all kanban records are left aligned
- this._appendGhostDivs(fragment, 6);
- },
/**
- * Appends empty invisible divs to a document fragment.
+ * Renders empty invisible divs in a document fragment.
*
+ * @private
* @param {DocumentFragment} fragment
* @param {integer} nbDivs the number of divs to append
*/
- _appendGhostDivs: function (fragment, nbDivs) {
+ _renderGhostDivs: function (fragment, nbDivs) {
for (var $ghost, i = 0; i < nbDivs; i++) {
$ghost = $('<div>').addClass('o_kanban_record o_kanban_ghost');
$ghost.appendTo(fragment);
}
},
+ /**
+ * Renders an grouped kanban view in a fragment.
+ *
+ * @private
+ * @param {DocumentFragment} fragment
+ */
_renderGrouped: function (fragment) {
var self = this;
- var group_by_field_attrs = this.state.fields[this.state.groupedBy[0]];
+ var groupByFieldAttrs = this.state.fields[this.state.groupedBy[0]];
// Deactivate the drag'n'drop if the groupedBy field:
// - is a date or datetime since we group by month or
// - is readonly
var draggable = true;
- if (group_by_field_attrs) {
- if (group_by_field_attrs.type === "date" || group_by_field_attrs.type === "datetime") {
+ if (groupByFieldAttrs) {
+ if (groupByFieldAttrs.type === "date" || groupByFieldAttrs.type === "datetime") {
draggable = false;
- } else if (group_by_field_attrs.readonly !== undefined) {
- draggable = !(group_by_field_attrs.readonly);
+ } else if (groupByFieldAttrs.readonly !== undefined) {
+ draggable = !(groupByFieldAttrs.readonly);
}
}
- var grouped_by_m2o = group_by_field_attrs && (group_by_field_attrs.type === 'many2one');
- var grouped_by_field = grouped_by_m2o && group_by_field_attrs.relation;
- this.column_options = _.extend(this.column_options, {
+ var groupedByM2O = groupByFieldAttrs && (groupByFieldAttrs.type === 'many2one');
+ var grouped_by_field = groupedByM2O && groupByFieldAttrs.relation;
+ this.columnOptions = _.extend(this.columnOptions, {
draggable: draggable,
- grouped_by_m2o: grouped_by_m2o,
+ grouped_by_m2o: groupedByM2O,
relation: grouped_by_field,
});
// Render columns
_.each(this.state.data, function (group) {
- var column = new KanbanColumn(self, group, self.column_options, self.record_options);
+ var column = new KanbanColumn(self, group, self.columnOptions, self.recordOptions);
if (!group.value) {
column.prependTo(fragment); // display the 'Undefined' group first
self.widgets.unshift(column);
@@ -247,18 +267,49 @@ return BasicRenderer.extend({
});
// Column quick create
- if (this.column_options.group_creatable && grouped_by_m2o) {
- this.column_quick_create = new ColumnQuickCreate(this);
- this.column_quick_create.appendTo(fragment);
+ if (this.columnOptions.group_creatable && groupedByM2O) {
+ var quickCreate = new ColumnQuickCreate(this);
+ quickCreate.appendTo(fragment);
}
},
- add_quick_create: function () {
- this.widgets[0].add_quick_create();
+ /**
+ * Renders an ungrouped kanban view in a fragment.
+ *
+ * @private
+ * @param {DocumentFragment} fragment
+ */
+ _renderUngrouped: function (fragment) {
+ var self = this;
+ _.each(this.state.data, function (record) {
+ var kanbanRecord = new KanbanRecord(self, record, self.recordOptions);
+ self.widgets.push(kanbanRecord);
+ kanbanRecord.appendTo(fragment);
+ });
+
+ // append ghost divs to ensure that all kanban records are left aligned
+ this._renderGhostDivs(fragment, 6);
+ },
+ /**
+ * @override
+ * @private
+ */
+ _renderView: function () {
+ var isGrouped = !!this.state.groupedBy.length;
+ this.$el.toggleClass('o_kanban_grouped', isGrouped);
+ this.$el.toggleClass('o_kanban_ungrouped', !isGrouped);
+ this.$el.empty();
+
+ var fragment = document.createDocumentFragment();
+ if (isGrouped) {
+ this._renderGrouped(fragment);
+ } else {
+ this._renderUngrouped(fragment);
+ }
+ this.$el.append(fragment);
+ return this._super.apply(this, arguments);
},
- remove_widget: function (widget) {
- this.widgets.splice(this.widgets.indexOf(widget), 1);
- widget.destroy();
- }
});
+return KanbanRenderer;
+
});