parent
e7b1ce31cc
commit
7106ffbe20
|
@ -49,6 +49,7 @@
|
|||
action.pyson_context || '{}');
|
||||
ctx = jQuery.extend(ctx, params.context);
|
||||
ctx = jQuery.extend(ctx, context);
|
||||
params.context = jQuery.extend(params.context, context);
|
||||
|
||||
var domain_context = jQuery.extend({}, ctx);
|
||||
domain_context.context = ctx;
|
||||
|
|
|
@ -186,6 +186,25 @@
|
|||
});
|
||||
Sao.common.MODELACCESS = new Sao.common.ModelAccess();
|
||||
|
||||
Sao.common.ModelHistory = Sao.class_(Object, {
|
||||
init: function() {
|
||||
this._models = [];
|
||||
},
|
||||
load_history: function() {
|
||||
this._models = [];
|
||||
return Sao.rpc({
|
||||
'method': 'model.ir.model.list_history',
|
||||
'params': [{}]
|
||||
}, Sao.Session.current_session).then(function(models) {
|
||||
this._models = models;
|
||||
}.bind(this));
|
||||
},
|
||||
contains: function(model) {
|
||||
return ~this._models.indexOf(model);
|
||||
}
|
||||
});
|
||||
Sao.common.MODELHISTORY = new Sao.common.ModelHistory();
|
||||
|
||||
Sao.common.humanize = function(size) {
|
||||
var sizes = ['bytes', 'KB', 'MB', 'GB', 'TB', 'PB'];
|
||||
for (var i =0, len = sizes.length; i < len; i++) {
|
||||
|
|
26
src/model.js
26
src/model.js
|
@ -81,9 +81,23 @@
|
|||
array.parent_datetime_field = undefined;
|
||||
array.record_removed = [];
|
||||
array.record_deleted = [];
|
||||
array.__readonly = false;
|
||||
array.skip_model_access = false;
|
||||
array.forEach(function(e, i, a) {
|
||||
e.group = a;
|
||||
});
|
||||
array.get_readonly = function() {
|
||||
// Must skip res.user for Preference windows
|
||||
if (this.context._datetime ||
|
||||
(!Sao.common.MODELACCESS.get(this.model.name).write &&
|
||||
!this.skip_model_access)) {
|
||||
return true;
|
||||
}
|
||||
return this.__readonly;
|
||||
};
|
||||
array.set_readonly = function(value) {
|
||||
this.__readonly = value;
|
||||
};
|
||||
array.load = function(ids, modified) {
|
||||
var new_records = [];
|
||||
var i, len;
|
||||
|
@ -869,7 +883,7 @@
|
|||
method: 'model.ir.attachment.search_count',
|
||||
params: [
|
||||
[['resource', '=', this.model.name + ',' + this.id]],
|
||||
{}]
|
||||
this.get_context()]
|
||||
}, this.model.session);
|
||||
} else {
|
||||
prm.resolve(this.attachment_count);
|
||||
|
@ -1044,15 +1058,19 @@
|
|||
this.description[state];
|
||||
}
|
||||
}.bind(this));
|
||||
// TODO group readonly
|
||||
// TODO domain readonly
|
||||
if (record.group.get_readonly() ||
|
||||
this.get_state_attrs(record).domain_readonly) {
|
||||
this.get_state_attrs(record).readonly = true;
|
||||
}
|
||||
},
|
||||
get_state_attrs: function(record) {
|
||||
if (!(this.name in record.state_attrs)) {
|
||||
record.state_attrs[this.name] = jQuery.extend(
|
||||
{}, this.description);
|
||||
}
|
||||
// TODO group readonly
|
||||
if (record.group.get_readonly() || record.readonly) {
|
||||
record.state_attrs[this.name].readonly = true;
|
||||
}
|
||||
return record.state_attrs[this.name];
|
||||
},
|
||||
check_required: function(record) {
|
||||
|
|
|
@ -168,6 +168,7 @@ var Sao = {};
|
|||
// TODO view_search
|
||||
deferreds.push(Sao.common.MODELACCESS.load_models());
|
||||
deferreds.push(Sao.common.ICONFACTORY.load_icons());
|
||||
deferreds.push(Sao.common.MODELHISTORY.load_history());
|
||||
jQuery.when.apply(jQuery, deferreds).then(function() {
|
||||
Sao.menu(preferences);
|
||||
Sao.user_menu(preferences);
|
||||
|
|
75
src/tab.js
75
src/tab.js
|
@ -13,8 +13,8 @@
|
|||
'class': this.class_
|
||||
});
|
||||
|
||||
var title = this.make_title_bar();
|
||||
this.el.append(title);
|
||||
this.title = this.make_title_bar();
|
||||
this.el.append(this.title);
|
||||
|
||||
var toolbar = this.create_toolbar();
|
||||
this.el.append(toolbar);
|
||||
|
@ -65,6 +65,9 @@
|
|||
var icon = definition[0];
|
||||
var name = definition[1];
|
||||
var func = definition[2];
|
||||
if (!func) {
|
||||
return;
|
||||
}
|
||||
var item = jQuery('<li/>').append(
|
||||
jQuery('<a/>').append(jQuery('<span/>', {
|
||||
'class': 'ui-icon ' + icon
|
||||
|
@ -190,6 +193,13 @@
|
|||
this.attributes = jQuery.extend({}, attributes);
|
||||
this.name = attributes.name; // XXX use screen current view title
|
||||
|
||||
if (!Sao.common.MODELHISTORY.contains(model_name)) {
|
||||
this.menu_def = jQuery.extend([], this.menu_def);
|
||||
this.menu_def[10] = jQuery.extend([], this.menu_def[10]);
|
||||
// Remove callback to revision
|
||||
this.menu_def[10][2] = null;
|
||||
}
|
||||
|
||||
this.create_tabcontent();
|
||||
|
||||
var access = Sao.common.MODELACCESS.get(model_name);
|
||||
|
@ -215,6 +225,7 @@
|
|||
screen.search_filter();
|
||||
}
|
||||
}
|
||||
this.update_revision();
|
||||
}.bind(this));
|
||||
},
|
||||
// TODO translate labels
|
||||
|
@ -240,7 +251,8 @@
|
|||
['ui-icon-arrowthick-1-w', 'Previous', 'previous'],
|
||||
['ui-icon-arrowthick-1-e', 'Next', 'next'],
|
||||
['ui-icon-search', 'Search', 'search'],
|
||||
['ui-icon-clock', 'View Logs', 'logs'],
|
||||
['ui-icon-clock', 'View Logs...', 'logs'],
|
||||
['ui-icon-clock', 'Show revisions...', 'revision'],
|
||||
['ui-icon-circle-close', 'Close Tab', 'close'],
|
||||
['ui-icon-pin-w', 'Attachment', 'attach'],
|
||||
['ui-icon-gear', 'Action', 'action'],
|
||||
|
@ -486,6 +498,63 @@
|
|||
Sao.common.message.run(message);
|
||||
}.bind(this));
|
||||
},
|
||||
revision: function() {
|
||||
var current_id = null;
|
||||
if (this.screen.current_record) {
|
||||
current_id = this.screen.current_record.id;
|
||||
}
|
||||
var set_revision = function(revision) {
|
||||
if (revision) {
|
||||
// Add a millisecond as microseconds are truncated
|
||||
revision.setMilliseconds(revision.getMilliseconds() + 1);
|
||||
}
|
||||
if (revision != this.screen.context._datetime) {
|
||||
// Update screen context that will be propagated by
|
||||
// recreating new group
|
||||
this.screen.context._datetime = revision;
|
||||
if (this.screen.current_view.view_type != 'form') {
|
||||
this.screen.search_filter(
|
||||
this.screen.screen_container
|
||||
.search_entry.val());
|
||||
} else {
|
||||
// Test if record exist in revisions
|
||||
this.screen.new_group([current_id]);
|
||||
}
|
||||
this.screen.display();
|
||||
this.update_revision();
|
||||
}
|
||||
}.bind(this);
|
||||
this.modified_save().done(function() {
|
||||
var ids = this.screen.current_view.selected_records().map(
|
||||
function(record) {
|
||||
return record.id;
|
||||
});
|
||||
this.screen.model.execute('history_revisions',
|
||||
[ids], this.screen.context)
|
||||
.then(function(revisions) {
|
||||
new Sao.Window.Revision(revisions, set_revision);
|
||||
});
|
||||
}.bind(this));
|
||||
},
|
||||
update_revision: function() {
|
||||
var revision = this.screen.context._datetime;
|
||||
var label;
|
||||
if (revision) {
|
||||
var date_format = Sao.common.date_format();
|
||||
var time_format = '%H:%M:%S.%f';
|
||||
revision = Sao.common.format_datetime(date_format, time_format,
|
||||
revision);
|
||||
label = this.name + ' @ '+ revision;
|
||||
} else {
|
||||
label = this.name;
|
||||
}
|
||||
this.title.find('button').button({
|
||||
label: label
|
||||
});
|
||||
['new', 'save'].forEach(function(button) {
|
||||
this.buttons[button].prop('disabled', revision);
|
||||
}.bind(this));
|
||||
},
|
||||
attach: function() {
|
||||
var record = this.screen.current_record;
|
||||
if (!record || (record.id < 0)) {
|
||||
|
|
|
@ -76,6 +76,7 @@
|
|||
if (view_type == 'tree') {
|
||||
menu = jQuery('<div/>');
|
||||
var access = Sao.common.MODELACCESS.get(this.screen.model_name);
|
||||
var readonly = this.screen.group.get_readonly();
|
||||
if (this.domain) {
|
||||
this.wid_text = jQuery('<input/>', {
|
||||
type: 'input'
|
||||
|
@ -90,7 +91,7 @@
|
|||
});
|
||||
this.but_add.click(this.add.bind(this));
|
||||
menu.append(this.but_add);
|
||||
this.but_add.prop('disabled', !access.read);
|
||||
this.but_add.prop('disabled', !access.read || readonly);
|
||||
|
||||
this.but_remove = jQuery('<button/>').button({
|
||||
icons: {
|
||||
|
@ -100,7 +101,7 @@
|
|||
});
|
||||
this.but_remove.click(this.remove.bind(this));
|
||||
menu.append(this.but_remove);
|
||||
this.but_remove.prop('disabled', !access.read);
|
||||
this.but_remove.prop('disabled', !access.read || readonly);
|
||||
}
|
||||
|
||||
this.but_new = jQuery('<button/>').button({
|
||||
|
@ -111,7 +112,7 @@
|
|||
});
|
||||
this.but_new.click(this.new_.bind(this));
|
||||
menu.append(this.but_new);
|
||||
this.but_new.prop('disabled', !access.create);
|
||||
this.but_new.prop('disabled', !access.create || readonly);
|
||||
|
||||
this.but_del = jQuery('<button/>').button({
|
||||
icons: {
|
||||
|
@ -121,7 +122,7 @@
|
|||
});
|
||||
this.but_del.click(this.delete_.bind(this));
|
||||
menu.append(this.but_del);
|
||||
this.but_del.prop('disabled', !access['delete']);
|
||||
this.but_del.prop('disabled', !access['delete'] || readonly);
|
||||
|
||||
this.but_undel = jQuery('<button/>').button({
|
||||
icons: {
|
||||
|
@ -131,6 +132,7 @@
|
|||
});
|
||||
this.but_undel.click(this.undelete.bind(this));
|
||||
menu.append(this.but_undel);
|
||||
this.but_undel.prop('disabled', !access['delete'] || readonly);
|
||||
|
||||
this.but_previous = jQuery('<button/>').button({
|
||||
icons: {
|
||||
|
@ -294,12 +296,12 @@
|
|||
init: function(record, callback) {
|
||||
this.resource = record.model.name + ',' + record.id;
|
||||
this.attachment_callback = callback;
|
||||
var context = jQuery.extend({}, record.get_context());
|
||||
context.resource = this.resource;
|
||||
var screen = new Sao.Screen('ir.attachment', {
|
||||
domain: [['resource', '=', this.resource]],
|
||||
mode: ['tree', 'form'],
|
||||
context: {
|
||||
resource: this.resource
|
||||
},
|
||||
context: context,
|
||||
exclude_field: 'resource'
|
||||
});
|
||||
screen.switch_view().done(function() {
|
||||
|
@ -458,7 +460,8 @@
|
|||
this.screen = new Sao.Screen('res.user', {
|
||||
mode: []
|
||||
});
|
||||
// TODO fix readonly from modelaccess
|
||||
this.screen.group.set_readonly(false);
|
||||
this.screen.group.skip_model_access = true;
|
||||
|
||||
var set_view = function(view) {
|
||||
this.screen.add_view(view);
|
||||
|
@ -517,4 +520,65 @@
|
|||
}
|
||||
});
|
||||
|
||||
Sao.Window.Revision = Sao.class_(Object, {
|
||||
init: function(revisions, callback) {
|
||||
this.callback = callback;
|
||||
this.el = jQuery('<div/>');
|
||||
|
||||
var buttons = [];
|
||||
buttons.push({
|
||||
text: 'Cancel', // TODO translate
|
||||
click: function() {
|
||||
this.response('RESPONSE_CANCEL');
|
||||
}.bind(this)
|
||||
});
|
||||
buttons.push({
|
||||
text: 'Ok', // TODO translate
|
||||
click: function() {
|
||||
this.response('RESPONSE_OK');
|
||||
}.bind(this)
|
||||
});
|
||||
|
||||
this.el.dialog({
|
||||
model: true,
|
||||
title: 'Revision', // TODO translate
|
||||
autoOpen: false,
|
||||
buttons: buttons
|
||||
});
|
||||
Sao.common.center_dialog(this.el);
|
||||
|
||||
this.el.append(jQuery('<label/>', {
|
||||
'text': 'Revision:' // TODO translate
|
||||
}));
|
||||
this.select = jQuery('<select/>');
|
||||
var date_format = Sao.common.date_format();
|
||||
var time_format = '%H:%M:%S.%f';
|
||||
this.select.append(jQuery('<option/>', {
|
||||
value: null,
|
||||
text: ''
|
||||
}));
|
||||
revisions.forEach(function(revision) {
|
||||
var name = revision[2];
|
||||
revision = revision[0];
|
||||
this.select.append(jQuery('<option/>', {
|
||||
value: revision.valueOf(),
|
||||
text: Sao.common.format_datetime(
|
||||
date_format, time_format, revision) + ' ' + name
|
||||
}));
|
||||
}.bind(this));
|
||||
this.el.append(this.select);
|
||||
this.el.dialog('open');
|
||||
},
|
||||
response: function(response_id) {
|
||||
var revision = null;
|
||||
if (response_id == 'RESPONSE_OK') {
|
||||
revision = this.select.val();
|
||||
if (revision) {
|
||||
revision = Sao.DateTime(parseInt(revision, 10));
|
||||
}
|
||||
}
|
||||
this.el.dialog('destroy');
|
||||
this.callback(revision);
|
||||
}
|
||||
});
|
||||
}());
|
||||
|
|
Loading…
Reference in New Issue