GRID
This commit is contained in:
727
dist/tryton-sao.js
vendored
727
dist/tryton-sao.js
vendored
@@ -3610,7 +3610,14 @@ var Sao = {
|
||||
};
|
||||
|
||||
Sao.common.parse_datetime = function(datetime_format, value) {
|
||||
var date = moment(value, Sao.common.moment_format(datetime_format));
|
||||
var formats = [
|
||||
Sao.common.moment_format(datetime_format),
|
||||
'YYYY-MM-DDTHH:mm',
|
||||
'YYYY-MM-DDTHH:mm:ss',
|
||||
'YYYY-MM-DD HH:mm',
|
||||
'YYYY-MM-DD HH:mm:ss',
|
||||
];
|
||||
var date = moment(value, formats, true);
|
||||
if (date.isValid()) {
|
||||
date = Sao.DateTime(date.year(), date.month(), date.date(),
|
||||
date.hour(), date.minute(), date.second(),
|
||||
@@ -16797,6 +16804,21 @@ function eval_pyson(value){
|
||||
this.input.appendTo(this.icon);
|
||||
Sao.common.ICONFACTORY.get_icon_img('tryton-date')
|
||||
.appendTo(this.icon);
|
||||
this.icon.on('click', (event_) => {
|
||||
if (this.date.prop('readonly')) {
|
||||
return;
|
||||
}
|
||||
if (event_.target == this.input[0]) {
|
||||
return;
|
||||
}
|
||||
event_.preventDefault();
|
||||
event_.stopPropagation();
|
||||
if (this.input[0].showPicker) {
|
||||
this.input[0].showPicker();
|
||||
} else {
|
||||
this.input.trigger('click');
|
||||
}
|
||||
});
|
||||
}
|
||||
this.date.change(this.focus_out.bind(this));
|
||||
var mousetrap = new Mousetrap(this.date[0]);
|
||||
@@ -16885,7 +16907,7 @@ function eval_pyson(value){
|
||||
Sao.View.Form.DateTime = Sao.class_(Sao.View.Form.Date, {
|
||||
class_: 'form-datetime',
|
||||
_input: 'datetime-local',
|
||||
_input_format: '%Y-%m-%dT%H:%M:%S',
|
||||
_input_format: '%Y-%m-%dT%H:%M',
|
||||
_format: Sao.common.format_datetime,
|
||||
_parse: Sao.common.parse_datetime,
|
||||
get_format: function() {
|
||||
@@ -16910,9 +16932,10 @@ function eval_pyson(value){
|
||||
_parse: Sao.common.parse_time,
|
||||
init: function(view, attributes) {
|
||||
Sao.View.Form.Time._super.init.call(this, view, attributes);
|
||||
if (~navigator.userAgent.indexOf("Firefox")) {
|
||||
// time input on Firefox does not have a pop-up
|
||||
this.input.parent().hide();
|
||||
if (this.icon) {
|
||||
this.input.remove();
|
||||
this.icon.remove();
|
||||
delete this.icon;
|
||||
}
|
||||
},
|
||||
get_format: function() {
|
||||
@@ -18351,6 +18374,7 @@ function eval_pyson(value){
|
||||
view_ids: (attributes.view_ids || '').split(','),
|
||||
views_preload: attributes.views || {},
|
||||
order: attributes.order,
|
||||
one2many: true,
|
||||
row_activate: this.activate.bind(this),
|
||||
exclude_field: attributes.relation_field || null,
|
||||
limit: null,
|
||||
@@ -18577,12 +18601,22 @@ function eval_pyson(value){
|
||||
this.screen.domain = domain;
|
||||
}
|
||||
this.screen.size_limit = size_limit;
|
||||
if (this.attributes.height !== undefined &&
|
||||
this.screen.current_view &&
|
||||
this.screen.current_view.set_embedded_height) {
|
||||
this.screen.current_view.set_embedded_height(
|
||||
this.attributes.height);
|
||||
}
|
||||
this.screen.display();
|
||||
if (this.attributes.height !== undefined) {
|
||||
this.screen.current_view.el
|
||||
.find('.treeview,.list-form').first()
|
||||
.css('min-height', this.attributes.height + 'px')
|
||||
.css('max-height', this.attributes.height + 'px');
|
||||
if (this.screen.current_view.set_embedded_height) {
|
||||
this.screen.current_view.set_embedded_height(
|
||||
this.attributes.height);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
@@ -21981,8 +22015,26 @@ function eval_pyson(value){
|
||||
},
|
||||
_parse_field: function(node, attributes) {
|
||||
var name = attributes.name;
|
||||
var ColumnFactory = Sao.View.TreeXMLViewParser.WIDGETS[
|
||||
attributes.widget];
|
||||
var field = this.view.screen.model.fields[name];
|
||||
var widget = attributes.widget || (field && field.description.type);
|
||||
var column_widget = widget == 'variation' ?
|
||||
(field && field.description.type || 'char') : widget;
|
||||
attributes.widget = widget;
|
||||
var ColumnFactory = Sao.View.TreeXMLViewParser.WIDGETS[column_widget];
|
||||
if (!ColumnFactory) {
|
||||
console.error('[TREE][UNKNOWN_WIDGET]', {
|
||||
viewId: this.view.view_id,
|
||||
model: this.view.screen && this.view.screen.model_name,
|
||||
field: name,
|
||||
widget: column_widget,
|
||||
attributes: attributes,
|
||||
node: node.outerHTML,
|
||||
availableWidgets: Object.keys(
|
||||
Sao.View.TreeXMLViewParser.WIDGETS).sort(),
|
||||
});
|
||||
attributes.widget = 'char';
|
||||
ColumnFactory = Sao.View.Tree.CharColumn;
|
||||
}
|
||||
var column = new ColumnFactory(this.view.screen.model, attributes);
|
||||
if (!this.view.widgets[name]) {
|
||||
this.view.widgets[name] = [];
|
||||
@@ -22022,9 +22074,21 @@ function eval_pyson(value){
|
||||
column.prefixes.push(
|
||||
new Sao.View.Tree.Symbol(attributes, 0));
|
||||
}
|
||||
var field_attrs = this.field_attrs[name] ||
|
||||
(field && field.description) || {};
|
||||
if (!this.field_attrs[name]) {
|
||||
console.warn('[TREE][MISSING_FIELD_ATTRS]', {
|
||||
viewId: this.view.view_id,
|
||||
model: this.view.screen && this.view.screen.model_name,
|
||||
field: name,
|
||||
widget: attributes.widget,
|
||||
attributes: attributes,
|
||||
fallbackFieldAttributes: field_attrs,
|
||||
});
|
||||
}
|
||||
if (!this.view.attributes.sequence &&
|
||||
!this.view.children_field &&
|
||||
this.field_attrs[name].sortable !== false){
|
||||
field_attrs.sortable !== false){
|
||||
column.sortable = true;
|
||||
}
|
||||
this.view.columns.push(column);
|
||||
@@ -22041,6 +22105,18 @@ function eval_pyson(value){
|
||||
'class': 'value',
|
||||
});
|
||||
this.view.sum_widgets.set(column, [sum, aggregate]);
|
||||
if (window.console && this.view instanceof Sao.View.AGGridTree) {
|
||||
console.info('[AGGRID][SUMMARY_SUM_COLUMN_JSON]',
|
||||
JSON.stringify({
|
||||
viewId: this.view.view_id,
|
||||
model: this.view.screen &&
|
||||
this.view.screen.model_name,
|
||||
name: attributes.name || null,
|
||||
label: attributes.string || attributes.name || '',
|
||||
widget: attributes.widget || '',
|
||||
sum: attributes.sum || '',
|
||||
}));
|
||||
}
|
||||
}
|
||||
},
|
||||
_parse_button: function(node, attributes) {
|
||||
@@ -22462,6 +22538,8 @@ function eval_pyson(value){
|
||||
(Sao.View.AGGridTree._next_debug_id || 0) + 1;
|
||||
this._debug_id = Sao.View.AGGridTree._next_debug_id;
|
||||
this.children_field = children_field;
|
||||
this.is_embedded_one2many = Boolean(
|
||||
screen.attributes && screen.attributes.one2many);
|
||||
this.optionals = [];
|
||||
this.sum_widgets = new Map();
|
||||
this.columns = [];
|
||||
@@ -22524,6 +22602,9 @@ function eval_pyson(value){
|
||||
this.toolbar = jQuery('<div/>', {
|
||||
'class': 'ag-grid-tree-toolbar',
|
||||
}).appendTo(this.el);
|
||||
if (this.is_embedded_one2many) {
|
||||
this.el.addClass('ag-grid-tree-embedded-one2many');
|
||||
}
|
||||
this.column_menu = jQuery('<div/>', {
|
||||
'class': 'ag-grid-tree-columns',
|
||||
}).appendTo(this.toolbar);
|
||||
@@ -22610,6 +22691,14 @@ function eval_pyson(value){
|
||||
this._toggle_filter_logic_menu();
|
||||
})
|
||||
.appendTo(this.toolbar);
|
||||
this.import_layout_input = jQuery('<input/>', {
|
||||
'type': 'file',
|
||||
'accept': 'application/json,.json',
|
||||
'class': 'ag-grid-view-import-input',
|
||||
}).hide().appendTo(this.el);
|
||||
this.import_layout_input.on('change', evt => {
|
||||
this._import_layout_from_input(evt.currentTarget);
|
||||
});
|
||||
this.filter_logic_panel = jQuery('<div/>', {
|
||||
'class': 'ag-grid-filter-logic-panel',
|
||||
}).hide().appendTo(jQuery(document.body));
|
||||
@@ -22685,8 +22774,18 @@ function eval_pyson(value){
|
||||
});
|
||||
|
||||
Sao.View.AGGridTree._super.init.call(this, view_id, screen, xml);
|
||||
this._persisted_state = this._load_persisted_state();
|
||||
if (this._persisted_state && this._persisted_state.valueFilters) {
|
||||
if (this.is_embedded_one2many) {
|
||||
this._layout_store = this._normalize_layout_store(null);
|
||||
this._persisted_state = null;
|
||||
this._sao_value_filters = {};
|
||||
this._restored_value_filter_state = null;
|
||||
this._sao_value_filter_restore_guard = false;
|
||||
} else {
|
||||
this._persisted_state = this._load_persisted_state();
|
||||
}
|
||||
if (!this.is_embedded_one2many &&
|
||||
this._persisted_state &&
|
||||
this._persisted_state.valueFilters) {
|
||||
this._apply_sao_value_filter_state(
|
||||
this._persisted_state.valueFilters);
|
||||
}
|
||||
@@ -22967,43 +23066,6 @@ function eval_pyson(value){
|
||||
});
|
||||
},
|
||||
_trace_aggrid_column_resize: function(reason, params, extra) {
|
||||
if (!window.console) {
|
||||
return;
|
||||
}
|
||||
var column_api = this.gridColumnApi || this.gridApi;
|
||||
var column_state = column_api && column_api.getColumnState ?
|
||||
column_api.getColumnState() : [];
|
||||
var target_col_id = null;
|
||||
if (params && params.column) {
|
||||
if (params.column.getColId) {
|
||||
target_col_id = params.column.getColId();
|
||||
} else if (params.column.colId) {
|
||||
target_col_id = params.column.colId;
|
||||
}
|
||||
}
|
||||
console.info('[AGGRID][COLUMN_RESIZE_JSON]',
|
||||
JSON.stringify(jQuery.extend({
|
||||
reason: reason,
|
||||
instanceId: this._debug_id,
|
||||
viewId: this.view_id,
|
||||
model: this.screen && this.screen.model_name,
|
||||
targetColId: target_col_id,
|
||||
finished: params && Object.prototype.hasOwnProperty.call(
|
||||
params, 'finished') ? params.finished : null,
|
||||
source: params && params.source || null,
|
||||
resizeActive: Boolean(this._column_resize_active),
|
||||
activeLayoutId: this._active_layout_id || null,
|
||||
columnWidths: (column_state || [])
|
||||
.filter(state => state && state.colId != '__selection__')
|
||||
.map(state => ({
|
||||
colId: state.colId,
|
||||
width: state.width,
|
||||
minWidth: state.minWidth || null,
|
||||
flex: state.flex || null,
|
||||
})),
|
||||
pendingTimers: this._layout_refresh_timers ?
|
||||
this._layout_refresh_timers.length : 0,
|
||||
}, extra || {})));
|
||||
},
|
||||
_refresh_grid_layout_now: function() {
|
||||
if (!this.gridApi || !this.grid_host || !this.grid_host.length) {
|
||||
@@ -23080,6 +23142,9 @@ function eval_pyson(value){
|
||||
window.addEventListener('resize', this._window_resize_handler);
|
||||
},
|
||||
_persist_grid_state: function(options) {
|
||||
if (this.is_embedded_one2many) {
|
||||
return;
|
||||
}
|
||||
options = options || {};
|
||||
var state = this._capture_grid_state();
|
||||
state.valueFilters = this._merge_restored_value_filter_state(
|
||||
@@ -24050,6 +24115,110 @@ function eval_pyson(value){
|
||||
this._layout_store.defaultPresetId = null;
|
||||
this._apply_layout_state(this._get_standard_layout_state(), null);
|
||||
},
|
||||
_sanitize_layout_file_name: function(name) {
|
||||
name = String(name || Sao.i18n.gettext('AG Grid view')).trim();
|
||||
name = name.replace(/[\\/:*?"<>|]+/g, '-')
|
||||
.replace(/\s+/g, ' ')
|
||||
.trim();
|
||||
return name || 'ag-grid-view';
|
||||
},
|
||||
_get_layout_export_payload: function() {
|
||||
var preset = this._find_layout_preset(this._active_layout_id);
|
||||
var name = preset && !this._layout_dirty ? preset.name :
|
||||
this._get_active_layout_name().replace(/\s+\*$/, '');
|
||||
return {
|
||||
type: 'sao-ag-grid-view',
|
||||
version: 1,
|
||||
model: this.screen && this.screen.model_name || null,
|
||||
viewId: this.view_id || null,
|
||||
name: name || Sao.i18n.gettext('AG Grid view'),
|
||||
exportedAt: new Date().toISOString(),
|
||||
state: this._capture_grid_state(),
|
||||
};
|
||||
},
|
||||
_export_current_layout: function() {
|
||||
var payload = this._get_layout_export_payload();
|
||||
var file_name = this._sanitize_layout_file_name(
|
||||
payload.model + '-' + payload.name) + '.json';
|
||||
Sao.common.download_file(
|
||||
JSON.stringify(payload, null, 2),
|
||||
file_name,
|
||||
{type: 'application/json;charset=utf-8'});
|
||||
},
|
||||
_decode_imported_layout_text: function(data) {
|
||||
if (typeof data == 'string') {
|
||||
return data;
|
||||
}
|
||||
if (data instanceof Uint8Array) {
|
||||
return new TextDecoder('utf-8').decode(data);
|
||||
}
|
||||
return String(data || '');
|
||||
},
|
||||
_import_layout_from_input: function(input) {
|
||||
var file = input && input.files && input.files[0];
|
||||
if (!file) {
|
||||
return;
|
||||
}
|
||||
Sao.common.get_file_data(file, data => {
|
||||
var payload;
|
||||
try {
|
||||
payload = JSON.parse(this._decode_imported_layout_text(data));
|
||||
} catch (error) {
|
||||
Sao.common.warning.run(
|
||||
Sao.i18n.gettext('The selected file is not a valid AG Grid view.'),
|
||||
Sao.i18n.gettext('Import view'));
|
||||
return;
|
||||
}
|
||||
this._import_layout_payload(payload);
|
||||
});
|
||||
},
|
||||
_import_layout_payload: function(payload) {
|
||||
if (!payload || payload.type != 'sao-ag-grid-view' ||
|
||||
!payload.state) {
|
||||
Sao.common.warning.run(
|
||||
Sao.i18n.gettext('The selected file is not a valid AG Grid view.'),
|
||||
Sao.i18n.gettext('Import view'));
|
||||
return;
|
||||
}
|
||||
if (payload.model && payload.model != this.screen.model_name) {
|
||||
Sao.common.warning.run(
|
||||
Sao.i18n.gettext('This view is for another model.') +
|
||||
' ' + payload.model + ' / ' + this.screen.model_name,
|
||||
Sao.i18n.gettext('Import view'));
|
||||
return;
|
||||
}
|
||||
var name = String(payload.name ||
|
||||
Sao.i18n.gettext('Imported view')).trim();
|
||||
if (!name) {
|
||||
name = Sao.i18n.gettext('Imported view');
|
||||
}
|
||||
this._layout_store = this._normalize_layout_store(
|
||||
this._layout_store || {});
|
||||
var existing_names = new Set((this._layout_store.presets || [])
|
||||
.map(preset => preset.name));
|
||||
var base_name = name;
|
||||
var suffix = 2;
|
||||
while (existing_names.has(name)) {
|
||||
name = base_name + ' ' + suffix;
|
||||
suffix += 1;
|
||||
}
|
||||
var now = new Date().toISOString();
|
||||
var preset = {
|
||||
id: this._new_layout_id(),
|
||||
name: name,
|
||||
importedAt: now,
|
||||
updatedAt: now,
|
||||
state: jQuery.extend(true, {}, payload.state),
|
||||
};
|
||||
this._layout_store.presets.push(preset);
|
||||
this._active_layout_id = preset.id;
|
||||
this._layout_dirty = false;
|
||||
this._layout_store.activePresetId = preset.id;
|
||||
this._layout_store.currentState = jQuery.extend(true, {}, preset.state);
|
||||
this._persisted_state = jQuery.extend(true, {}, preset.state);
|
||||
this._save_layout_store();
|
||||
this._apply_layout_state(preset.state, preset.id);
|
||||
},
|
||||
_save_layout_as: function() {
|
||||
var name = window.prompt(Sao.i18n.gettext('View name'));
|
||||
if (!name) {
|
||||
@@ -24271,6 +24440,30 @@ function eval_pyson(value){
|
||||
evt.preventDefault();
|
||||
this._apply_standard_layout_state();
|
||||
}).appendTo(actions);
|
||||
var transfer_actions = jQuery('<div/>', {
|
||||
'class': 'ag-grid-tree-layouts-transfer-actions',
|
||||
}).appendTo(actions);
|
||||
jQuery('<button/>', {
|
||||
'class': 'btn btn-default btn-sm ag-grid-view-transfer-button',
|
||||
'type': 'button',
|
||||
'title': Sao.i18n.gettext('Export view'),
|
||||
'aria-label': Sao.i18n.gettext('Export view'),
|
||||
'text': Sao.i18n.gettext('Export'),
|
||||
}).click(evt => {
|
||||
evt.preventDefault();
|
||||
this._export_current_layout();
|
||||
}).appendTo(transfer_actions);
|
||||
jQuery('<button/>', {
|
||||
'class': 'btn btn-default btn-sm ag-grid-view-transfer-button',
|
||||
'type': 'button',
|
||||
'title': Sao.i18n.gettext('Import view'),
|
||||
'aria-label': Sao.i18n.gettext('Import view'),
|
||||
'text': Sao.i18n.gettext('Import'),
|
||||
}).click(evt => {
|
||||
evt.preventDefault();
|
||||
this.import_layout_input.val(null);
|
||||
this.import_layout_input[0].click();
|
||||
}).appendTo(transfer_actions);
|
||||
},
|
||||
_render_grouping_panel: function() {
|
||||
if (!this.grouping_panel) {
|
||||
@@ -24635,6 +24828,12 @@ function eval_pyson(value){
|
||||
this._sync_selection_header_checkbox();
|
||||
this._update_summary_bar();
|
||||
},
|
||||
onFirstDataRendered: () => {
|
||||
window.requestAnimationFrame(() => this._update_summary_bar());
|
||||
},
|
||||
onRowDataUpdated: () => {
|
||||
window.requestAnimationFrame(() => this._update_summary_bar());
|
||||
},
|
||||
onColumnMoved: this._on_grid_column_layout_changed.bind(this),
|
||||
onColumnPinned: this._on_grid_column_layout_changed.bind(this),
|
||||
onColumnResized: this._on_grid_column_resized.bind(this),
|
||||
@@ -24844,16 +25043,6 @@ function eval_pyson(value){
|
||||
},
|
||||
};
|
||||
|
||||
console.info('[AGGRID][ALIGN_COLUMN]', {
|
||||
colId: name,
|
||||
label: column.attributes.string || '',
|
||||
widget: column.attributes.widget || '',
|
||||
className: column.class_ || '',
|
||||
rightAligned: right_aligned,
|
||||
cellClass: col_def.cellClass,
|
||||
headerClass: col_def.headerClass,
|
||||
});
|
||||
|
||||
column_defs.push(col_def);
|
||||
});
|
||||
return column_defs;
|
||||
@@ -26077,7 +26266,7 @@ function eval_pyson(value){
|
||||
var pair = item.split(':');
|
||||
return pair.length < 2 ? '' :
|
||||
this._normalize_badge_text_key(pair.shift());
|
||||
}).filter(Boolean);
|
||||
}).filter(value => value && value != '*');
|
||||
},
|
||||
_get_record_field_value: function(record, name) {
|
||||
if (!record || !name) {
|
||||
@@ -26169,6 +26358,8 @@ function eval_pyson(value){
|
||||
} else if (Object.prototype.hasOwnProperty.call(
|
||||
mapped, String(normalized_text).toLowerCase())) {
|
||||
color = mapped[String(normalized_text).toLowerCase()];
|
||||
} else if (Object.prototype.hasOwnProperty.call(mapped, '*')) {
|
||||
color = mapped['*'];
|
||||
}
|
||||
if (!color && attributes.badge_color_field) {
|
||||
color = this._get_record_field_value(
|
||||
@@ -26714,7 +26905,7 @@ function eval_pyson(value){
|
||||
}
|
||||
return rows;
|
||||
},
|
||||
_get_summary_badge_columns: function() {
|
||||
_get_displayed_column_map: function() {
|
||||
var visible_columns = {};
|
||||
var column_api = this.gridColumnApi || this.gridApi;
|
||||
if (column_api && column_api.getAllDisplayedColumns) {
|
||||
@@ -26724,37 +26915,336 @@ function eval_pyson(value){
|
||||
}
|
||||
});
|
||||
}
|
||||
return visible_columns;
|
||||
},
|
||||
_get_viewport_column_map: function() {
|
||||
var visible_columns = {};
|
||||
var column_api = this.gridColumnApi || this.gridApi;
|
||||
var columns = null;
|
||||
if (column_api && column_api.getAllDisplayedVirtualColumns) {
|
||||
columns = column_api.getAllDisplayedVirtualColumns();
|
||||
} else if (column_api && column_api.getAllDisplayedColumns) {
|
||||
columns = column_api.getAllDisplayedColumns();
|
||||
}
|
||||
(columns || []).forEach(column => {
|
||||
if (column && column.getColId) {
|
||||
visible_columns[column.getColId()] = true;
|
||||
}
|
||||
});
|
||||
return visible_columns;
|
||||
},
|
||||
_is_summary_column_visible: function(column, visible_columns) {
|
||||
var name = column && column.attributes && column.attributes.name;
|
||||
return name && (!Object.keys(visible_columns).length ||
|
||||
visible_columns[name]);
|
||||
},
|
||||
_get_summary_badge_columns: function() {
|
||||
return this.columns.filter(column => {
|
||||
var name = column.attributes && column.attributes.name;
|
||||
var label = column.attributes &&
|
||||
(column.attributes.string || column.attributes.name) || '';
|
||||
var is_status_column = /(^|[_\s-])(status|state|type)([_\s-]|$)/i
|
||||
.test(String(name || '') + ' ' + String(label || ''));
|
||||
if (!name || (!this._is_badge_column(column) &&
|
||||
!is_status_column)) {
|
||||
return false;
|
||||
}
|
||||
return !Object.keys(visible_columns).length ||
|
||||
visible_columns[name];
|
||||
return name && column.attributes.widget == 'badge';
|
||||
});
|
||||
},
|
||||
_render_summary_item: function(label, value, color) {
|
||||
_get_summary_sum_columns: function() {
|
||||
var columns = [];
|
||||
this.sum_widgets.forEach((sum_widget, column) => {
|
||||
if (column && column.attributes && column.attributes.name) {
|
||||
columns.push(column);
|
||||
}
|
||||
});
|
||||
return columns;
|
||||
},
|
||||
_get_summary_variation_columns: function() {
|
||||
return this.columns.filter(column => {
|
||||
var attributes = column && column.attributes || {};
|
||||
return attributes.name &&
|
||||
attributes.widget == 'variation' &&
|
||||
attributes.variation_summary == '1' &&
|
||||
attributes.variation_previous &&
|
||||
attributes.variation_group_by;
|
||||
});
|
||||
},
|
||||
_render_summary_item: function(
|
||||
label, value, color, class_name, variation_text,
|
||||
variation_class) {
|
||||
var item = jQuery('<div/>', {
|
||||
'class': 'ag-grid-summary-item',
|
||||
'class': 'ag-grid-summary-item' +
|
||||
(class_name ? ' ' + class_name : ''),
|
||||
});
|
||||
jQuery('<span/>', {
|
||||
'class': 'ag-grid-summary-label',
|
||||
'text': label,
|
||||
}).appendTo(item);
|
||||
if (variation_text) {
|
||||
jQuery('<span/>', {
|
||||
'class': 'ag-grid-summary-variation-badge ' +
|
||||
(variation_class || ''),
|
||||
'text': variation_text,
|
||||
}).appendTo(item);
|
||||
}
|
||||
var value_wrap = jQuery('<span/>', {
|
||||
'class': 'ag-grid-summary-value-wrap',
|
||||
}).appendTo(item);
|
||||
var value_el = jQuery('<span/>', {
|
||||
'class': 'ag-grid-summary-value',
|
||||
'text': value,
|
||||
}).appendTo(item);
|
||||
}).appendTo(value_wrap);
|
||||
if (color) {
|
||||
value_el.css('color', color);
|
||||
}
|
||||
return item;
|
||||
},
|
||||
_trace_summary_bar: function(
|
||||
rows, badge_columns, sum_columns, variation_columns, summary_items) {
|
||||
if (!window.console) {
|
||||
return;
|
||||
}
|
||||
var describe = column => ({
|
||||
name: column && column.attributes && column.attributes.name || null,
|
||||
label: column && column.attributes &&
|
||||
(column.attributes.string || column.attributes.name) || '',
|
||||
widget: column && column.attributes && column.attributes.widget || '',
|
||||
sum: column && column.attributes && column.attributes.sum || '',
|
||||
badge: Boolean(column && column.attributes &&
|
||||
column.attributes.widget == 'badge'),
|
||||
});
|
||||
console.info('[AGGRID][SUMMARY_BAR_JSON]', JSON.stringify({
|
||||
instanceId: this._debug_id,
|
||||
viewId: this.view_id,
|
||||
model: this.screen && this.screen.model_name,
|
||||
rowCount: rows.length,
|
||||
viewportColumns: Object.keys(this._get_viewport_column_map()),
|
||||
displayedColumns: Object.keys(this._get_displayed_column_map()),
|
||||
badgeColumns: badge_columns.map(describe),
|
||||
sumColumns: sum_columns.map(describe),
|
||||
variationColumns: variation_columns.map(describe),
|
||||
sumWidgetColumns: Array.from(this.sum_widgets.keys()).map(describe),
|
||||
badgeLikeColumns: this.columns.filter(column =>
|
||||
this._is_badge_column(column)).map(describe),
|
||||
summaryItems: summary_items.map(item => ({
|
||||
label: item.label,
|
||||
count: item.count,
|
||||
className: item.className || '',
|
||||
})),
|
||||
}));
|
||||
},
|
||||
_get_summary_column_load_fields: function(column) {
|
||||
var attributes = column && column.attributes || {};
|
||||
var fields = [];
|
||||
if (attributes.name) {
|
||||
fields.push(attributes.name);
|
||||
}
|
||||
if (attributes.widget == 'variation') {
|
||||
if (attributes.variation_previous) {
|
||||
fields.push(attributes.variation_previous);
|
||||
}
|
||||
if (attributes.variation_group_by) {
|
||||
fields.push(attributes.variation_group_by);
|
||||
}
|
||||
}
|
||||
if (attributes.sum_variation == '1' && attributes.sum_previous) {
|
||||
fields.push(attributes.sum_previous);
|
||||
}
|
||||
return fields.filter((field, index) =>
|
||||
field && fields.indexOf(field) == index);
|
||||
},
|
||||
_load_summary_column_values: function(rows, columns, reason) {
|
||||
if (this._summary_sum_loading) {
|
||||
return null;
|
||||
}
|
||||
var promises = [];
|
||||
var field_names = [];
|
||||
columns.forEach(column => {
|
||||
var names = this._get_summary_column_load_fields(column);
|
||||
field_names = field_names.concat(names);
|
||||
rows.forEach(row => {
|
||||
var record = row && row.__record;
|
||||
names.forEach(name => {
|
||||
if (record && record.id >= 0 &&
|
||||
!record.get_loaded([name])) {
|
||||
promises.push(record.load(name, true, false));
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
if (!promises.length) {
|
||||
return null;
|
||||
}
|
||||
this._summary_sum_loading = true;
|
||||
if (window.console) {
|
||||
console.info('[AGGRID][SUMMARY_SUM_LOAD_JSON]',
|
||||
JSON.stringify({
|
||||
instanceId: this._debug_id,
|
||||
viewId: this.view_id,
|
||||
model: this.screen && this.screen.model_name,
|
||||
reason: reason || 'summary',
|
||||
fields: field_names.filter((field, index) =>
|
||||
field && field_names.indexOf(field) == index),
|
||||
promiseCount: promises.length,
|
||||
}));
|
||||
}
|
||||
return jQuery.when.apply(jQuery, promises).always(() => {
|
||||
this._summary_sum_loading = false;
|
||||
});
|
||||
},
|
||||
_load_summary_sum_values: function(rows, columns) {
|
||||
return this._load_summary_column_values(rows, columns, 'sum');
|
||||
},
|
||||
_load_summary_badge_values: function(rows, columns) {
|
||||
return this._load_summary_column_values(rows, columns, 'badge');
|
||||
},
|
||||
_append_sum_summary_item: function(summary_items, rows, column) {
|
||||
var sum = null;
|
||||
var name = column && column.attributes && column.attributes.name;
|
||||
var field = name ? this.screen.model.fields[name] : null;
|
||||
var previous_sum = null;
|
||||
var previous_name = column && column.attributes &&
|
||||
column.attributes.sum_previous;
|
||||
var with_variation = column && column.attributes &&
|
||||
column.attributes.sum_variation == '1' && previous_name;
|
||||
rows.forEach(row => {
|
||||
var record = row && row.__record;
|
||||
if (!field || !record || record.id >= 0 &&
|
||||
!record.get_loaded([name])) {
|
||||
return;
|
||||
}
|
||||
var value = field.get(record);
|
||||
if (value && value.isTimeDelta) {
|
||||
value = value.asSeconds();
|
||||
}
|
||||
if (value !== null && value !== undefined && value !== '') {
|
||||
sum = sum === null ? value : sum + value;
|
||||
}
|
||||
if (with_variation) {
|
||||
var previous = this._get_record_raw_field_value(
|
||||
record, previous_name);
|
||||
if (previous !== null && previous !== undefined &&
|
||||
previous !== '') {
|
||||
previous = Number(previous);
|
||||
if (isFinite(previous)) {
|
||||
previous_sum = previous_sum === null ?
|
||||
previous : previous_sum + previous;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
var variation = null;
|
||||
if (with_variation && sum !== null && previous_sum !== null &&
|
||||
previous_sum !== 0) {
|
||||
variation = ((sum - previous_sum) /
|
||||
Math.abs(previous_sum)) * 100;
|
||||
}
|
||||
summary_items.push({
|
||||
label: column.attributes.string || column.attributes.name,
|
||||
count: sum === null ? '-' :
|
||||
this._format_aggregate_value(column, sum),
|
||||
color: '#111111',
|
||||
className: 'ag-grid-summary-item-sum',
|
||||
variationText: variation === null ? '' :
|
||||
this._format_sum_variation_percent(variation),
|
||||
variationClass: variation === null ? '' :
|
||||
(variation < 0 ? 'ag-grid-summary-variation-negative' :
|
||||
'ag-grid-summary-variation-positive'),
|
||||
});
|
||||
},
|
||||
_get_record_raw_field_value: function(record, name) {
|
||||
if (!record || !name) {
|
||||
return null;
|
||||
}
|
||||
var field = this.screen.model.fields[name];
|
||||
if (!field || record.id >= 0 && !record.get_loaded([name])) {
|
||||
return null;
|
||||
}
|
||||
var value = field.get(record);
|
||||
if (value && value.isTimeDelta) {
|
||||
value = value.asSeconds();
|
||||
}
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return null;
|
||||
}
|
||||
return value;
|
||||
},
|
||||
_get_record_text_field_value: function(record, name) {
|
||||
if (!record || !name) {
|
||||
return '';
|
||||
}
|
||||
var field = this.screen.model.fields[name];
|
||||
if (!field || record.id >= 0 && !record.get_loaded([name])) {
|
||||
return '';
|
||||
}
|
||||
try {
|
||||
return field.get_client(record);
|
||||
} catch (error) {
|
||||
var value = this._get_record_raw_field_value(record, name);
|
||||
return value === null || value === undefined ? '' : String(value);
|
||||
}
|
||||
},
|
||||
_format_variation_percent: function(value) {
|
||||
var locale = Sao.i18n.BC47(Sao.i18n.getlang());
|
||||
var sign = value > 0 ? '+' : '';
|
||||
return sign + value.toLocaleString(locale, {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
}) + '%';
|
||||
},
|
||||
_format_sum_variation_percent: function(value) {
|
||||
var locale = Sao.i18n.BC47(Sao.i18n.getlang());
|
||||
var sign = value >= 0 ? '+' : '';
|
||||
return sign + value.toLocaleString(locale, {
|
||||
minimumFractionDigits: 0,
|
||||
maximumFractionDigits: 2,
|
||||
}) + '%';
|
||||
},
|
||||
_append_variation_summary_items: function(summary_items, rows, column) {
|
||||
var attributes = column && column.attributes || {};
|
||||
var current_name = attributes.name;
|
||||
var previous_name = attributes.variation_previous;
|
||||
var group_name = attributes.variation_group_by;
|
||||
var groups = {};
|
||||
rows.forEach(row => {
|
||||
var record = row && row.__record;
|
||||
if (!record) {
|
||||
return;
|
||||
}
|
||||
var current = Number(this._get_record_raw_field_value(
|
||||
record, current_name));
|
||||
var previous = Number(this._get_record_raw_field_value(
|
||||
record, previous_name));
|
||||
var group = this._get_record_text_field_value(
|
||||
record, group_name) || Sao.i18n.gettext('(Empty)');
|
||||
if (!isFinite(current) || !isFinite(previous) || previous === 0) {
|
||||
return;
|
||||
}
|
||||
if (!groups[group]) {
|
||||
groups[group] = {
|
||||
current: 0,
|
||||
previous: 0,
|
||||
};
|
||||
}
|
||||
groups[group].current += current;
|
||||
groups[group].previous += previous;
|
||||
});
|
||||
Object.keys(groups).sort((a, b) => String(a).localeCompare(
|
||||
String(b), undefined, {numeric: true, sensitivity: 'base'}))
|
||||
.forEach(group => {
|
||||
var values = groups[group];
|
||||
if (!values.previous) {
|
||||
return;
|
||||
}
|
||||
var variation = ((values.current - values.previous) /
|
||||
Math.abs(values.previous)) * 100;
|
||||
summary_items.push({
|
||||
label: group,
|
||||
count: this._format_variation_percent(variation),
|
||||
color: variation > 0 ? '#16a34a' :
|
||||
variation < 0 ? '#dc2626' : '#64748b',
|
||||
className: 'ag-grid-summary-item-variation' +
|
||||
(variation > 0 ? ' ag-grid-summary-variation-up' :
|
||||
variation < 0 ?
|
||||
' ag-grid-summary-variation-down' :
|
||||
' ag-grid-summary-variation-flat'),
|
||||
});
|
||||
});
|
||||
},
|
||||
_get_default_badge_summary_color: function(value) {
|
||||
var key = String(value || '').toLowerCase();
|
||||
var palette = {
|
||||
@@ -26785,8 +27275,16 @@ function eval_pyson(value){
|
||||
var order = [];
|
||||
var empty = Sao.i18n.gettext('(Empty)');
|
||||
rows.forEach(row => {
|
||||
var value = row[name] ?
|
||||
this._normalize_badge_text_key(row[name]) : empty;
|
||||
var raw_value = '';
|
||||
if (column && row && row.__record) {
|
||||
raw_value = this._get_column_text_value(
|
||||
column, row.__record);
|
||||
}
|
||||
if (!raw_value && row) {
|
||||
raw_value = row[name];
|
||||
}
|
||||
var value = raw_value ?
|
||||
this._normalize_badge_text_key(raw_value) : empty;
|
||||
if (value == empty) {
|
||||
return;
|
||||
}
|
||||
@@ -26836,27 +27334,6 @@ function eval_pyson(value){
|
||||
});
|
||||
return Boolean(order.length);
|
||||
},
|
||||
_get_summary_status_sources_from_grid: function() {
|
||||
var sources = [];
|
||||
var seen = {};
|
||||
(this._grid_columns || []).forEach(col_def => {
|
||||
var name = col_def && col_def.field || col_def && col_def.colId;
|
||||
if (!name || name == '__selection__' || seen[name]) {
|
||||
return;
|
||||
}
|
||||
var label = col_def.headerName || name;
|
||||
if (!/(status|state|type|shipping|shipment|open\/physic)/i
|
||||
.test(String(name) + ' ' + String(label))) {
|
||||
return;
|
||||
}
|
||||
seen[name] = true;
|
||||
sources.push({
|
||||
name: name,
|
||||
label: label,
|
||||
});
|
||||
});
|
||||
return sources;
|
||||
},
|
||||
_update_summary_bar: function() {
|
||||
if (!this.summary_bar || !this.summary_bar.length) {
|
||||
return;
|
||||
@@ -26869,25 +27346,38 @@ function eval_pyson(value){
|
||||
rows.length.toLocaleString(locale),
|
||||
'#145369'));
|
||||
var summary_items = [];
|
||||
var summarized_names = {};
|
||||
this._get_summary_badge_columns().forEach(column => {
|
||||
if (this._append_badge_summary_items(
|
||||
summary_items, rows, column)) {
|
||||
summarized_names[column.attributes.name] = true;
|
||||
}
|
||||
});
|
||||
this._get_summary_status_sources_from_grid().forEach(source => {
|
||||
if (summarized_names[source.name]) {
|
||||
return;
|
||||
}
|
||||
var sum_columns = this._get_summary_sum_columns();
|
||||
var badge_columns = this._get_summary_badge_columns();
|
||||
var variation_columns = this._get_summary_variation_columns();
|
||||
var summary_load = this._load_summary_column_values(
|
||||
rows, badge_columns.concat(sum_columns, variation_columns),
|
||||
'summary');
|
||||
if (summary_load) {
|
||||
summary_load.then(() => this._update_summary_bar());
|
||||
}
|
||||
badge_columns.forEach(column => {
|
||||
this._append_badge_summary_items(
|
||||
summary_items, rows, null, source);
|
||||
summary_items, rows, column);
|
||||
});
|
||||
sum_columns.forEach(column => {
|
||||
this._append_sum_summary_item(summary_items, rows, column);
|
||||
});
|
||||
variation_columns.forEach(column => {
|
||||
this._append_variation_summary_items(
|
||||
summary_items, rows, column);
|
||||
});
|
||||
this._trace_summary_bar(
|
||||
rows, badge_columns, sum_columns, variation_columns,
|
||||
summary_items);
|
||||
summary_items.forEach(item => {
|
||||
this.summary_bar.append(this._render_summary_item(
|
||||
item.label,
|
||||
item.count.toLocaleString(locale),
|
||||
item.color));
|
||||
typeof item.count == 'number' ?
|
||||
item.count.toLocaleString(locale) : item.count,
|
||||
item.color,
|
||||
item.className,
|
||||
item.variationText,
|
||||
item.variationClass));
|
||||
});
|
||||
},
|
||||
on_copy: function() {
|
||||
@@ -27052,7 +27542,10 @@ function eval_pyson(value){
|
||||
var readable_min_height = 420;
|
||||
var maximum_height = 720;
|
||||
var height;
|
||||
if (available >= compact_min_height) {
|
||||
if (this.is_embedded_one2many && this._embedded_height) {
|
||||
height = Math.max(80, this._embedded_height - toolbar_height -
|
||||
summary_height - external_scroll_height);
|
||||
} else if (available >= compact_min_height) {
|
||||
height = Math.max(
|
||||
compact_min_height,
|
||||
Math.min(maximum_height, available));
|
||||
@@ -27104,6 +27597,17 @@ function eval_pyson(value){
|
||||
});
|
||||
}
|
||||
},
|
||||
set_embedded_height: function(height) {
|
||||
height = parseInt(height, 10);
|
||||
if (!this.is_embedded_one2many || isNaN(height) || height <= 0) {
|
||||
return;
|
||||
}
|
||||
this._embedded_height = height;
|
||||
this._resize_grid_host();
|
||||
if (this.gridApi && this.gridApi.doLayout) {
|
||||
this.gridApi.doLayout();
|
||||
}
|
||||
},
|
||||
_refresh_grid_layout_after_row_data: function(row_data) {
|
||||
if (!this.gridApi) {
|
||||
return;
|
||||
@@ -27319,7 +27823,7 @@ function eval_pyson(value){
|
||||
} else if (diagnostics.relationWidget) {
|
||||
diagnostics.fallbackReason = diagnostics.relationWidget +
|
||||
'_relation_widget';
|
||||
} else if (diagnostics.embeddedContext) {
|
||||
} else if (diagnostics.embeddedContext && diagnostics.editable) {
|
||||
diagnostics.fallbackReason = 'embedded_relation_tree';
|
||||
} else if (diagnostics.editable) {
|
||||
diagnostics.fallbackReason = 'editable_view';
|
||||
@@ -30481,6 +30985,7 @@ function eval_pyson(value){
|
||||
'timedelta': Sao.View.Tree.TimeDeltaColumn,
|
||||
'tolerance_gauge': Sao.View.Tree.ToleranceGauge,
|
||||
'url': Sao.View.Tree.URLColumn,
|
||||
'variation': Sao.View.Tree.CharColumn,
|
||||
};
|
||||
|
||||
Sao.View.EditableTree = {};
|
||||
|
||||
192
tryton-sao.css
192
tryton-sao.css
@@ -9691,20 +9691,20 @@ img.icon {
|
||||
margin: 0 0 5px;
|
||||
}
|
||||
.ag-grid-tree-toolbar > .ag-grid-screen-filter-toggle-bar {
|
||||
margin: 0 10px 0 auto;
|
||||
margin: 0 4px 0 auto;
|
||||
}
|
||||
.ag-grid-screen-filter-toggle {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 7px;
|
||||
min-height: 30px;
|
||||
padding: 4px 10px;
|
||||
border: 1px solid #d6e4df;
|
||||
border-radius: 8px;
|
||||
background: linear-gradient(180deg, #f6fbf9 0%, #edf5f1 100%);
|
||||
gap: 5px;
|
||||
min-height: 26px;
|
||||
padding: 2px 7px;
|
||||
border: 1px solid #d8e2df;
|
||||
border-radius: 6px;
|
||||
background: #ffffff;
|
||||
color: #355154;
|
||||
box-shadow: 0 2px 7px rgba(53, 81, 84, 0.1);
|
||||
font-size: 12px;
|
||||
box-shadow: none;
|
||||
font-size: 11.5px;
|
||||
font-weight: 600;
|
||||
line-height: 1.2;
|
||||
text-transform: none !important;
|
||||
@@ -9713,18 +9713,18 @@ img.icon {
|
||||
}
|
||||
.ag-grid-screen-filter-toggle:hover,
|
||||
.ag-grid-screen-filter-toggle:focus {
|
||||
background: linear-gradient(180deg, #f2faf7 0%, #e7f2ed 100%);
|
||||
background: #f6faf8;
|
||||
border-color: #bfd5cd;
|
||||
color: #28484b;
|
||||
box-shadow: 0 3px 9px rgba(53, 81, 84, 0.13);
|
||||
box-shadow: 0 1px 1px rgba(53, 81, 84, 0.05);
|
||||
}
|
||||
.ag-grid-screen-filter-toggle:active {
|
||||
transform: translateY(1px);
|
||||
box-shadow: 0 1px 5px rgba(53, 81, 84, 0.1);
|
||||
box-shadow: none;
|
||||
}
|
||||
.ag-grid-screen-filter-toggle .icon {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
opacity: 0.78;
|
||||
}
|
||||
@media screen and (max-width: 991px) {
|
||||
@@ -11122,24 +11122,26 @@ html[theme="default"] .screen-container .nav-tabs > li.active > a:hover {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
gap: 12px;
|
||||
padding: 6px 0;
|
||||
gap: 5px;
|
||||
min-height: 32px;
|
||||
padding: 2px 0 4px;
|
||||
}
|
||||
|
||||
.ag-grid-tree-columns > .btn,
|
||||
.ag-grid-tree-grouping > .btn,
|
||||
.ag-grid-tree-layouts > .btn,
|
||||
.ag-grid-value-filter-mode {
|
||||
.ag-grid-value-filter-mode,
|
||||
.ag-grid-view-transfer-button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
min-height: 34px;
|
||||
padding: 6px 12px;
|
||||
border: 1px solid #d6e4df;
|
||||
border-radius: 8px;
|
||||
background: linear-gradient(180deg, #f6fbf9 0%, #edf5f1 100%);
|
||||
gap: 5px;
|
||||
min-height: 27px;
|
||||
padding: 3px 8px;
|
||||
border: 1px solid #d8e2df;
|
||||
border-radius: 6px;
|
||||
background: #ffffff;
|
||||
color: #355154;
|
||||
box-shadow: 0 3px 10px rgba(53, 81, 84, 0.12);
|
||||
box-shadow: none;
|
||||
text-transform: none !important;
|
||||
transition: background-color 0.18s ease, border-color 0.18s ease,
|
||||
box-shadow 0.18s ease, transform 0.18s ease;
|
||||
@@ -11149,20 +11151,23 @@ html[theme="default"] .screen-container .nav-tabs > li.active > a:hover {
|
||||
.ag-grid-tree-grouping > .btn:hover,
|
||||
.ag-grid-tree-layouts > .btn:hover,
|
||||
.ag-grid-value-filter-mode:hover,
|
||||
.ag-grid-view-transfer-button:hover,
|
||||
.ag-grid-tree-columns > .btn:focus,
|
||||
.ag-grid-tree-grouping > .btn:focus,
|
||||
.ag-grid-tree-layouts > .btn:focus,
|
||||
.ag-grid-value-filter-mode:focus {
|
||||
.ag-grid-value-filter-mode:focus,
|
||||
.ag-grid-view-transfer-button:focus {
|
||||
background: linear-gradient(180deg, #f2faf7 0%, #e7f2ed 100%);
|
||||
border-color: #bfd5cd;
|
||||
color: #28484b;
|
||||
box-shadow: 0 5px 14px rgba(53, 81, 84, 0.16);
|
||||
box-shadow: 0 1px 1px rgba(53, 81, 84, 0.05);
|
||||
}
|
||||
|
||||
.ag-grid-tree-columns > .btn:active,
|
||||
.ag-grid-tree-grouping > .btn:active,
|
||||
.ag-grid-tree-layouts > .btn:active,
|
||||
.ag-grid-value-filter-mode:active {
|
||||
.ag-grid-value-filter-mode:active,
|
||||
.ag-grid-view-transfer-button:active {
|
||||
transform: translateY(1px);
|
||||
box-shadow: 0 2px 8px rgba(53, 81, 84, 0.12);
|
||||
}
|
||||
@@ -11171,18 +11176,30 @@ html[theme="default"] .screen-container .nav-tabs > li.active > a:hover {
|
||||
.ag-grid-tree-grouping-label,
|
||||
.ag-grid-tree-layouts-label,
|
||||
.ag-grid-value-filter-mode-label {
|
||||
font-size: 12px;
|
||||
font-size: 11.5px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.01em;
|
||||
letter-spacing: 0;
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
.ag-grid-value-filter-mode.active {
|
||||
background: linear-gradient(180deg, #e0f4f1 0%, #cbe9e3 100%);
|
||||
background: #f2faf8;
|
||||
border-color: #8fc3bd;
|
||||
color: #0f6f6d;
|
||||
}
|
||||
|
||||
.ag-grid-view-transfer-button {
|
||||
font-size: 11.5px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.ag-grid-tree-layouts-transfer-actions {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.ag-grid-tree-grouping-panel .btn,
|
||||
.ag-grid-tree-layouts-panel .btn,
|
||||
.ag-grid-filter-logic-panel .btn {
|
||||
@@ -11289,7 +11306,7 @@ html[theme="default"] .screen-container .nav-tabs > li.active > a:hover {
|
||||
justify-content: center;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
color: #2b8c87;
|
||||
color: #6f8f8b;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
@@ -11308,6 +11325,14 @@ html[theme="default"] .screen-container .nav-tabs > li.active > a:hover {
|
||||
fill: none;
|
||||
}
|
||||
|
||||
.ag-grid-tree-columns > .btn:hover .ag-grid-toolbar-icon,
|
||||
.ag-grid-tree-grouping > .btn:hover .ag-grid-toolbar-icon,
|
||||
.ag-grid-tree-layouts > .btn:hover .ag-grid-toolbar-icon,
|
||||
.ag-grid-value-filter-mode:hover .ag-grid-toolbar-icon,
|
||||
.ag-grid-value-filter-mode.active .ag-grid-toolbar-icon {
|
||||
color: #2b8c87;
|
||||
}
|
||||
|
||||
.ag-grid-tree-grouping-panel {
|
||||
width: 420px;
|
||||
max-width: calc(100vw - 24px);
|
||||
@@ -11637,6 +11662,7 @@ html[theme="default"] .ag-grid-tree-grouping-panel input[type="checkbox"]:after
|
||||
gap: 3px;
|
||||
padding: 8px 18px;
|
||||
border-right: 1px solid #e7efeb;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.ag-grid-summary-item:last-child {
|
||||
@@ -11661,6 +11687,78 @@ html[theme="default"] .ag-grid-tree-grouping-panel input[type="checkbox"]:after
|
||||
line-height: 1.15;
|
||||
}
|
||||
|
||||
.ag-grid-summary-value-wrap {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.ag-grid-summary-variation-badge {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: absolute;
|
||||
top: 7px;
|
||||
right: 10px;
|
||||
min-height: 16px;
|
||||
padding: 0 5px;
|
||||
border-radius: 4px;
|
||||
font-size: 10.5px;
|
||||
font-weight: 800;
|
||||
line-height: 1.1;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.ag-grid-summary-variation-positive {
|
||||
border: none;
|
||||
background: transparent;
|
||||
color: #16a34a;
|
||||
}
|
||||
|
||||
.ag-grid-summary-variation-negative {
|
||||
border: none;
|
||||
background: transparent;
|
||||
color: #dc2626;
|
||||
}
|
||||
|
||||
.ag-grid-summary-item-sum .ag-grid-summary-value {
|
||||
color: #111111;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.ag-grid-summary-item-sum {
|
||||
flex-basis: 180px;
|
||||
min-width: 165px;
|
||||
max-width: 230px;
|
||||
padding-left: 22px;
|
||||
padding-right: 28px;
|
||||
}
|
||||
|
||||
.ag-grid-summary-item-variation {
|
||||
flex-basis: 165px;
|
||||
min-width: 145px;
|
||||
max-width: 220px;
|
||||
background: #fbfdfc;
|
||||
}
|
||||
|
||||
.ag-grid-summary-item-variation .ag-grid-summary-value {
|
||||
font-size: 17px;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.ag-grid-summary-variation-up .ag-grid-summary-value {
|
||||
color: #16a34a;
|
||||
}
|
||||
|
||||
.ag-grid-summary-variation-down .ag-grid-summary-value {
|
||||
color: #dc2626;
|
||||
}
|
||||
|
||||
.ag-grid-summary-variation-flat .ag-grid-summary-value {
|
||||
color: #64748b;
|
||||
}
|
||||
|
||||
.ag-grid-tree-host {
|
||||
flex: 0 0 auto;
|
||||
min-height: 520px;
|
||||
@@ -11790,6 +11888,12 @@ html[theme="default"] .ag-grid-tree-grouping-panel input[type="checkbox"]:after
|
||||
border-right: 1px solid #e3ebe7;
|
||||
}
|
||||
|
||||
.ag-grid-tree-host .ag-header-cell:not([col-id="__selection__"]),
|
||||
.ag-grid-tree-host .ag-cell:not([col-id="__selection__"]) {
|
||||
padding-left: 10px;
|
||||
padding-right: 14px;
|
||||
}
|
||||
|
||||
.ag-grid-tree-host .ag-header-cell:last-child,
|
||||
.ag-grid-tree-host .ag-cell:last-child {
|
||||
border-right: none;
|
||||
@@ -11819,6 +11923,10 @@ html[theme="default"] .ag-grid-tree-grouping-panel input[type="checkbox"]:after
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.ag-grid-tree-host .ag-grid-right-aligned-cell {
|
||||
padding-right: 18px;
|
||||
}
|
||||
|
||||
.ag-grid-tree-host .ag-grid-badge-cell {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -12772,6 +12880,7 @@ html[data-theme-mode="dark"] .screen-container .filter-box .btn,
|
||||
html[data-theme-mode="dark"] .ag-grid-tree-columns > .btn,
|
||||
html[data-theme-mode="dark"] .ag-grid-tree-grouping > .btn,
|
||||
html[data-theme-mode="dark"] .ag-grid-tree-layouts > .btn,
|
||||
html[data-theme-mode="dark"] .ag-grid-view-transfer-button,
|
||||
html[data-theme-mode="dark"] .ag-grid-tree-grouping-panel .btn,
|
||||
html[data-theme-mode="dark"] .ag-grid-tree-layouts-panel .btn,
|
||||
html[data-theme-mode="dark"] .ag-grid-filter-logic-panel .btn {
|
||||
@@ -12787,6 +12896,7 @@ html[data-theme-mode="dark"] .screen-container .filter-box .btn:hover,
|
||||
html[data-theme-mode="dark"] .ag-grid-tree-columns > .btn:hover,
|
||||
html[data-theme-mode="dark"] .ag-grid-tree-grouping > .btn:hover,
|
||||
html[data-theme-mode="dark"] .ag-grid-tree-layouts > .btn:hover,
|
||||
html[data-theme-mode="dark"] .ag-grid-view-transfer-button:hover,
|
||||
html[data-theme-mode="dark"] .ag-grid-tree-grouping-panel .btn:hover,
|
||||
html[data-theme-mode="dark"] .ag-grid-tree-layouts-panel .btn:hover,
|
||||
html[data-theme-mode="dark"] .ag-grid-filter-logic-panel .btn:hover {
|
||||
@@ -12835,6 +12945,26 @@ html[data-theme-mode="dark"] .ag-grid-summary-value {
|
||||
color: #8fe1d8;
|
||||
}
|
||||
|
||||
html[data-theme-mode="dark"] .ag-grid-summary-item-sum .ag-grid-summary-value {
|
||||
color: #111111;
|
||||
}
|
||||
|
||||
html[data-theme-mode="dark"] .ag-grid-summary-item-variation {
|
||||
background: #172321;
|
||||
}
|
||||
|
||||
html[data-theme-mode="dark"] .ag-grid-summary-variation-positive {
|
||||
border-color: transparent;
|
||||
background: transparent;
|
||||
color: #86efac;
|
||||
}
|
||||
|
||||
html[data-theme-mode="dark"] .ag-grid-summary-variation-negative {
|
||||
border-color: transparent;
|
||||
background: transparent;
|
||||
color: #fca5a5;
|
||||
}
|
||||
|
||||
html[data-theme-mode="dark"] .form-tolerance-gauge {
|
||||
color: #dce7e2;
|
||||
}
|
||||
|
||||
727
tryton-sao.js
727
tryton-sao.js
@@ -3610,7 +3610,14 @@ var Sao = {
|
||||
};
|
||||
|
||||
Sao.common.parse_datetime = function(datetime_format, value) {
|
||||
var date = moment(value, Sao.common.moment_format(datetime_format));
|
||||
var formats = [
|
||||
Sao.common.moment_format(datetime_format),
|
||||
'YYYY-MM-DDTHH:mm',
|
||||
'YYYY-MM-DDTHH:mm:ss',
|
||||
'YYYY-MM-DD HH:mm',
|
||||
'YYYY-MM-DD HH:mm:ss',
|
||||
];
|
||||
var date = moment(value, formats, true);
|
||||
if (date.isValid()) {
|
||||
date = Sao.DateTime(date.year(), date.month(), date.date(),
|
||||
date.hour(), date.minute(), date.second(),
|
||||
@@ -16797,6 +16804,21 @@ function eval_pyson(value){
|
||||
this.input.appendTo(this.icon);
|
||||
Sao.common.ICONFACTORY.get_icon_img('tryton-date')
|
||||
.appendTo(this.icon);
|
||||
this.icon.on('click', (event_) => {
|
||||
if (this.date.prop('readonly')) {
|
||||
return;
|
||||
}
|
||||
if (event_.target == this.input[0]) {
|
||||
return;
|
||||
}
|
||||
event_.preventDefault();
|
||||
event_.stopPropagation();
|
||||
if (this.input[0].showPicker) {
|
||||
this.input[0].showPicker();
|
||||
} else {
|
||||
this.input.trigger('click');
|
||||
}
|
||||
});
|
||||
}
|
||||
this.date.change(this.focus_out.bind(this));
|
||||
var mousetrap = new Mousetrap(this.date[0]);
|
||||
@@ -16885,7 +16907,7 @@ function eval_pyson(value){
|
||||
Sao.View.Form.DateTime = Sao.class_(Sao.View.Form.Date, {
|
||||
class_: 'form-datetime',
|
||||
_input: 'datetime-local',
|
||||
_input_format: '%Y-%m-%dT%H:%M:%S',
|
||||
_input_format: '%Y-%m-%dT%H:%M',
|
||||
_format: Sao.common.format_datetime,
|
||||
_parse: Sao.common.parse_datetime,
|
||||
get_format: function() {
|
||||
@@ -16910,9 +16932,10 @@ function eval_pyson(value){
|
||||
_parse: Sao.common.parse_time,
|
||||
init: function(view, attributes) {
|
||||
Sao.View.Form.Time._super.init.call(this, view, attributes);
|
||||
if (~navigator.userAgent.indexOf("Firefox")) {
|
||||
// time input on Firefox does not have a pop-up
|
||||
this.input.parent().hide();
|
||||
if (this.icon) {
|
||||
this.input.remove();
|
||||
this.icon.remove();
|
||||
delete this.icon;
|
||||
}
|
||||
},
|
||||
get_format: function() {
|
||||
@@ -18351,6 +18374,7 @@ function eval_pyson(value){
|
||||
view_ids: (attributes.view_ids || '').split(','),
|
||||
views_preload: attributes.views || {},
|
||||
order: attributes.order,
|
||||
one2many: true,
|
||||
row_activate: this.activate.bind(this),
|
||||
exclude_field: attributes.relation_field || null,
|
||||
limit: null,
|
||||
@@ -18577,12 +18601,22 @@ function eval_pyson(value){
|
||||
this.screen.domain = domain;
|
||||
}
|
||||
this.screen.size_limit = size_limit;
|
||||
if (this.attributes.height !== undefined &&
|
||||
this.screen.current_view &&
|
||||
this.screen.current_view.set_embedded_height) {
|
||||
this.screen.current_view.set_embedded_height(
|
||||
this.attributes.height);
|
||||
}
|
||||
this.screen.display();
|
||||
if (this.attributes.height !== undefined) {
|
||||
this.screen.current_view.el
|
||||
.find('.treeview,.list-form').first()
|
||||
.css('min-height', this.attributes.height + 'px')
|
||||
.css('max-height', this.attributes.height + 'px');
|
||||
if (this.screen.current_view.set_embedded_height) {
|
||||
this.screen.current_view.set_embedded_height(
|
||||
this.attributes.height);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
@@ -21981,8 +22015,26 @@ function eval_pyson(value){
|
||||
},
|
||||
_parse_field: function(node, attributes) {
|
||||
var name = attributes.name;
|
||||
var ColumnFactory = Sao.View.TreeXMLViewParser.WIDGETS[
|
||||
attributes.widget];
|
||||
var field = this.view.screen.model.fields[name];
|
||||
var widget = attributes.widget || (field && field.description.type);
|
||||
var column_widget = widget == 'variation' ?
|
||||
(field && field.description.type || 'char') : widget;
|
||||
attributes.widget = widget;
|
||||
var ColumnFactory = Sao.View.TreeXMLViewParser.WIDGETS[column_widget];
|
||||
if (!ColumnFactory) {
|
||||
console.error('[TREE][UNKNOWN_WIDGET]', {
|
||||
viewId: this.view.view_id,
|
||||
model: this.view.screen && this.view.screen.model_name,
|
||||
field: name,
|
||||
widget: column_widget,
|
||||
attributes: attributes,
|
||||
node: node.outerHTML,
|
||||
availableWidgets: Object.keys(
|
||||
Sao.View.TreeXMLViewParser.WIDGETS).sort(),
|
||||
});
|
||||
attributes.widget = 'char';
|
||||
ColumnFactory = Sao.View.Tree.CharColumn;
|
||||
}
|
||||
var column = new ColumnFactory(this.view.screen.model, attributes);
|
||||
if (!this.view.widgets[name]) {
|
||||
this.view.widgets[name] = [];
|
||||
@@ -22022,9 +22074,21 @@ function eval_pyson(value){
|
||||
column.prefixes.push(
|
||||
new Sao.View.Tree.Symbol(attributes, 0));
|
||||
}
|
||||
var field_attrs = this.field_attrs[name] ||
|
||||
(field && field.description) || {};
|
||||
if (!this.field_attrs[name]) {
|
||||
console.warn('[TREE][MISSING_FIELD_ATTRS]', {
|
||||
viewId: this.view.view_id,
|
||||
model: this.view.screen && this.view.screen.model_name,
|
||||
field: name,
|
||||
widget: attributes.widget,
|
||||
attributes: attributes,
|
||||
fallbackFieldAttributes: field_attrs,
|
||||
});
|
||||
}
|
||||
if (!this.view.attributes.sequence &&
|
||||
!this.view.children_field &&
|
||||
this.field_attrs[name].sortable !== false){
|
||||
field_attrs.sortable !== false){
|
||||
column.sortable = true;
|
||||
}
|
||||
this.view.columns.push(column);
|
||||
@@ -22041,6 +22105,18 @@ function eval_pyson(value){
|
||||
'class': 'value',
|
||||
});
|
||||
this.view.sum_widgets.set(column, [sum, aggregate]);
|
||||
if (window.console && this.view instanceof Sao.View.AGGridTree) {
|
||||
console.info('[AGGRID][SUMMARY_SUM_COLUMN_JSON]',
|
||||
JSON.stringify({
|
||||
viewId: this.view.view_id,
|
||||
model: this.view.screen &&
|
||||
this.view.screen.model_name,
|
||||
name: attributes.name || null,
|
||||
label: attributes.string || attributes.name || '',
|
||||
widget: attributes.widget || '',
|
||||
sum: attributes.sum || '',
|
||||
}));
|
||||
}
|
||||
}
|
||||
},
|
||||
_parse_button: function(node, attributes) {
|
||||
@@ -22462,6 +22538,8 @@ function eval_pyson(value){
|
||||
(Sao.View.AGGridTree._next_debug_id || 0) + 1;
|
||||
this._debug_id = Sao.View.AGGridTree._next_debug_id;
|
||||
this.children_field = children_field;
|
||||
this.is_embedded_one2many = Boolean(
|
||||
screen.attributes && screen.attributes.one2many);
|
||||
this.optionals = [];
|
||||
this.sum_widgets = new Map();
|
||||
this.columns = [];
|
||||
@@ -22524,6 +22602,9 @@ function eval_pyson(value){
|
||||
this.toolbar = jQuery('<div/>', {
|
||||
'class': 'ag-grid-tree-toolbar',
|
||||
}).appendTo(this.el);
|
||||
if (this.is_embedded_one2many) {
|
||||
this.el.addClass('ag-grid-tree-embedded-one2many');
|
||||
}
|
||||
this.column_menu = jQuery('<div/>', {
|
||||
'class': 'ag-grid-tree-columns',
|
||||
}).appendTo(this.toolbar);
|
||||
@@ -22610,6 +22691,14 @@ function eval_pyson(value){
|
||||
this._toggle_filter_logic_menu();
|
||||
})
|
||||
.appendTo(this.toolbar);
|
||||
this.import_layout_input = jQuery('<input/>', {
|
||||
'type': 'file',
|
||||
'accept': 'application/json,.json',
|
||||
'class': 'ag-grid-view-import-input',
|
||||
}).hide().appendTo(this.el);
|
||||
this.import_layout_input.on('change', evt => {
|
||||
this._import_layout_from_input(evt.currentTarget);
|
||||
});
|
||||
this.filter_logic_panel = jQuery('<div/>', {
|
||||
'class': 'ag-grid-filter-logic-panel',
|
||||
}).hide().appendTo(jQuery(document.body));
|
||||
@@ -22685,8 +22774,18 @@ function eval_pyson(value){
|
||||
});
|
||||
|
||||
Sao.View.AGGridTree._super.init.call(this, view_id, screen, xml);
|
||||
this._persisted_state = this._load_persisted_state();
|
||||
if (this._persisted_state && this._persisted_state.valueFilters) {
|
||||
if (this.is_embedded_one2many) {
|
||||
this._layout_store = this._normalize_layout_store(null);
|
||||
this._persisted_state = null;
|
||||
this._sao_value_filters = {};
|
||||
this._restored_value_filter_state = null;
|
||||
this._sao_value_filter_restore_guard = false;
|
||||
} else {
|
||||
this._persisted_state = this._load_persisted_state();
|
||||
}
|
||||
if (!this.is_embedded_one2many &&
|
||||
this._persisted_state &&
|
||||
this._persisted_state.valueFilters) {
|
||||
this._apply_sao_value_filter_state(
|
||||
this._persisted_state.valueFilters);
|
||||
}
|
||||
@@ -22967,43 +23066,6 @@ function eval_pyson(value){
|
||||
});
|
||||
},
|
||||
_trace_aggrid_column_resize: function(reason, params, extra) {
|
||||
if (!window.console) {
|
||||
return;
|
||||
}
|
||||
var column_api = this.gridColumnApi || this.gridApi;
|
||||
var column_state = column_api && column_api.getColumnState ?
|
||||
column_api.getColumnState() : [];
|
||||
var target_col_id = null;
|
||||
if (params && params.column) {
|
||||
if (params.column.getColId) {
|
||||
target_col_id = params.column.getColId();
|
||||
} else if (params.column.colId) {
|
||||
target_col_id = params.column.colId;
|
||||
}
|
||||
}
|
||||
console.info('[AGGRID][COLUMN_RESIZE_JSON]',
|
||||
JSON.stringify(jQuery.extend({
|
||||
reason: reason,
|
||||
instanceId: this._debug_id,
|
||||
viewId: this.view_id,
|
||||
model: this.screen && this.screen.model_name,
|
||||
targetColId: target_col_id,
|
||||
finished: params && Object.prototype.hasOwnProperty.call(
|
||||
params, 'finished') ? params.finished : null,
|
||||
source: params && params.source || null,
|
||||
resizeActive: Boolean(this._column_resize_active),
|
||||
activeLayoutId: this._active_layout_id || null,
|
||||
columnWidths: (column_state || [])
|
||||
.filter(state => state && state.colId != '__selection__')
|
||||
.map(state => ({
|
||||
colId: state.colId,
|
||||
width: state.width,
|
||||
minWidth: state.minWidth || null,
|
||||
flex: state.flex || null,
|
||||
})),
|
||||
pendingTimers: this._layout_refresh_timers ?
|
||||
this._layout_refresh_timers.length : 0,
|
||||
}, extra || {})));
|
||||
},
|
||||
_refresh_grid_layout_now: function() {
|
||||
if (!this.gridApi || !this.grid_host || !this.grid_host.length) {
|
||||
@@ -23080,6 +23142,9 @@ function eval_pyson(value){
|
||||
window.addEventListener('resize', this._window_resize_handler);
|
||||
},
|
||||
_persist_grid_state: function(options) {
|
||||
if (this.is_embedded_one2many) {
|
||||
return;
|
||||
}
|
||||
options = options || {};
|
||||
var state = this._capture_grid_state();
|
||||
state.valueFilters = this._merge_restored_value_filter_state(
|
||||
@@ -24050,6 +24115,110 @@ function eval_pyson(value){
|
||||
this._layout_store.defaultPresetId = null;
|
||||
this._apply_layout_state(this._get_standard_layout_state(), null);
|
||||
},
|
||||
_sanitize_layout_file_name: function(name) {
|
||||
name = String(name || Sao.i18n.gettext('AG Grid view')).trim();
|
||||
name = name.replace(/[\\/:*?"<>|]+/g, '-')
|
||||
.replace(/\s+/g, ' ')
|
||||
.trim();
|
||||
return name || 'ag-grid-view';
|
||||
},
|
||||
_get_layout_export_payload: function() {
|
||||
var preset = this._find_layout_preset(this._active_layout_id);
|
||||
var name = preset && !this._layout_dirty ? preset.name :
|
||||
this._get_active_layout_name().replace(/\s+\*$/, '');
|
||||
return {
|
||||
type: 'sao-ag-grid-view',
|
||||
version: 1,
|
||||
model: this.screen && this.screen.model_name || null,
|
||||
viewId: this.view_id || null,
|
||||
name: name || Sao.i18n.gettext('AG Grid view'),
|
||||
exportedAt: new Date().toISOString(),
|
||||
state: this._capture_grid_state(),
|
||||
};
|
||||
},
|
||||
_export_current_layout: function() {
|
||||
var payload = this._get_layout_export_payload();
|
||||
var file_name = this._sanitize_layout_file_name(
|
||||
payload.model + '-' + payload.name) + '.json';
|
||||
Sao.common.download_file(
|
||||
JSON.stringify(payload, null, 2),
|
||||
file_name,
|
||||
{type: 'application/json;charset=utf-8'});
|
||||
},
|
||||
_decode_imported_layout_text: function(data) {
|
||||
if (typeof data == 'string') {
|
||||
return data;
|
||||
}
|
||||
if (data instanceof Uint8Array) {
|
||||
return new TextDecoder('utf-8').decode(data);
|
||||
}
|
||||
return String(data || '');
|
||||
},
|
||||
_import_layout_from_input: function(input) {
|
||||
var file = input && input.files && input.files[0];
|
||||
if (!file) {
|
||||
return;
|
||||
}
|
||||
Sao.common.get_file_data(file, data => {
|
||||
var payload;
|
||||
try {
|
||||
payload = JSON.parse(this._decode_imported_layout_text(data));
|
||||
} catch (error) {
|
||||
Sao.common.warning.run(
|
||||
Sao.i18n.gettext('The selected file is not a valid AG Grid view.'),
|
||||
Sao.i18n.gettext('Import view'));
|
||||
return;
|
||||
}
|
||||
this._import_layout_payload(payload);
|
||||
});
|
||||
},
|
||||
_import_layout_payload: function(payload) {
|
||||
if (!payload || payload.type != 'sao-ag-grid-view' ||
|
||||
!payload.state) {
|
||||
Sao.common.warning.run(
|
||||
Sao.i18n.gettext('The selected file is not a valid AG Grid view.'),
|
||||
Sao.i18n.gettext('Import view'));
|
||||
return;
|
||||
}
|
||||
if (payload.model && payload.model != this.screen.model_name) {
|
||||
Sao.common.warning.run(
|
||||
Sao.i18n.gettext('This view is for another model.') +
|
||||
' ' + payload.model + ' / ' + this.screen.model_name,
|
||||
Sao.i18n.gettext('Import view'));
|
||||
return;
|
||||
}
|
||||
var name = String(payload.name ||
|
||||
Sao.i18n.gettext('Imported view')).trim();
|
||||
if (!name) {
|
||||
name = Sao.i18n.gettext('Imported view');
|
||||
}
|
||||
this._layout_store = this._normalize_layout_store(
|
||||
this._layout_store || {});
|
||||
var existing_names = new Set((this._layout_store.presets || [])
|
||||
.map(preset => preset.name));
|
||||
var base_name = name;
|
||||
var suffix = 2;
|
||||
while (existing_names.has(name)) {
|
||||
name = base_name + ' ' + suffix;
|
||||
suffix += 1;
|
||||
}
|
||||
var now = new Date().toISOString();
|
||||
var preset = {
|
||||
id: this._new_layout_id(),
|
||||
name: name,
|
||||
importedAt: now,
|
||||
updatedAt: now,
|
||||
state: jQuery.extend(true, {}, payload.state),
|
||||
};
|
||||
this._layout_store.presets.push(preset);
|
||||
this._active_layout_id = preset.id;
|
||||
this._layout_dirty = false;
|
||||
this._layout_store.activePresetId = preset.id;
|
||||
this._layout_store.currentState = jQuery.extend(true, {}, preset.state);
|
||||
this._persisted_state = jQuery.extend(true, {}, preset.state);
|
||||
this._save_layout_store();
|
||||
this._apply_layout_state(preset.state, preset.id);
|
||||
},
|
||||
_save_layout_as: function() {
|
||||
var name = window.prompt(Sao.i18n.gettext('View name'));
|
||||
if (!name) {
|
||||
@@ -24271,6 +24440,30 @@ function eval_pyson(value){
|
||||
evt.preventDefault();
|
||||
this._apply_standard_layout_state();
|
||||
}).appendTo(actions);
|
||||
var transfer_actions = jQuery('<div/>', {
|
||||
'class': 'ag-grid-tree-layouts-transfer-actions',
|
||||
}).appendTo(actions);
|
||||
jQuery('<button/>', {
|
||||
'class': 'btn btn-default btn-sm ag-grid-view-transfer-button',
|
||||
'type': 'button',
|
||||
'title': Sao.i18n.gettext('Export view'),
|
||||
'aria-label': Sao.i18n.gettext('Export view'),
|
||||
'text': Sao.i18n.gettext('Export'),
|
||||
}).click(evt => {
|
||||
evt.preventDefault();
|
||||
this._export_current_layout();
|
||||
}).appendTo(transfer_actions);
|
||||
jQuery('<button/>', {
|
||||
'class': 'btn btn-default btn-sm ag-grid-view-transfer-button',
|
||||
'type': 'button',
|
||||
'title': Sao.i18n.gettext('Import view'),
|
||||
'aria-label': Sao.i18n.gettext('Import view'),
|
||||
'text': Sao.i18n.gettext('Import'),
|
||||
}).click(evt => {
|
||||
evt.preventDefault();
|
||||
this.import_layout_input.val(null);
|
||||
this.import_layout_input[0].click();
|
||||
}).appendTo(transfer_actions);
|
||||
},
|
||||
_render_grouping_panel: function() {
|
||||
if (!this.grouping_panel) {
|
||||
@@ -24635,6 +24828,12 @@ function eval_pyson(value){
|
||||
this._sync_selection_header_checkbox();
|
||||
this._update_summary_bar();
|
||||
},
|
||||
onFirstDataRendered: () => {
|
||||
window.requestAnimationFrame(() => this._update_summary_bar());
|
||||
},
|
||||
onRowDataUpdated: () => {
|
||||
window.requestAnimationFrame(() => this._update_summary_bar());
|
||||
},
|
||||
onColumnMoved: this._on_grid_column_layout_changed.bind(this),
|
||||
onColumnPinned: this._on_grid_column_layout_changed.bind(this),
|
||||
onColumnResized: this._on_grid_column_resized.bind(this),
|
||||
@@ -24844,16 +25043,6 @@ function eval_pyson(value){
|
||||
},
|
||||
};
|
||||
|
||||
console.info('[AGGRID][ALIGN_COLUMN]', {
|
||||
colId: name,
|
||||
label: column.attributes.string || '',
|
||||
widget: column.attributes.widget || '',
|
||||
className: column.class_ || '',
|
||||
rightAligned: right_aligned,
|
||||
cellClass: col_def.cellClass,
|
||||
headerClass: col_def.headerClass,
|
||||
});
|
||||
|
||||
column_defs.push(col_def);
|
||||
});
|
||||
return column_defs;
|
||||
@@ -26077,7 +26266,7 @@ function eval_pyson(value){
|
||||
var pair = item.split(':');
|
||||
return pair.length < 2 ? '' :
|
||||
this._normalize_badge_text_key(pair.shift());
|
||||
}).filter(Boolean);
|
||||
}).filter(value => value && value != '*');
|
||||
},
|
||||
_get_record_field_value: function(record, name) {
|
||||
if (!record || !name) {
|
||||
@@ -26169,6 +26358,8 @@ function eval_pyson(value){
|
||||
} else if (Object.prototype.hasOwnProperty.call(
|
||||
mapped, String(normalized_text).toLowerCase())) {
|
||||
color = mapped[String(normalized_text).toLowerCase()];
|
||||
} else if (Object.prototype.hasOwnProperty.call(mapped, '*')) {
|
||||
color = mapped['*'];
|
||||
}
|
||||
if (!color && attributes.badge_color_field) {
|
||||
color = this._get_record_field_value(
|
||||
@@ -26714,7 +26905,7 @@ function eval_pyson(value){
|
||||
}
|
||||
return rows;
|
||||
},
|
||||
_get_summary_badge_columns: function() {
|
||||
_get_displayed_column_map: function() {
|
||||
var visible_columns = {};
|
||||
var column_api = this.gridColumnApi || this.gridApi;
|
||||
if (column_api && column_api.getAllDisplayedColumns) {
|
||||
@@ -26724,37 +26915,336 @@ function eval_pyson(value){
|
||||
}
|
||||
});
|
||||
}
|
||||
return visible_columns;
|
||||
},
|
||||
_get_viewport_column_map: function() {
|
||||
var visible_columns = {};
|
||||
var column_api = this.gridColumnApi || this.gridApi;
|
||||
var columns = null;
|
||||
if (column_api && column_api.getAllDisplayedVirtualColumns) {
|
||||
columns = column_api.getAllDisplayedVirtualColumns();
|
||||
} else if (column_api && column_api.getAllDisplayedColumns) {
|
||||
columns = column_api.getAllDisplayedColumns();
|
||||
}
|
||||
(columns || []).forEach(column => {
|
||||
if (column && column.getColId) {
|
||||
visible_columns[column.getColId()] = true;
|
||||
}
|
||||
});
|
||||
return visible_columns;
|
||||
},
|
||||
_is_summary_column_visible: function(column, visible_columns) {
|
||||
var name = column && column.attributes && column.attributes.name;
|
||||
return name && (!Object.keys(visible_columns).length ||
|
||||
visible_columns[name]);
|
||||
},
|
||||
_get_summary_badge_columns: function() {
|
||||
return this.columns.filter(column => {
|
||||
var name = column.attributes && column.attributes.name;
|
||||
var label = column.attributes &&
|
||||
(column.attributes.string || column.attributes.name) || '';
|
||||
var is_status_column = /(^|[_\s-])(status|state|type)([_\s-]|$)/i
|
||||
.test(String(name || '') + ' ' + String(label || ''));
|
||||
if (!name || (!this._is_badge_column(column) &&
|
||||
!is_status_column)) {
|
||||
return false;
|
||||
}
|
||||
return !Object.keys(visible_columns).length ||
|
||||
visible_columns[name];
|
||||
return name && column.attributes.widget == 'badge';
|
||||
});
|
||||
},
|
||||
_render_summary_item: function(label, value, color) {
|
||||
_get_summary_sum_columns: function() {
|
||||
var columns = [];
|
||||
this.sum_widgets.forEach((sum_widget, column) => {
|
||||
if (column && column.attributes && column.attributes.name) {
|
||||
columns.push(column);
|
||||
}
|
||||
});
|
||||
return columns;
|
||||
},
|
||||
_get_summary_variation_columns: function() {
|
||||
return this.columns.filter(column => {
|
||||
var attributes = column && column.attributes || {};
|
||||
return attributes.name &&
|
||||
attributes.widget == 'variation' &&
|
||||
attributes.variation_summary == '1' &&
|
||||
attributes.variation_previous &&
|
||||
attributes.variation_group_by;
|
||||
});
|
||||
},
|
||||
_render_summary_item: function(
|
||||
label, value, color, class_name, variation_text,
|
||||
variation_class) {
|
||||
var item = jQuery('<div/>', {
|
||||
'class': 'ag-grid-summary-item',
|
||||
'class': 'ag-grid-summary-item' +
|
||||
(class_name ? ' ' + class_name : ''),
|
||||
});
|
||||
jQuery('<span/>', {
|
||||
'class': 'ag-grid-summary-label',
|
||||
'text': label,
|
||||
}).appendTo(item);
|
||||
if (variation_text) {
|
||||
jQuery('<span/>', {
|
||||
'class': 'ag-grid-summary-variation-badge ' +
|
||||
(variation_class || ''),
|
||||
'text': variation_text,
|
||||
}).appendTo(item);
|
||||
}
|
||||
var value_wrap = jQuery('<span/>', {
|
||||
'class': 'ag-grid-summary-value-wrap',
|
||||
}).appendTo(item);
|
||||
var value_el = jQuery('<span/>', {
|
||||
'class': 'ag-grid-summary-value',
|
||||
'text': value,
|
||||
}).appendTo(item);
|
||||
}).appendTo(value_wrap);
|
||||
if (color) {
|
||||
value_el.css('color', color);
|
||||
}
|
||||
return item;
|
||||
},
|
||||
_trace_summary_bar: function(
|
||||
rows, badge_columns, sum_columns, variation_columns, summary_items) {
|
||||
if (!window.console) {
|
||||
return;
|
||||
}
|
||||
var describe = column => ({
|
||||
name: column && column.attributes && column.attributes.name || null,
|
||||
label: column && column.attributes &&
|
||||
(column.attributes.string || column.attributes.name) || '',
|
||||
widget: column && column.attributes && column.attributes.widget || '',
|
||||
sum: column && column.attributes && column.attributes.sum || '',
|
||||
badge: Boolean(column && column.attributes &&
|
||||
column.attributes.widget == 'badge'),
|
||||
});
|
||||
console.info('[AGGRID][SUMMARY_BAR_JSON]', JSON.stringify({
|
||||
instanceId: this._debug_id,
|
||||
viewId: this.view_id,
|
||||
model: this.screen && this.screen.model_name,
|
||||
rowCount: rows.length,
|
||||
viewportColumns: Object.keys(this._get_viewport_column_map()),
|
||||
displayedColumns: Object.keys(this._get_displayed_column_map()),
|
||||
badgeColumns: badge_columns.map(describe),
|
||||
sumColumns: sum_columns.map(describe),
|
||||
variationColumns: variation_columns.map(describe),
|
||||
sumWidgetColumns: Array.from(this.sum_widgets.keys()).map(describe),
|
||||
badgeLikeColumns: this.columns.filter(column =>
|
||||
this._is_badge_column(column)).map(describe),
|
||||
summaryItems: summary_items.map(item => ({
|
||||
label: item.label,
|
||||
count: item.count,
|
||||
className: item.className || '',
|
||||
})),
|
||||
}));
|
||||
},
|
||||
_get_summary_column_load_fields: function(column) {
|
||||
var attributes = column && column.attributes || {};
|
||||
var fields = [];
|
||||
if (attributes.name) {
|
||||
fields.push(attributes.name);
|
||||
}
|
||||
if (attributes.widget == 'variation') {
|
||||
if (attributes.variation_previous) {
|
||||
fields.push(attributes.variation_previous);
|
||||
}
|
||||
if (attributes.variation_group_by) {
|
||||
fields.push(attributes.variation_group_by);
|
||||
}
|
||||
}
|
||||
if (attributes.sum_variation == '1' && attributes.sum_previous) {
|
||||
fields.push(attributes.sum_previous);
|
||||
}
|
||||
return fields.filter((field, index) =>
|
||||
field && fields.indexOf(field) == index);
|
||||
},
|
||||
_load_summary_column_values: function(rows, columns, reason) {
|
||||
if (this._summary_sum_loading) {
|
||||
return null;
|
||||
}
|
||||
var promises = [];
|
||||
var field_names = [];
|
||||
columns.forEach(column => {
|
||||
var names = this._get_summary_column_load_fields(column);
|
||||
field_names = field_names.concat(names);
|
||||
rows.forEach(row => {
|
||||
var record = row && row.__record;
|
||||
names.forEach(name => {
|
||||
if (record && record.id >= 0 &&
|
||||
!record.get_loaded([name])) {
|
||||
promises.push(record.load(name, true, false));
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
if (!promises.length) {
|
||||
return null;
|
||||
}
|
||||
this._summary_sum_loading = true;
|
||||
if (window.console) {
|
||||
console.info('[AGGRID][SUMMARY_SUM_LOAD_JSON]',
|
||||
JSON.stringify({
|
||||
instanceId: this._debug_id,
|
||||
viewId: this.view_id,
|
||||
model: this.screen && this.screen.model_name,
|
||||
reason: reason || 'summary',
|
||||
fields: field_names.filter((field, index) =>
|
||||
field && field_names.indexOf(field) == index),
|
||||
promiseCount: promises.length,
|
||||
}));
|
||||
}
|
||||
return jQuery.when.apply(jQuery, promises).always(() => {
|
||||
this._summary_sum_loading = false;
|
||||
});
|
||||
},
|
||||
_load_summary_sum_values: function(rows, columns) {
|
||||
return this._load_summary_column_values(rows, columns, 'sum');
|
||||
},
|
||||
_load_summary_badge_values: function(rows, columns) {
|
||||
return this._load_summary_column_values(rows, columns, 'badge');
|
||||
},
|
||||
_append_sum_summary_item: function(summary_items, rows, column) {
|
||||
var sum = null;
|
||||
var name = column && column.attributes && column.attributes.name;
|
||||
var field = name ? this.screen.model.fields[name] : null;
|
||||
var previous_sum = null;
|
||||
var previous_name = column && column.attributes &&
|
||||
column.attributes.sum_previous;
|
||||
var with_variation = column && column.attributes &&
|
||||
column.attributes.sum_variation == '1' && previous_name;
|
||||
rows.forEach(row => {
|
||||
var record = row && row.__record;
|
||||
if (!field || !record || record.id >= 0 &&
|
||||
!record.get_loaded([name])) {
|
||||
return;
|
||||
}
|
||||
var value = field.get(record);
|
||||
if (value && value.isTimeDelta) {
|
||||
value = value.asSeconds();
|
||||
}
|
||||
if (value !== null && value !== undefined && value !== '') {
|
||||
sum = sum === null ? value : sum + value;
|
||||
}
|
||||
if (with_variation) {
|
||||
var previous = this._get_record_raw_field_value(
|
||||
record, previous_name);
|
||||
if (previous !== null && previous !== undefined &&
|
||||
previous !== '') {
|
||||
previous = Number(previous);
|
||||
if (isFinite(previous)) {
|
||||
previous_sum = previous_sum === null ?
|
||||
previous : previous_sum + previous;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
var variation = null;
|
||||
if (with_variation && sum !== null && previous_sum !== null &&
|
||||
previous_sum !== 0) {
|
||||
variation = ((sum - previous_sum) /
|
||||
Math.abs(previous_sum)) * 100;
|
||||
}
|
||||
summary_items.push({
|
||||
label: column.attributes.string || column.attributes.name,
|
||||
count: sum === null ? '-' :
|
||||
this._format_aggregate_value(column, sum),
|
||||
color: '#111111',
|
||||
className: 'ag-grid-summary-item-sum',
|
||||
variationText: variation === null ? '' :
|
||||
this._format_sum_variation_percent(variation),
|
||||
variationClass: variation === null ? '' :
|
||||
(variation < 0 ? 'ag-grid-summary-variation-negative' :
|
||||
'ag-grid-summary-variation-positive'),
|
||||
});
|
||||
},
|
||||
_get_record_raw_field_value: function(record, name) {
|
||||
if (!record || !name) {
|
||||
return null;
|
||||
}
|
||||
var field = this.screen.model.fields[name];
|
||||
if (!field || record.id >= 0 && !record.get_loaded([name])) {
|
||||
return null;
|
||||
}
|
||||
var value = field.get(record);
|
||||
if (value && value.isTimeDelta) {
|
||||
value = value.asSeconds();
|
||||
}
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return null;
|
||||
}
|
||||
return value;
|
||||
},
|
||||
_get_record_text_field_value: function(record, name) {
|
||||
if (!record || !name) {
|
||||
return '';
|
||||
}
|
||||
var field = this.screen.model.fields[name];
|
||||
if (!field || record.id >= 0 && !record.get_loaded([name])) {
|
||||
return '';
|
||||
}
|
||||
try {
|
||||
return field.get_client(record);
|
||||
} catch (error) {
|
||||
var value = this._get_record_raw_field_value(record, name);
|
||||
return value === null || value === undefined ? '' : String(value);
|
||||
}
|
||||
},
|
||||
_format_variation_percent: function(value) {
|
||||
var locale = Sao.i18n.BC47(Sao.i18n.getlang());
|
||||
var sign = value > 0 ? '+' : '';
|
||||
return sign + value.toLocaleString(locale, {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
}) + '%';
|
||||
},
|
||||
_format_sum_variation_percent: function(value) {
|
||||
var locale = Sao.i18n.BC47(Sao.i18n.getlang());
|
||||
var sign = value >= 0 ? '+' : '';
|
||||
return sign + value.toLocaleString(locale, {
|
||||
minimumFractionDigits: 0,
|
||||
maximumFractionDigits: 2,
|
||||
}) + '%';
|
||||
},
|
||||
_append_variation_summary_items: function(summary_items, rows, column) {
|
||||
var attributes = column && column.attributes || {};
|
||||
var current_name = attributes.name;
|
||||
var previous_name = attributes.variation_previous;
|
||||
var group_name = attributes.variation_group_by;
|
||||
var groups = {};
|
||||
rows.forEach(row => {
|
||||
var record = row && row.__record;
|
||||
if (!record) {
|
||||
return;
|
||||
}
|
||||
var current = Number(this._get_record_raw_field_value(
|
||||
record, current_name));
|
||||
var previous = Number(this._get_record_raw_field_value(
|
||||
record, previous_name));
|
||||
var group = this._get_record_text_field_value(
|
||||
record, group_name) || Sao.i18n.gettext('(Empty)');
|
||||
if (!isFinite(current) || !isFinite(previous) || previous === 0) {
|
||||
return;
|
||||
}
|
||||
if (!groups[group]) {
|
||||
groups[group] = {
|
||||
current: 0,
|
||||
previous: 0,
|
||||
};
|
||||
}
|
||||
groups[group].current += current;
|
||||
groups[group].previous += previous;
|
||||
});
|
||||
Object.keys(groups).sort((a, b) => String(a).localeCompare(
|
||||
String(b), undefined, {numeric: true, sensitivity: 'base'}))
|
||||
.forEach(group => {
|
||||
var values = groups[group];
|
||||
if (!values.previous) {
|
||||
return;
|
||||
}
|
||||
var variation = ((values.current - values.previous) /
|
||||
Math.abs(values.previous)) * 100;
|
||||
summary_items.push({
|
||||
label: group,
|
||||
count: this._format_variation_percent(variation),
|
||||
color: variation > 0 ? '#16a34a' :
|
||||
variation < 0 ? '#dc2626' : '#64748b',
|
||||
className: 'ag-grid-summary-item-variation' +
|
||||
(variation > 0 ? ' ag-grid-summary-variation-up' :
|
||||
variation < 0 ?
|
||||
' ag-grid-summary-variation-down' :
|
||||
' ag-grid-summary-variation-flat'),
|
||||
});
|
||||
});
|
||||
},
|
||||
_get_default_badge_summary_color: function(value) {
|
||||
var key = String(value || '').toLowerCase();
|
||||
var palette = {
|
||||
@@ -26785,8 +27275,16 @@ function eval_pyson(value){
|
||||
var order = [];
|
||||
var empty = Sao.i18n.gettext('(Empty)');
|
||||
rows.forEach(row => {
|
||||
var value = row[name] ?
|
||||
this._normalize_badge_text_key(row[name]) : empty;
|
||||
var raw_value = '';
|
||||
if (column && row && row.__record) {
|
||||
raw_value = this._get_column_text_value(
|
||||
column, row.__record);
|
||||
}
|
||||
if (!raw_value && row) {
|
||||
raw_value = row[name];
|
||||
}
|
||||
var value = raw_value ?
|
||||
this._normalize_badge_text_key(raw_value) : empty;
|
||||
if (value == empty) {
|
||||
return;
|
||||
}
|
||||
@@ -26836,27 +27334,6 @@ function eval_pyson(value){
|
||||
});
|
||||
return Boolean(order.length);
|
||||
},
|
||||
_get_summary_status_sources_from_grid: function() {
|
||||
var sources = [];
|
||||
var seen = {};
|
||||
(this._grid_columns || []).forEach(col_def => {
|
||||
var name = col_def && col_def.field || col_def && col_def.colId;
|
||||
if (!name || name == '__selection__' || seen[name]) {
|
||||
return;
|
||||
}
|
||||
var label = col_def.headerName || name;
|
||||
if (!/(status|state|type|shipping|shipment|open\/physic)/i
|
||||
.test(String(name) + ' ' + String(label))) {
|
||||
return;
|
||||
}
|
||||
seen[name] = true;
|
||||
sources.push({
|
||||
name: name,
|
||||
label: label,
|
||||
});
|
||||
});
|
||||
return sources;
|
||||
},
|
||||
_update_summary_bar: function() {
|
||||
if (!this.summary_bar || !this.summary_bar.length) {
|
||||
return;
|
||||
@@ -26869,25 +27346,38 @@ function eval_pyson(value){
|
||||
rows.length.toLocaleString(locale),
|
||||
'#145369'));
|
||||
var summary_items = [];
|
||||
var summarized_names = {};
|
||||
this._get_summary_badge_columns().forEach(column => {
|
||||
if (this._append_badge_summary_items(
|
||||
summary_items, rows, column)) {
|
||||
summarized_names[column.attributes.name] = true;
|
||||
}
|
||||
});
|
||||
this._get_summary_status_sources_from_grid().forEach(source => {
|
||||
if (summarized_names[source.name]) {
|
||||
return;
|
||||
}
|
||||
var sum_columns = this._get_summary_sum_columns();
|
||||
var badge_columns = this._get_summary_badge_columns();
|
||||
var variation_columns = this._get_summary_variation_columns();
|
||||
var summary_load = this._load_summary_column_values(
|
||||
rows, badge_columns.concat(sum_columns, variation_columns),
|
||||
'summary');
|
||||
if (summary_load) {
|
||||
summary_load.then(() => this._update_summary_bar());
|
||||
}
|
||||
badge_columns.forEach(column => {
|
||||
this._append_badge_summary_items(
|
||||
summary_items, rows, null, source);
|
||||
summary_items, rows, column);
|
||||
});
|
||||
sum_columns.forEach(column => {
|
||||
this._append_sum_summary_item(summary_items, rows, column);
|
||||
});
|
||||
variation_columns.forEach(column => {
|
||||
this._append_variation_summary_items(
|
||||
summary_items, rows, column);
|
||||
});
|
||||
this._trace_summary_bar(
|
||||
rows, badge_columns, sum_columns, variation_columns,
|
||||
summary_items);
|
||||
summary_items.forEach(item => {
|
||||
this.summary_bar.append(this._render_summary_item(
|
||||
item.label,
|
||||
item.count.toLocaleString(locale),
|
||||
item.color));
|
||||
typeof item.count == 'number' ?
|
||||
item.count.toLocaleString(locale) : item.count,
|
||||
item.color,
|
||||
item.className,
|
||||
item.variationText,
|
||||
item.variationClass));
|
||||
});
|
||||
},
|
||||
on_copy: function() {
|
||||
@@ -27052,7 +27542,10 @@ function eval_pyson(value){
|
||||
var readable_min_height = 420;
|
||||
var maximum_height = 720;
|
||||
var height;
|
||||
if (available >= compact_min_height) {
|
||||
if (this.is_embedded_one2many && this._embedded_height) {
|
||||
height = Math.max(80, this._embedded_height - toolbar_height -
|
||||
summary_height - external_scroll_height);
|
||||
} else if (available >= compact_min_height) {
|
||||
height = Math.max(
|
||||
compact_min_height,
|
||||
Math.min(maximum_height, available));
|
||||
@@ -27104,6 +27597,17 @@ function eval_pyson(value){
|
||||
});
|
||||
}
|
||||
},
|
||||
set_embedded_height: function(height) {
|
||||
height = parseInt(height, 10);
|
||||
if (!this.is_embedded_one2many || isNaN(height) || height <= 0) {
|
||||
return;
|
||||
}
|
||||
this._embedded_height = height;
|
||||
this._resize_grid_host();
|
||||
if (this.gridApi && this.gridApi.doLayout) {
|
||||
this.gridApi.doLayout();
|
||||
}
|
||||
},
|
||||
_refresh_grid_layout_after_row_data: function(row_data) {
|
||||
if (!this.gridApi) {
|
||||
return;
|
||||
@@ -27319,7 +27823,7 @@ function eval_pyson(value){
|
||||
} else if (diagnostics.relationWidget) {
|
||||
diagnostics.fallbackReason = diagnostics.relationWidget +
|
||||
'_relation_widget';
|
||||
} else if (diagnostics.embeddedContext) {
|
||||
} else if (diagnostics.embeddedContext && diagnostics.editable) {
|
||||
diagnostics.fallbackReason = 'embedded_relation_tree';
|
||||
} else if (diagnostics.editable) {
|
||||
diagnostics.fallbackReason = 'editable_view';
|
||||
@@ -30481,6 +30985,7 @@ function eval_pyson(value){
|
||||
'timedelta': Sao.View.Tree.TimeDeltaColumn,
|
||||
'tolerance_gauge': Sao.View.Tree.ToleranceGauge,
|
||||
'url': Sao.View.Tree.URLColumn,
|
||||
'variation': Sao.View.Tree.CharColumn,
|
||||
};
|
||||
|
||||
Sao.View.EditableTree = {};
|
||||
|
||||
Reference in New Issue
Block a user