Badge notes
This commit is contained in:
@@ -1027,3 +1027,101 @@ Point de deploiement:
|
||||
- `GROUPING_LOAD_FIELDS_FLAT_JSON`
|
||||
- `GROUPING_KEYS_FLAT_JSON`
|
||||
- si une correction visuelle semble inactive, verifier d'abord quel fichier est charge par `index.html` et si `dist/` a ete synchronise
|
||||
|
||||
### Session du 2026-06-02 - KPI badges Lots Management non resolu
|
||||
|
||||
Demande UX:
|
||||
|
||||
- rapprocher `Lots management` de la maquette recue:
|
||||
- barre KPI compacte entre les boutons AG Grid et la grille
|
||||
- compteurs par valeur de badge (`Open`, `Physic`, `scheduled`, `shipped`, `unshipped`, etc.)
|
||||
- badges en rendu pastel: fond clair + texte couleur forte
|
||||
- couleurs proches de la maquette:
|
||||
- `Open`: bleu
|
||||
- `Physic`: violet
|
||||
- `scheduled`: orange
|
||||
- `shipped`: vert
|
||||
- `unshipped`: rouge
|
||||
|
||||
Ce qui a ete implemente dans `tryton-sao.js` / `dist/tryton-sao.js`:
|
||||
|
||||
- ajout de `this.summary_bar` sous la toolbar AG Grid
|
||||
- appel de `_update_summary_bar()` apres:
|
||||
- changement de colonnes
|
||||
- changement de filtre AG Grid
|
||||
- refresh de `rowData`
|
||||
- `display()`
|
||||
- prise en compte de la hauteur de la barre KPI dans `_resize_grid_host()`
|
||||
- helpers ajoutes/touches:
|
||||
- `_get_visible_record_rows`
|
||||
- `_get_summary_badge_columns`
|
||||
- `_render_summary_item`
|
||||
- `_update_summary_bar`
|
||||
- `_normalize_badge_text_key`
|
||||
- `_get_badge_color_order`
|
||||
- `_get_badge_display_colors`
|
||||
- `_append_badge_summary_items`
|
||||
- `_get_summary_status_sources_from_grid`
|
||||
- `_get_default_badge_summary_color`
|
||||
- tentative de fallback:
|
||||
- scanner les `columnDefs` AG Grid visibles qui ressemblent a des colonnes `status`, `state`, `type`, `shipping`, `shipment`, `open/physic`
|
||||
- normaliser les valeurs type `emoji + Open` en `Open`
|
||||
|
||||
Ce qui a ete implemente dans `tryton-sao.css` / `dist/tryton-sao.css`:
|
||||
|
||||
- styles `.ag-grid-tree-summary`, `.ag-grid-summary-item`, `.ag-grid-summary-label`, `.ag-grid-summary-value`
|
||||
- badges `.ag-grid-badge` passes en fond clair + texte plus fort
|
||||
- couleurs dark mode pour la barre KPI
|
||||
|
||||
Etat observe par l'utilisateur:
|
||||
|
||||
- les badges de grille sont bien en rendu pastel pour `Shipping status`
|
||||
- `Qt type` affiche encore `Open` / `Physic` en texte simple ou avec rendu partiel selon la config cote Tryton
|
||||
- la barre KPI affiche toujours seulement:
|
||||
- `Rows`
|
||||
- `192`
|
||||
- les compteurs par valeur de badge ne s'affichent pas, meme apres les fallbacks ajoutes
|
||||
|
||||
Conclusion importante:
|
||||
|
||||
- le probleme des totaux par valeur de badge n'est PAS resolu
|
||||
- ne pas considerer les helpers KPI actuels comme valides
|
||||
- prochaine reprise: instrumenter avant de retoucher encore
|
||||
|
||||
Hypotheses probables a verifier:
|
||||
|
||||
- `_get_summary_badge_columns()` retourne vide au runtime, ou retourne des colonnes sans valeurs exploitables
|
||||
- `_get_summary_status_sources_from_grid()` ne voit pas les `columnDefs` attendus au moment ou `_update_summary_bar()` tourne
|
||||
- `rows` contient bien 192 lignes, mais les proprietes lues (`row[name]`) ne correspondent pas aux `field/colId` visibles dans AG Grid
|
||||
- les valeurs visibles dans les cellules peuvent venir du `valueGetter` / renderer, mais ne pas etre presentes dans le `rowData` sous le meme nom
|
||||
- le `summary_bar` peut etre mis a jour avant que `_grid_columns` soit disponible ou avant que les `columnDefs` restaurees soient reappliquees
|
||||
|
||||
Trace a ajouter en premier a la prochaine session:
|
||||
|
||||
- une trace plate, appelee par exemple `[AGGRID][SUMMARY_BADGES_DEBUG_JSON]`, dans `_update_summary_bar()`
|
||||
- champs minimum:
|
||||
- `rowsLength`
|
||||
- `rowKeysSample`: `Object.keys(rows[0] || {})`
|
||||
- `rowSample`: valeurs des colonnes visibles sur 1 ou 2 lignes
|
||||
- `summaryBadgeColumns`: noms/labels/attributs des colonnes retournees par `_get_summary_badge_columns()`
|
||||
- `gridColumns`: `field`, `colId`, `headerName`, `cellClass`, `headerClass` de `this._grid_columns`
|
||||
- `displayedColumns`: `getAllDisplayedColumns().map(col => col.getColId())`
|
||||
- `statusSources`: retour de `_get_summary_status_sources_from_grid()`
|
||||
- `summaryItemsBeforeRender`
|
||||
|
||||
Lignes Tryton/XML conseillees pour le rendu badges, mais a confirmer apres debug:
|
||||
|
||||
```xml
|
||||
<field name="r_lot_status" widget="badge"
|
||||
badge_colors="Open:#2563eb,Physic:#8b5cf6"/>
|
||||
|
||||
<field name="r_shipping_status" widget="badge"
|
||||
badge_colors="scheduled:#f59e0b,shipped:#16a34a,unshipped:#ef4444"/>
|
||||
```
|
||||
|
||||
Point de vigilance:
|
||||
|
||||
- si `Qt type` a un emoji/prefixe cote Python ou XML, SAO doit soit:
|
||||
- rendre l'icone separement du texte de valeur
|
||||
- soit normaliser la cle avant mapping couleur/KPI
|
||||
- eviter de continuer a corriger "a l'oeil"; le prochain pas doit etre une trace runtime partageable.
|
||||
|
||||
@@ -349,3 +349,12 @@ Traces a lire si le sujet revient:
|
||||
- `_resize_grid_host()` peut poser des styles inline sur le `content_box`; quand `Sao.ScreenContainer.set()` repasse sur un widget non AG Grid, nettoyer `height`, `minHeight`, `flexBasis`, `flexShrink`, `width`, `maxWidth`
|
||||
- regression typique si cet invariant casse: forme Purchase classique coupee en bas, onglets/lignes mal visibles, grande zone blanche ou largeur incorrecte apres toggle du menu gauche
|
||||
- test obligatoire: Purchase form sans AG Grid principale avec menu gauche ouvert/cache, puis Lots Management/report AG Grid avec filtres hauts
|
||||
|
||||
### Point de reprise 2026-06-02 - KPI badges non resolu
|
||||
|
||||
- tentative en cours: barre KPI au-dessus de la grille avec compteurs par valeur de badge
|
||||
- resultat actuel: la barre affiche `Rows 192`, mais PAS les compteurs `Open`, `Physic`, `scheduled`, `shipped`, `unshipped`
|
||||
- le rendu pastel des badges `Shipping status` est visible, mais la logique de totaux par valeur ne marche pas
|
||||
- fichiers touches: `tryton-sao.js`, `tryton-sao.css`, `dist/tryton-sao.js`, `dist/tryton-sao.css`
|
||||
- avant toute nouvelle correction, ajouter une trace `[AGGRID][SUMMARY_BADGES_DEBUG_JSON]` dans `_update_summary_bar()`
|
||||
- lire le bloc detaille dans `AG_GRID_PROGRESS.md > Session du 2026-06-02 - KPI badges Lots Management non resolu`
|
||||
|
||||
72
dist/tryton-sao.css
vendored
72
dist/tryton-sao.css
vendored
@@ -11613,6 +11613,54 @@ html[theme="default"] .ag-grid-tree-grouping-panel input[type="checkbox"]:after
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.ag-grid-tree-summary {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
flex-wrap: wrap;
|
||||
gap: 0;
|
||||
min-height: 48px;
|
||||
margin: 0 0 8px;
|
||||
border: 1px solid #dfe8e3;
|
||||
border-radius: 6px;
|
||||
background: #ffffff;
|
||||
box-shadow: 0 1px 4px rgba(53, 81, 84, 0.06);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ag-grid-summary-item {
|
||||
display: flex;
|
||||
flex: 0 1 150px;
|
||||
min-width: 120px;
|
||||
max-width: 190px;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
gap: 3px;
|
||||
padding: 8px 18px;
|
||||
border-right: 1px solid #e7efeb;
|
||||
}
|
||||
|
||||
.ag-grid-summary-item:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.ag-grid-summary-label {
|
||||
min-width: 0;
|
||||
color: #64748b;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
line-height: 1.2;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.ag-grid-summary-value {
|
||||
color: #145369;
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
line-height: 1.15;
|
||||
}
|
||||
|
||||
.ag-grid-tree-host {
|
||||
flex: 0 0 auto;
|
||||
min-height: 520px;
|
||||
@@ -11794,10 +11842,10 @@ html[theme="default"] .ag-grid-tree-grouping-panel input[type="checkbox"]:after
|
||||
min-height: 22px;
|
||||
padding: 2px 10px;
|
||||
border-radius: 999px;
|
||||
background: #6c757d;
|
||||
color: #f7fbf9;
|
||||
background: #eef3f2;
|
||||
color: #355154;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
font-weight: 700;
|
||||
line-height: 1.35;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
@@ -12769,6 +12817,24 @@ html[data-theme-mode="dark"] .ag-grid-filter-logic-operator {
|
||||
color: #8fe1d8;
|
||||
}
|
||||
|
||||
html[data-theme-mode="dark"] .ag-grid-tree-summary {
|
||||
background: #151f1e;
|
||||
border-color: #2a403d;
|
||||
box-shadow: 0 8px 22px rgba(0, 0, 0, 0.24);
|
||||
}
|
||||
|
||||
html[data-theme-mode="dark"] .ag-grid-summary-item {
|
||||
border-right-color: #243735;
|
||||
}
|
||||
|
||||
html[data-theme-mode="dark"] .ag-grid-summary-label {
|
||||
color: #aebfba;
|
||||
}
|
||||
|
||||
html[data-theme-mode="dark"] .ag-grid-summary-value {
|
||||
color: #8fe1d8;
|
||||
}
|
||||
|
||||
html[data-theme-mode="dark"] .form-tolerance-gauge {
|
||||
color: #dce7e2;
|
||||
}
|
||||
|
||||
307
dist/tryton-sao.js
vendored
307
dist/tryton-sao.js
vendored
@@ -22624,6 +22624,9 @@ function eval_pyson(value){
|
||||
this.status = jQuery('<div/>', {
|
||||
'class': 'ag-grid-tree-status text-muted',
|
||||
}).appendTo(this.toolbar);
|
||||
this.summary_bar = jQuery('<div/>', {
|
||||
'class': 'ag-grid-tree-summary',
|
||||
}).appendTo(this.el);
|
||||
this.grid_host = jQuery('<div/>', {
|
||||
'class': 'ag-grid-theme-alpine ag-grid-tree-host',
|
||||
}).appendTo(this.el);
|
||||
@@ -22946,6 +22949,7 @@ function eval_pyson(value){
|
||||
if (!options.skipLayoutRefresh) {
|
||||
this._schedule_grid_layout_refresh();
|
||||
}
|
||||
this._update_summary_bar();
|
||||
},
|
||||
_on_grid_column_resized: function(params) {
|
||||
this._trace_aggrid_column_resize('event', params);
|
||||
@@ -24629,6 +24633,7 @@ function eval_pyson(value){
|
||||
onFilterChanged: () => {
|
||||
this._schedule_state_save();
|
||||
this._sync_selection_header_checkbox();
|
||||
this._update_summary_bar();
|
||||
},
|
||||
onColumnMoved: this._on_grid_column_layout_changed.bind(this),
|
||||
onColumnPinned: this._on_grid_column_layout_changed.bind(this),
|
||||
@@ -25220,6 +25225,7 @@ function eval_pyson(value){
|
||||
this._log_sao_value_filter_empty_result(this.group.slice());
|
||||
}
|
||||
this._resize_grid_host();
|
||||
this._update_summary_bar();
|
||||
this._schedule_grid_layout_refresh([0, 80]);
|
||||
});
|
||||
},
|
||||
@@ -25258,6 +25264,7 @@ function eval_pyson(value){
|
||||
this._refresh_grid_layout_after_row_data(row_data);
|
||||
this._sync_selection(selected);
|
||||
this._update_copy_state();
|
||||
this._update_summary_bar();
|
||||
},
|
||||
_toggle_sao_value_filter_mode: function() {
|
||||
this._set_sao_value_filter_mode(
|
||||
@@ -26061,6 +26068,17 @@ function eval_pyson(value){
|
||||
});
|
||||
return parsed;
|
||||
},
|
||||
_normalize_badge_text_key: function(text) {
|
||||
text = text === null || text === undefined ? '' : String(text);
|
||||
return text.replace(/^[^A-Za-z0-9]+/, '').trim();
|
||||
},
|
||||
_get_badge_color_order: function(colors) {
|
||||
return (colors || '').split(',').map(item => {
|
||||
var pair = item.split(':');
|
||||
return pair.length < 2 ? '' :
|
||||
this._normalize_badge_text_key(pair.shift());
|
||||
}).filter(Boolean);
|
||||
},
|
||||
_get_record_field_value: function(record, name) {
|
||||
if (!record || !name) {
|
||||
return '';
|
||||
@@ -26084,34 +26102,73 @@ function eval_pyson(value){
|
||||
color = color === null || color === undefined ? '' :
|
||||
String(color).trim();
|
||||
var palette = {
|
||||
red: '#e06a6a',
|
||||
danger: '#e06a6a',
|
||||
coral: '#e06a6a',
|
||||
orange: '#d99a2b',
|
||||
warning: '#d99a2b',
|
||||
amber: '#d99a2b',
|
||||
yellow: '#f1c40f',
|
||||
green: '#2b8c87',
|
||||
success: '#2b8c87',
|
||||
teal: '#2b8c87',
|
||||
blue: '#57c1b9',
|
||||
info: '#57c1b9',
|
||||
red: '#ef4444',
|
||||
danger: '#ef4444',
|
||||
coral: '#ef4444',
|
||||
orange: '#f59e0b',
|
||||
warning: '#f59e0b',
|
||||
amber: '#f59e0b',
|
||||
yellow: '#eab308',
|
||||
green: '#16a34a',
|
||||
success: '#16a34a',
|
||||
teal: '#0f766e',
|
||||
blue: '#2563eb',
|
||||
info: '#2563eb',
|
||||
purple: '#8b5cf6',
|
||||
violet: '#8b5cf6',
|
||||
gray: '#6c757d',
|
||||
grey: '#6c757d',
|
||||
muted: '#6c757d',
|
||||
};
|
||||
return palette[color.toLowerCase()] || color;
|
||||
},
|
||||
_hex_to_rgb_badge_color: function(color) {
|
||||
color = this._normalize_badge_color(color);
|
||||
var match = /^#?([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(color || '');
|
||||
if (!match) {
|
||||
return null;
|
||||
}
|
||||
var hex = match[1];
|
||||
if (hex.length == 3) {
|
||||
hex = hex.split('').map(part => part + part).join('');
|
||||
}
|
||||
return {
|
||||
r: parseInt(hex.slice(0, 2), 16),
|
||||
g: parseInt(hex.slice(2, 4), 16),
|
||||
b: parseInt(hex.slice(4, 6), 16),
|
||||
};
|
||||
},
|
||||
_rgb_to_badge_color: function(rgb) {
|
||||
var part = value => Math.max(0, Math.min(255, Math.round(value)))
|
||||
.toString(16).padStart(2, '0');
|
||||
return '#' + part(rgb.r) + part(rgb.g) + part(rgb.b);
|
||||
},
|
||||
_mix_badge_color: function(color, mix_with, weight) {
|
||||
var source = this._hex_to_rgb_badge_color(color);
|
||||
var target = this._hex_to_rgb_badge_color(mix_with);
|
||||
if (!source || !target) {
|
||||
return '';
|
||||
}
|
||||
return this._rgb_to_badge_color({
|
||||
r: source.r * (1 - weight) + target.r * weight,
|
||||
g: source.g * (1 - weight) + target.g * weight,
|
||||
b: source.b * (1 - weight) + target.b * weight,
|
||||
});
|
||||
},
|
||||
_get_badge_colors: function(column, record, text) {
|
||||
var attributes = column.attributes || {};
|
||||
var color = '';
|
||||
var text_color = '';
|
||||
var mapped = this._parse_badge_colors(attributes.badge_colors);
|
||||
var normalized_text = this._normalize_badge_text_key(text);
|
||||
if (Object.prototype.hasOwnProperty.call(mapped, text)) {
|
||||
color = mapped[text];
|
||||
} else if (Object.prototype.hasOwnProperty.call(
|
||||
mapped, String(text).toLowerCase())) {
|
||||
color = mapped[String(text).toLowerCase()];
|
||||
mapped, normalized_text)) {
|
||||
color = mapped[normalized_text];
|
||||
} else if (Object.prototype.hasOwnProperty.call(
|
||||
mapped, String(normalized_text).toLowerCase())) {
|
||||
color = mapped[String(normalized_text).toLowerCase()];
|
||||
}
|
||||
if (!color && attributes.badge_color_field) {
|
||||
color = this._get_record_field_value(
|
||||
@@ -26138,6 +26195,19 @@ function eval_pyson(value){
|
||||
color: this._normalize_badge_color(text_color),
|
||||
};
|
||||
},
|
||||
_get_badge_display_colors: function(column, record, text) {
|
||||
var colors = this._get_badge_colors(column, record, text);
|
||||
var accent = colors.color || colors.background;
|
||||
if (!accent) {
|
||||
return colors;
|
||||
}
|
||||
return {
|
||||
background: this._mix_badge_color(accent, '#ffffff', 0.86) ||
|
||||
colors.background,
|
||||
color: colors.color || accent,
|
||||
accent: accent,
|
||||
};
|
||||
},
|
||||
_render_badge_cell: function(column, record) {
|
||||
var text = this._get_column_text_value(column, record);
|
||||
var cell = jQuery('<div/>', {
|
||||
@@ -26153,7 +26223,7 @@ function eval_pyson(value){
|
||||
if (parseInt(column.attributes.badge_bold || '0', 10)) {
|
||||
badge.addClass('ag-grid-badge-bold');
|
||||
}
|
||||
var colors = this._get_badge_colors(column, record, text);
|
||||
var colors = this._get_badge_display_colors(column, record, text);
|
||||
if (colors.background) {
|
||||
badge.css('background-color', colors.background);
|
||||
}
|
||||
@@ -26621,6 +26691,205 @@ function eval_pyson(value){
|
||||
this.copy_button.prop('disabled', !this.selected_records.length);
|
||||
this.status.text(String(this.group.length) + ' records');
|
||||
},
|
||||
_get_visible_record_rows: function() {
|
||||
var rows = [];
|
||||
if (!this.gridApi) {
|
||||
return rows;
|
||||
}
|
||||
var collect = node => {
|
||||
if (node && node.data && node.data.__kind == 'record') {
|
||||
rows.push(node.data);
|
||||
}
|
||||
};
|
||||
if (this.gridApi.forEachNodeAfterFilterAndSort) {
|
||||
this.gridApi.forEachNodeAfterFilterAndSort(collect);
|
||||
} else if (this.gridApi.forEachNodeAfterFilter) {
|
||||
this.gridApi.forEachNodeAfterFilter(collect);
|
||||
} else {
|
||||
(this._last_row_data || []).forEach(row => {
|
||||
if (row && row.__kind == 'record') {
|
||||
rows.push(row);
|
||||
}
|
||||
});
|
||||
}
|
||||
return rows;
|
||||
},
|
||||
_get_summary_badge_columns: function() {
|
||||
var visible_columns = {};
|
||||
var column_api = this.gridColumnApi || this.gridApi;
|
||||
if (column_api && column_api.getAllDisplayedColumns) {
|
||||
column_api.getAllDisplayedColumns().forEach(column => {
|
||||
if (column && column.getColId) {
|
||||
visible_columns[column.getColId()] = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
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];
|
||||
});
|
||||
},
|
||||
_render_summary_item: function(label, value, color) {
|
||||
var item = jQuery('<div/>', {
|
||||
'class': 'ag-grid-summary-item',
|
||||
});
|
||||
jQuery('<span/>', {
|
||||
'class': 'ag-grid-summary-label',
|
||||
'text': label,
|
||||
}).appendTo(item);
|
||||
var value_el = jQuery('<span/>', {
|
||||
'class': 'ag-grid-summary-value',
|
||||
'text': value,
|
||||
}).appendTo(item);
|
||||
if (color) {
|
||||
value_el.css('color', color);
|
||||
}
|
||||
return item;
|
||||
},
|
||||
_get_default_badge_summary_color: function(value) {
|
||||
var key = String(value || '').toLowerCase();
|
||||
var palette = {
|
||||
open: '#2563eb',
|
||||
physic: '#8b5cf6',
|
||||
physical: '#8b5cf6',
|
||||
scheduled: '#f59e0b',
|
||||
shipped: '#16a34a',
|
||||
unshipped: '#ef4444',
|
||||
done: '#16a34a',
|
||||
cancelled: '#ef4444',
|
||||
canceled: '#ef4444',
|
||||
draft: '#64748b',
|
||||
quote: '#2563eb',
|
||||
confirmed: '#16a34a',
|
||||
processing: '#f59e0b',
|
||||
};
|
||||
return palette[key] || '#0f766e';
|
||||
},
|
||||
_append_badge_summary_items: function(summary_items, rows, column, source) {
|
||||
var name = source && source.name ||
|
||||
column && column.attributes && column.attributes.name;
|
||||
if (!name) {
|
||||
return false;
|
||||
}
|
||||
var counts = {};
|
||||
var samples = {};
|
||||
var order = [];
|
||||
var empty = Sao.i18n.gettext('(Empty)');
|
||||
rows.forEach(row => {
|
||||
var value = row[name] ?
|
||||
this._normalize_badge_text_key(row[name]) : empty;
|
||||
if (value == empty) {
|
||||
return;
|
||||
}
|
||||
if (!Object.prototype.hasOwnProperty.call(counts, value)) {
|
||||
counts[value] = 0;
|
||||
samples[value] = row;
|
||||
order.push(value);
|
||||
}
|
||||
counts[value] += 1;
|
||||
});
|
||||
var color_order = this._get_badge_color_order(
|
||||
column && column.attributes && column.attributes.badge_colors);
|
||||
var color_order_lower = color_order.map(value =>
|
||||
String(value).toLowerCase());
|
||||
order.sort((a, b) => {
|
||||
var a_index = color_order.indexOf(a);
|
||||
var b_index = color_order.indexOf(b);
|
||||
if (a_index < 0) {
|
||||
a_index = color_order_lower.indexOf(
|
||||
String(a).toLowerCase());
|
||||
}
|
||||
if (b_index < 0) {
|
||||
b_index = color_order_lower.indexOf(
|
||||
String(b).toLowerCase());
|
||||
}
|
||||
if (a_index >= 0 || b_index >= 0) {
|
||||
return (a_index < 0 ? 999 : a_index) -
|
||||
(b_index < 0 ? 999 : b_index);
|
||||
}
|
||||
return counts[b] - counts[a] ||
|
||||
String(a).localeCompare(String(b), undefined, {
|
||||
numeric: true,
|
||||
sensitivity: 'base',
|
||||
});
|
||||
});
|
||||
order.forEach(value => {
|
||||
var colors = column ? this._get_badge_display_colors(
|
||||
column,
|
||||
samples[value] && samples[value].__record,
|
||||
value) : {};
|
||||
summary_items.push({
|
||||
label: value,
|
||||
count: counts[value],
|
||||
color: colors.color || colors.accent ||
|
||||
this._get_default_badge_summary_color(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;
|
||||
}
|
||||
var rows = this._get_visible_record_rows();
|
||||
var locale = Sao.i18n.BC47(Sao.i18n.getlang());
|
||||
this.summary_bar.empty();
|
||||
this.summary_bar.append(this._render_summary_item(
|
||||
Sao.i18n.gettext('Rows'),
|
||||
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;
|
||||
}
|
||||
this._append_badge_summary_items(
|
||||
summary_items, rows, null, source);
|
||||
});
|
||||
summary_items.forEach(item => {
|
||||
this.summary_bar.append(this._render_summary_item(
|
||||
item.label,
|
||||
item.count.toLocaleString(locale),
|
||||
item.color));
|
||||
});
|
||||
},
|
||||
on_copy: function() {
|
||||
var data = [];
|
||||
this.selected_records.forEach(record => {
|
||||
@@ -26739,6 +27008,7 @@ function eval_pyson(value){
|
||||
this._update_layout_button();
|
||||
this._render_filter_logic_panel();
|
||||
this._update_copy_state();
|
||||
this._update_summary_bar();
|
||||
if (this._has_active_sao_value_filters()) {
|
||||
this._apply_sao_value_filters({refreshRowData: false});
|
||||
}
|
||||
@@ -26765,6 +27035,8 @@ function eval_pyson(value){
|
||||
var screen_container = this.grid_host.closest('.screen-container');
|
||||
var toolbar_height = this.toolbar && this.toolbar.length ?
|
||||
Math.ceil(this.toolbar.outerHeight(true)) : 0;
|
||||
var summary_height = this.summary_bar && this.summary_bar.length ?
|
||||
Math.ceil(this.summary_bar.outerHeight(true)) : 0;
|
||||
var external_scroll_height = 20;
|
||||
var bottom_margin = 96;
|
||||
var available = window.innerHeight - rect.top -
|
||||
@@ -26774,7 +27046,7 @@ function eval_pyson(value){
|
||||
available = Math.min(
|
||||
available,
|
||||
window.innerHeight - content_rect.top - toolbar_height -
|
||||
external_scroll_height - bottom_margin);
|
||||
summary_height - external_scroll_height - bottom_margin);
|
||||
}
|
||||
var compact_min_height = 260;
|
||||
var readable_min_height = 420;
|
||||
@@ -26805,7 +27077,8 @@ function eval_pyson(value){
|
||||
width: available_width + 'px',
|
||||
maxWidth: available_width + 'px',
|
||||
});
|
||||
var container_height = height + toolbar_height + external_scroll_height;
|
||||
var container_height = height + toolbar_height + summary_height +
|
||||
external_scroll_height;
|
||||
this.el.css({
|
||||
height: container_height + 'px',
|
||||
minHeight: container_height + 'px',
|
||||
|
||||
@@ -11613,6 +11613,54 @@ html[theme="default"] .ag-grid-tree-grouping-panel input[type="checkbox"]:after
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.ag-grid-tree-summary {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
flex-wrap: wrap;
|
||||
gap: 0;
|
||||
min-height: 48px;
|
||||
margin: 0 0 8px;
|
||||
border: 1px solid #dfe8e3;
|
||||
border-radius: 6px;
|
||||
background: #ffffff;
|
||||
box-shadow: 0 1px 4px rgba(53, 81, 84, 0.06);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ag-grid-summary-item {
|
||||
display: flex;
|
||||
flex: 0 1 150px;
|
||||
min-width: 120px;
|
||||
max-width: 190px;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
gap: 3px;
|
||||
padding: 8px 18px;
|
||||
border-right: 1px solid #e7efeb;
|
||||
}
|
||||
|
||||
.ag-grid-summary-item:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.ag-grid-summary-label {
|
||||
min-width: 0;
|
||||
color: #64748b;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
line-height: 1.2;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.ag-grid-summary-value {
|
||||
color: #145369;
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
line-height: 1.15;
|
||||
}
|
||||
|
||||
.ag-grid-tree-host {
|
||||
flex: 0 0 auto;
|
||||
min-height: 520px;
|
||||
@@ -11794,10 +11842,10 @@ html[theme="default"] .ag-grid-tree-grouping-panel input[type="checkbox"]:after
|
||||
min-height: 22px;
|
||||
padding: 2px 10px;
|
||||
border-radius: 999px;
|
||||
background: #6c757d;
|
||||
color: #f7fbf9;
|
||||
background: #eef3f2;
|
||||
color: #355154;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
font-weight: 700;
|
||||
line-height: 1.35;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
@@ -12769,6 +12817,24 @@ html[data-theme-mode="dark"] .ag-grid-filter-logic-operator {
|
||||
color: #8fe1d8;
|
||||
}
|
||||
|
||||
html[data-theme-mode="dark"] .ag-grid-tree-summary {
|
||||
background: #151f1e;
|
||||
border-color: #2a403d;
|
||||
box-shadow: 0 8px 22px rgba(0, 0, 0, 0.24);
|
||||
}
|
||||
|
||||
html[data-theme-mode="dark"] .ag-grid-summary-item {
|
||||
border-right-color: #243735;
|
||||
}
|
||||
|
||||
html[data-theme-mode="dark"] .ag-grid-summary-label {
|
||||
color: #aebfba;
|
||||
}
|
||||
|
||||
html[data-theme-mode="dark"] .ag-grid-summary-value {
|
||||
color: #8fe1d8;
|
||||
}
|
||||
|
||||
html[data-theme-mode="dark"] .form-tolerance-gauge {
|
||||
color: #dce7e2;
|
||||
}
|
||||
|
||||
307
tryton-sao.js
307
tryton-sao.js
@@ -22624,6 +22624,9 @@ function eval_pyson(value){
|
||||
this.status = jQuery('<div/>', {
|
||||
'class': 'ag-grid-tree-status text-muted',
|
||||
}).appendTo(this.toolbar);
|
||||
this.summary_bar = jQuery('<div/>', {
|
||||
'class': 'ag-grid-tree-summary',
|
||||
}).appendTo(this.el);
|
||||
this.grid_host = jQuery('<div/>', {
|
||||
'class': 'ag-grid-theme-alpine ag-grid-tree-host',
|
||||
}).appendTo(this.el);
|
||||
@@ -22946,6 +22949,7 @@ function eval_pyson(value){
|
||||
if (!options.skipLayoutRefresh) {
|
||||
this._schedule_grid_layout_refresh();
|
||||
}
|
||||
this._update_summary_bar();
|
||||
},
|
||||
_on_grid_column_resized: function(params) {
|
||||
this._trace_aggrid_column_resize('event', params);
|
||||
@@ -24629,6 +24633,7 @@ function eval_pyson(value){
|
||||
onFilterChanged: () => {
|
||||
this._schedule_state_save();
|
||||
this._sync_selection_header_checkbox();
|
||||
this._update_summary_bar();
|
||||
},
|
||||
onColumnMoved: this._on_grid_column_layout_changed.bind(this),
|
||||
onColumnPinned: this._on_grid_column_layout_changed.bind(this),
|
||||
@@ -25220,6 +25225,7 @@ function eval_pyson(value){
|
||||
this._log_sao_value_filter_empty_result(this.group.slice());
|
||||
}
|
||||
this._resize_grid_host();
|
||||
this._update_summary_bar();
|
||||
this._schedule_grid_layout_refresh([0, 80]);
|
||||
});
|
||||
},
|
||||
@@ -25258,6 +25264,7 @@ function eval_pyson(value){
|
||||
this._refresh_grid_layout_after_row_data(row_data);
|
||||
this._sync_selection(selected);
|
||||
this._update_copy_state();
|
||||
this._update_summary_bar();
|
||||
},
|
||||
_toggle_sao_value_filter_mode: function() {
|
||||
this._set_sao_value_filter_mode(
|
||||
@@ -26061,6 +26068,17 @@ function eval_pyson(value){
|
||||
});
|
||||
return parsed;
|
||||
},
|
||||
_normalize_badge_text_key: function(text) {
|
||||
text = text === null || text === undefined ? '' : String(text);
|
||||
return text.replace(/^[^A-Za-z0-9]+/, '').trim();
|
||||
},
|
||||
_get_badge_color_order: function(colors) {
|
||||
return (colors || '').split(',').map(item => {
|
||||
var pair = item.split(':');
|
||||
return pair.length < 2 ? '' :
|
||||
this._normalize_badge_text_key(pair.shift());
|
||||
}).filter(Boolean);
|
||||
},
|
||||
_get_record_field_value: function(record, name) {
|
||||
if (!record || !name) {
|
||||
return '';
|
||||
@@ -26084,34 +26102,73 @@ function eval_pyson(value){
|
||||
color = color === null || color === undefined ? '' :
|
||||
String(color).trim();
|
||||
var palette = {
|
||||
red: '#e06a6a',
|
||||
danger: '#e06a6a',
|
||||
coral: '#e06a6a',
|
||||
orange: '#d99a2b',
|
||||
warning: '#d99a2b',
|
||||
amber: '#d99a2b',
|
||||
yellow: '#f1c40f',
|
||||
green: '#2b8c87',
|
||||
success: '#2b8c87',
|
||||
teal: '#2b8c87',
|
||||
blue: '#57c1b9',
|
||||
info: '#57c1b9',
|
||||
red: '#ef4444',
|
||||
danger: '#ef4444',
|
||||
coral: '#ef4444',
|
||||
orange: '#f59e0b',
|
||||
warning: '#f59e0b',
|
||||
amber: '#f59e0b',
|
||||
yellow: '#eab308',
|
||||
green: '#16a34a',
|
||||
success: '#16a34a',
|
||||
teal: '#0f766e',
|
||||
blue: '#2563eb',
|
||||
info: '#2563eb',
|
||||
purple: '#8b5cf6',
|
||||
violet: '#8b5cf6',
|
||||
gray: '#6c757d',
|
||||
grey: '#6c757d',
|
||||
muted: '#6c757d',
|
||||
};
|
||||
return palette[color.toLowerCase()] || color;
|
||||
},
|
||||
_hex_to_rgb_badge_color: function(color) {
|
||||
color = this._normalize_badge_color(color);
|
||||
var match = /^#?([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(color || '');
|
||||
if (!match) {
|
||||
return null;
|
||||
}
|
||||
var hex = match[1];
|
||||
if (hex.length == 3) {
|
||||
hex = hex.split('').map(part => part + part).join('');
|
||||
}
|
||||
return {
|
||||
r: parseInt(hex.slice(0, 2), 16),
|
||||
g: parseInt(hex.slice(2, 4), 16),
|
||||
b: parseInt(hex.slice(4, 6), 16),
|
||||
};
|
||||
},
|
||||
_rgb_to_badge_color: function(rgb) {
|
||||
var part = value => Math.max(0, Math.min(255, Math.round(value)))
|
||||
.toString(16).padStart(2, '0');
|
||||
return '#' + part(rgb.r) + part(rgb.g) + part(rgb.b);
|
||||
},
|
||||
_mix_badge_color: function(color, mix_with, weight) {
|
||||
var source = this._hex_to_rgb_badge_color(color);
|
||||
var target = this._hex_to_rgb_badge_color(mix_with);
|
||||
if (!source || !target) {
|
||||
return '';
|
||||
}
|
||||
return this._rgb_to_badge_color({
|
||||
r: source.r * (1 - weight) + target.r * weight,
|
||||
g: source.g * (1 - weight) + target.g * weight,
|
||||
b: source.b * (1 - weight) + target.b * weight,
|
||||
});
|
||||
},
|
||||
_get_badge_colors: function(column, record, text) {
|
||||
var attributes = column.attributes || {};
|
||||
var color = '';
|
||||
var text_color = '';
|
||||
var mapped = this._parse_badge_colors(attributes.badge_colors);
|
||||
var normalized_text = this._normalize_badge_text_key(text);
|
||||
if (Object.prototype.hasOwnProperty.call(mapped, text)) {
|
||||
color = mapped[text];
|
||||
} else if (Object.prototype.hasOwnProperty.call(
|
||||
mapped, String(text).toLowerCase())) {
|
||||
color = mapped[String(text).toLowerCase()];
|
||||
mapped, normalized_text)) {
|
||||
color = mapped[normalized_text];
|
||||
} else if (Object.prototype.hasOwnProperty.call(
|
||||
mapped, String(normalized_text).toLowerCase())) {
|
||||
color = mapped[String(normalized_text).toLowerCase()];
|
||||
}
|
||||
if (!color && attributes.badge_color_field) {
|
||||
color = this._get_record_field_value(
|
||||
@@ -26138,6 +26195,19 @@ function eval_pyson(value){
|
||||
color: this._normalize_badge_color(text_color),
|
||||
};
|
||||
},
|
||||
_get_badge_display_colors: function(column, record, text) {
|
||||
var colors = this._get_badge_colors(column, record, text);
|
||||
var accent = colors.color || colors.background;
|
||||
if (!accent) {
|
||||
return colors;
|
||||
}
|
||||
return {
|
||||
background: this._mix_badge_color(accent, '#ffffff', 0.86) ||
|
||||
colors.background,
|
||||
color: colors.color || accent,
|
||||
accent: accent,
|
||||
};
|
||||
},
|
||||
_render_badge_cell: function(column, record) {
|
||||
var text = this._get_column_text_value(column, record);
|
||||
var cell = jQuery('<div/>', {
|
||||
@@ -26153,7 +26223,7 @@ function eval_pyson(value){
|
||||
if (parseInt(column.attributes.badge_bold || '0', 10)) {
|
||||
badge.addClass('ag-grid-badge-bold');
|
||||
}
|
||||
var colors = this._get_badge_colors(column, record, text);
|
||||
var colors = this._get_badge_display_colors(column, record, text);
|
||||
if (colors.background) {
|
||||
badge.css('background-color', colors.background);
|
||||
}
|
||||
@@ -26621,6 +26691,205 @@ function eval_pyson(value){
|
||||
this.copy_button.prop('disabled', !this.selected_records.length);
|
||||
this.status.text(String(this.group.length) + ' records');
|
||||
},
|
||||
_get_visible_record_rows: function() {
|
||||
var rows = [];
|
||||
if (!this.gridApi) {
|
||||
return rows;
|
||||
}
|
||||
var collect = node => {
|
||||
if (node && node.data && node.data.__kind == 'record') {
|
||||
rows.push(node.data);
|
||||
}
|
||||
};
|
||||
if (this.gridApi.forEachNodeAfterFilterAndSort) {
|
||||
this.gridApi.forEachNodeAfterFilterAndSort(collect);
|
||||
} else if (this.gridApi.forEachNodeAfterFilter) {
|
||||
this.gridApi.forEachNodeAfterFilter(collect);
|
||||
} else {
|
||||
(this._last_row_data || []).forEach(row => {
|
||||
if (row && row.__kind == 'record') {
|
||||
rows.push(row);
|
||||
}
|
||||
});
|
||||
}
|
||||
return rows;
|
||||
},
|
||||
_get_summary_badge_columns: function() {
|
||||
var visible_columns = {};
|
||||
var column_api = this.gridColumnApi || this.gridApi;
|
||||
if (column_api && column_api.getAllDisplayedColumns) {
|
||||
column_api.getAllDisplayedColumns().forEach(column => {
|
||||
if (column && column.getColId) {
|
||||
visible_columns[column.getColId()] = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
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];
|
||||
});
|
||||
},
|
||||
_render_summary_item: function(label, value, color) {
|
||||
var item = jQuery('<div/>', {
|
||||
'class': 'ag-grid-summary-item',
|
||||
});
|
||||
jQuery('<span/>', {
|
||||
'class': 'ag-grid-summary-label',
|
||||
'text': label,
|
||||
}).appendTo(item);
|
||||
var value_el = jQuery('<span/>', {
|
||||
'class': 'ag-grid-summary-value',
|
||||
'text': value,
|
||||
}).appendTo(item);
|
||||
if (color) {
|
||||
value_el.css('color', color);
|
||||
}
|
||||
return item;
|
||||
},
|
||||
_get_default_badge_summary_color: function(value) {
|
||||
var key = String(value || '').toLowerCase();
|
||||
var palette = {
|
||||
open: '#2563eb',
|
||||
physic: '#8b5cf6',
|
||||
physical: '#8b5cf6',
|
||||
scheduled: '#f59e0b',
|
||||
shipped: '#16a34a',
|
||||
unshipped: '#ef4444',
|
||||
done: '#16a34a',
|
||||
cancelled: '#ef4444',
|
||||
canceled: '#ef4444',
|
||||
draft: '#64748b',
|
||||
quote: '#2563eb',
|
||||
confirmed: '#16a34a',
|
||||
processing: '#f59e0b',
|
||||
};
|
||||
return palette[key] || '#0f766e';
|
||||
},
|
||||
_append_badge_summary_items: function(summary_items, rows, column, source) {
|
||||
var name = source && source.name ||
|
||||
column && column.attributes && column.attributes.name;
|
||||
if (!name) {
|
||||
return false;
|
||||
}
|
||||
var counts = {};
|
||||
var samples = {};
|
||||
var order = [];
|
||||
var empty = Sao.i18n.gettext('(Empty)');
|
||||
rows.forEach(row => {
|
||||
var value = row[name] ?
|
||||
this._normalize_badge_text_key(row[name]) : empty;
|
||||
if (value == empty) {
|
||||
return;
|
||||
}
|
||||
if (!Object.prototype.hasOwnProperty.call(counts, value)) {
|
||||
counts[value] = 0;
|
||||
samples[value] = row;
|
||||
order.push(value);
|
||||
}
|
||||
counts[value] += 1;
|
||||
});
|
||||
var color_order = this._get_badge_color_order(
|
||||
column && column.attributes && column.attributes.badge_colors);
|
||||
var color_order_lower = color_order.map(value =>
|
||||
String(value).toLowerCase());
|
||||
order.sort((a, b) => {
|
||||
var a_index = color_order.indexOf(a);
|
||||
var b_index = color_order.indexOf(b);
|
||||
if (a_index < 0) {
|
||||
a_index = color_order_lower.indexOf(
|
||||
String(a).toLowerCase());
|
||||
}
|
||||
if (b_index < 0) {
|
||||
b_index = color_order_lower.indexOf(
|
||||
String(b).toLowerCase());
|
||||
}
|
||||
if (a_index >= 0 || b_index >= 0) {
|
||||
return (a_index < 0 ? 999 : a_index) -
|
||||
(b_index < 0 ? 999 : b_index);
|
||||
}
|
||||
return counts[b] - counts[a] ||
|
||||
String(a).localeCompare(String(b), undefined, {
|
||||
numeric: true,
|
||||
sensitivity: 'base',
|
||||
});
|
||||
});
|
||||
order.forEach(value => {
|
||||
var colors = column ? this._get_badge_display_colors(
|
||||
column,
|
||||
samples[value] && samples[value].__record,
|
||||
value) : {};
|
||||
summary_items.push({
|
||||
label: value,
|
||||
count: counts[value],
|
||||
color: colors.color || colors.accent ||
|
||||
this._get_default_badge_summary_color(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;
|
||||
}
|
||||
var rows = this._get_visible_record_rows();
|
||||
var locale = Sao.i18n.BC47(Sao.i18n.getlang());
|
||||
this.summary_bar.empty();
|
||||
this.summary_bar.append(this._render_summary_item(
|
||||
Sao.i18n.gettext('Rows'),
|
||||
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;
|
||||
}
|
||||
this._append_badge_summary_items(
|
||||
summary_items, rows, null, source);
|
||||
});
|
||||
summary_items.forEach(item => {
|
||||
this.summary_bar.append(this._render_summary_item(
|
||||
item.label,
|
||||
item.count.toLocaleString(locale),
|
||||
item.color));
|
||||
});
|
||||
},
|
||||
on_copy: function() {
|
||||
var data = [];
|
||||
this.selected_records.forEach(record => {
|
||||
@@ -26739,6 +27008,7 @@ function eval_pyson(value){
|
||||
this._update_layout_button();
|
||||
this._render_filter_logic_panel();
|
||||
this._update_copy_state();
|
||||
this._update_summary_bar();
|
||||
if (this._has_active_sao_value_filters()) {
|
||||
this._apply_sao_value_filters({refreshRowData: false});
|
||||
}
|
||||
@@ -26765,6 +27035,8 @@ function eval_pyson(value){
|
||||
var screen_container = this.grid_host.closest('.screen-container');
|
||||
var toolbar_height = this.toolbar && this.toolbar.length ?
|
||||
Math.ceil(this.toolbar.outerHeight(true)) : 0;
|
||||
var summary_height = this.summary_bar && this.summary_bar.length ?
|
||||
Math.ceil(this.summary_bar.outerHeight(true)) : 0;
|
||||
var external_scroll_height = 20;
|
||||
var bottom_margin = 96;
|
||||
var available = window.innerHeight - rect.top -
|
||||
@@ -26774,7 +27046,7 @@ function eval_pyson(value){
|
||||
available = Math.min(
|
||||
available,
|
||||
window.innerHeight - content_rect.top - toolbar_height -
|
||||
external_scroll_height - bottom_margin);
|
||||
summary_height - external_scroll_height - bottom_margin);
|
||||
}
|
||||
var compact_min_height = 260;
|
||||
var readable_min_height = 420;
|
||||
@@ -26805,7 +27077,8 @@ function eval_pyson(value){
|
||||
width: available_width + 'px',
|
||||
maxWidth: available_width + 'px',
|
||||
});
|
||||
var container_height = height + toolbar_height + external_scroll_height;
|
||||
var container_height = height + toolbar_height + summary_height +
|
||||
external_scroll_height;
|
||||
this.el.css({
|
||||
height: container_height + 'px',
|
||||
minHeight: container_height + 'px',
|
||||
|
||||
Reference in New Issue
Block a user