From 66ac2d0e0a85b01af8470a2a40accf1515318a72 Mon Sep 17 00:00:00 2001 From: laurentbarontini Date: Sun, 17 May 2026 19:12:46 +0200 Subject: [PATCH] Jauge tolerance --- dist/tryton-sao.css | 150 ++++++++++++++++++++++++++++++ dist/tryton-sao.js | 220 ++++++++++++++++++++++++++++++++++++++++++++ tryton-sao.css | 150 ++++++++++++++++++++++++++++++ tryton-sao.js | 220 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 740 insertions(+) diff --git a/dist/tryton-sao.css b/dist/tryton-sao.css index 06f5899..4c4c983 100644 --- a/dist/tryton-sao.css +++ b/dist/tryton-sao.css @@ -10362,6 +10362,110 @@ input.column-boolean { .progress { margin-bottom: 0px; } +.form-tolerance-gauge { + --tolerance-gauge-value: 50%; + --tolerance-gauge-center: 50%; + --tolerance-gauge-fill-left: 50%; + --tolerance-gauge-fill-width: 0%; + min-width: 180px; + color: #355154; +} +.form-tolerance-gauge-labels { + display: grid; + grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); + align-items: end; + gap: 8px; + margin-bottom: 4px; + color: #6a7b7a; + font-size: 11px; + line-height: 1.2; +} +.form-tolerance-gauge-label { + display: block; + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.form-tolerance-gauge-label-center { + color: #2b8c87; + font-weight: 600; + text-align: center; +} +.form-tolerance-gauge-label-max { + text-align: right; + text-align: end; +} +.form-tolerance-gauge-track { + position: relative; + height: 12px; + overflow: visible; + border: 1px solid #d6e4df; + border-radius: 8px; + background: linear-gradient(180deg, #f6fbf9 0%, #e7f2ed 100%); + box-shadow: inset 0 1px 2px rgba(53, 81, 84, 0.08); +} +.form-tolerance-gauge-fill { + position: absolute; + top: 2px; + bottom: 2px; + left: var(--tolerance-gauge-fill-left); + width: var(--tolerance-gauge-fill-width); + border-radius: 6px; + background: linear-gradient(90deg, #8fd4cc 0%, #2b8c87 100%); + box-shadow: 0 0 0 1px rgba(43, 140, 135, 0.12); +} +.form-tolerance-gauge-center-tick { + position: absolute; + top: -4px; + bottom: -4px; + left: var(--tolerance-gauge-center); + width: 2px; + border-radius: 2px; + background: #2b8c87; + transform: translateX(-1px); +} +.form-tolerance-gauge-marker { + position: absolute; + top: 50%; + left: var(--tolerance-gauge-value); + width: 12px; + height: 12px; + border: 2px solid #ffffff; + border-radius: 50%; + background: #2b8c87; + box-shadow: 0 2px 6px rgba(53, 81, 84, 0.28); + transform: translate(-50%, -50%); +} +.form-tolerance-gauge-value { + margin-top: 5px; + overflow: hidden; + color: #355154; + font-size: 12px; + font-weight: 600; + line-height: 1.2; + text-align: center; + text-overflow: ellipsis; + white-space: nowrap; +} +.form-tolerance-gauge.outside .form-tolerance-gauge-fill, +.form-tolerance-gauge.outside .form-tolerance-gauge-marker { + background: #c94f4f; +} +.form-tolerance-gauge.outside .form-tolerance-gauge-value { + color: #9d3d3d; +} +.column-tolerance-gauge.form-tolerance-gauge { + min-width: 140px; + padding: 2px 4px; +} +.column-tolerance-gauge .form-tolerance-gauge-labels { + display: none; +} +.column-tolerance-gauge .form-tolerance-gauge-value { + margin-top: 3px; + font-size: 11px; +} .window-form .window-form-toolbar { text-align: right; text-align: end; @@ -12550,6 +12654,52 @@ html[data-theme-mode="dark"] .ag-grid-filter-logic-operator { color: #8fe1d8; } +html[data-theme-mode="dark"] .form-tolerance-gauge { + color: #dce7e2; +} + +html[data-theme-mode="dark"] .form-tolerance-gauge-labels { + color: #aebfba; +} + +html[data-theme-mode="dark"] .form-tolerance-gauge-label-center { + color: #8fe1d8; +} + +html[data-theme-mode="dark"] .form-tolerance-gauge-track { + border-color: #304643; + background: linear-gradient(180deg, #213130 0%, #1a2726 100%); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.28); +} + +html[data-theme-mode="dark"] .form-tolerance-gauge-fill { + background: linear-gradient(90deg, #57c1b9 0%, #2b8c87 100%); + box-shadow: 0 0 0 1px rgba(143, 225, 216, 0.18); +} + +html[data-theme-mode="dark"] .form-tolerance-gauge-center-tick, +html[data-theme-mode="dark"] .form-tolerance-gauge-marker { + background: #57c1b9; +} + +html[data-theme-mode="dark"] .form-tolerance-gauge-marker { + border-color: #162220; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.34); +} + +html[data-theme-mode="dark"] .form-tolerance-gauge-value { + color: #dce7e2; +} + +html[data-theme-mode="dark"] .form-tolerance-gauge.outside .form-tolerance-gauge-fill, +html[data-theme-mode="dark"] .form-tolerance-gauge.outside .form-tolerance-gauge-marker { + background: #e06a6a; +} + +html[data-theme-mode="dark"] .form-tolerance-gauge.outside .form-tolerance-gauge-value { + color: #ffb1b1; +} + html[data-theme-mode="dark"] .ag-grid-tree-host { border-color: #2a3f3d; --ag-background-color: #101817; diff --git a/dist/tryton-sao.js b/dist/tryton-sao.js index 2d0fe7d..4c0a020 100644 --- a/dist/tryton-sao.js +++ b/dist/tryton-sao.js @@ -19840,6 +19840,169 @@ function eval_pyson(value){ } }); + Sao.View.ToleranceGaugeMixin = { + _number: function(value) { + if ((value === null) || (value === undefined) || (value === '')) { + return null; + } + value = Number(value); + if (isNaN(value)) { + return null; + } + return value; + }, + _field_value: function(record, name) { + if (!name || !record || !record.model.fields[name]) { + return null; + } + return this._number(record.model.fields[name].get(record)); + }, + _bound_value: function(record, literal, field_name, fallback) { + var value = this._field_value(record, field_name); + if (value === null) { + value = this._number(literal); + } + if (value === null) { + value = fallback; + } + return value; + }, + _bounds: function(record) { + var min = this._bound_value( + record, this.attributes.min, this.attributes.min_field, null); + var max = this._bound_value( + record, this.attributes.max, this.attributes.max_field, null); + if ((min === null) && (max !== null)) { + min = -Math.abs(max); + } + if ((max === null) && (min !== null)) { + max = Math.abs(min); + } + if (min === null) { + min = -1; + } + if (max === null) { + max = 1; + } + if (min == max) { + min -= 1; + max += 1; + } + if (min > max) { + var swap = min; + min = max; + max = swap; + } + return [min, max]; + }, + _position: function(value, min, max) { + return Math.max(0, Math.min(100, ((value - min) / (max - min)) * 100)); + }, + _format_number: function(value) { + if ((value === null) || (value === undefined) || isNaN(value)) { + return ''; + } + return (value * Number(this.attributes.factor || 1)).toLocaleString( + Sao.i18n.BC47(Sao.i18n.getlang()), { + maximumFractionDigits: Number( + this.attributes.digits || 6), + useGrouping: true + }); + }, + _set_gauge: function(record, value, text) { + var bounds = this._bounds(record); + var min = bounds[0]; + var max = bounds[1]; + var center = this._number(this.attributes.center); + if (center === null) { + center = 0; + } + var current = this._number(value); + if (current === null) { + current = center; + } + + var current_position = this._position(current, min, max); + var center_position = this._position(center, min, max); + var fill_left = Math.min(current_position, center_position); + var fill_width = Math.abs(current_position - center_position); + var outside = (current < min) || (current > max); + var title = text || this._format_number(current); + + this.el.toggleClass('outside', outside); + this.el.toggleClass('under', current < min); + this.el.toggleClass('over', current > max); + this.el.css('--tolerance-gauge-value', current_position + '%'); + this.el.css('--tolerance-gauge-center', center_position + '%'); + this.el.css('--tolerance-gauge-fill-left', fill_left + '%'); + this.el.css('--tolerance-gauge-fill-width', fill_width + '%'); + this.min_label.text(this._format_number(min)); + this.center_label.text(this._format_number(center)); + this.max_label.text(this._format_number(max)); + this.value_label.text(title); + this.track.attr('aria-valuemin', min); + this.track.attr('aria-valuemax', max); + this.track.attr('aria-valuenow', current); + this.track.attr('aria-valuetext', title); + this.el.attr('title', title); + } + }; + + Sao.View.Form.ToleranceGauge = Sao.class_(Sao.View.Form.Widget, { + class_: 'form-tolerance-gauge', + init: function(view, attributes) { + Sao.View.Form.ToleranceGauge._super.init.call( + this, view, attributes); + this.el = jQuery('
', { + 'class': this.class_ + }); + var labels = jQuery('
', { + 'class': this.class_ + '-labels' + }).appendTo(this.el); + this.min_label = jQuery('', { + 'class': this.class_ + '-label ' + this.class_ + '-label-min' + }).appendTo(labels); + this.center_label = jQuery('', { + 'class': this.class_ + '-label ' + this.class_ + '-label-center' + }).appendTo(labels); + this.max_label = jQuery('', { + 'class': this.class_ + '-label ' + this.class_ + '-label-max' + }).appendTo(labels); + this.track = jQuery('
', { + 'class': this.class_ + '-track', + 'role': 'meter', + 'tabindex': 0 + }).appendTo(this.el); + jQuery('
', { + 'class': this.class_ + '-fill' + }).appendTo(this.track); + jQuery('
', { + 'class': this.class_ + '-center-tick' + }).appendTo(this.track); + jQuery('
', { + 'class': this.class_ + '-marker' + }).appendTo(this.track); + this.value_label = jQuery('
', { + 'class': this.class_ + '-value' + }).appendTo(this.el); + }, + display: function() { + Sao.View.Form.ToleranceGauge._super.display.call(this); + var record = this.record; + var field = this.field; + var value = 0; + var text = ''; + if (field) { + value = field.get(record); + text = field.get_client(record); + } + this._set_gauge(record, value, text); + } + }); + jQuery.extend( + Sao.View.Form.ToleranceGauge.prototype, + Sao.View.ToleranceGaugeMixin); + Sao.View.Form.Dict = Sao.class_(Sao.View.Form.Widget, { class_: 'form-dict', expand: true, @@ -21685,6 +21848,7 @@ function eval_pyson(value){ 'time': Sao.View.Form.Time, 'timedelta': Sao.View.Form.TimeDelta, 'timestamp': Sao.View.Form.DateTime, + 'tolerance_gauge': Sao.View.Form.ToleranceGauge, 'url': Sao.View.Form.URL, }; Sao.View.FormXMLViewParser.WIDGETS['html_viewer'] = Sao.View.Form.HTMLViewer; @@ -29510,6 +29674,61 @@ function eval_pyson(value){ } }); + Sao.View.Tree.ToleranceGauge = Sao.class_(Sao.View.Tree.CharColumn, { + class_: 'column-tolerance-gauge form-tolerance-gauge', + get_cell: function() { + var cell = jQuery('
', { + 'class': this.class_, + 'tabindex': 0 + }); + var labels = jQuery('
', { + 'class': 'form-tolerance-gauge-labels' + }).appendTo(cell); + jQuery('', { + 'class': 'form-tolerance-gauge-label form-tolerance-gauge-label-min' + }).appendTo(labels); + jQuery('', { + 'class': 'form-tolerance-gauge-label form-tolerance-gauge-label-center' + }).appendTo(labels); + jQuery('', { + 'class': 'form-tolerance-gauge-label form-tolerance-gauge-label-max' + }).appendTo(labels); + var track = jQuery('
', { + 'class': 'form-tolerance-gauge-track', + 'role': 'meter' + }).appendTo(cell); + jQuery('
', { + 'class': 'form-tolerance-gauge-fill' + }).appendTo(track); + jQuery('
', { + 'class': 'form-tolerance-gauge-center-tick' + }).appendTo(track); + jQuery('
', { + 'class': 'form-tolerance-gauge-marker' + }).appendTo(track); + jQuery('
', { + 'class': 'form-tolerance-gauge-value' + }).appendTo(cell); + return cell; + }, + get_textual_value: function(record) { + return this.field.get_client(record); + }, + update_text: function(cell, record) { + this.el = cell; + this.min_label = cell.find('.form-tolerance-gauge-label-min'); + this.center_label = cell.find('.form-tolerance-gauge-label-center'); + this.max_label = cell.find('.form-tolerance-gauge-label-max'); + this.track = cell.find('.form-tolerance-gauge-track'); + this.value_label = cell.find('.form-tolerance-gauge-value'); + this._set_gauge( + record, this.field.get(record), this.get_textual_value(record)); + } + }); + jQuery.extend( + Sao.View.Tree.ToleranceGauge.prototype, + Sao.View.ToleranceGaugeMixin); + Sao.View.Tree.ButtonColumn = Sao.class_(Object, { init: function(view, attributes) { this.view = view; @@ -29597,6 +29816,7 @@ function eval_pyson(value){ 'text': Sao.View.Tree.TextColum, 'time': Sao.View.Tree.TimeColumn, 'timedelta': Sao.View.Tree.TimeDeltaColumn, + 'tolerance_gauge': Sao.View.Tree.ToleranceGauge, 'url': Sao.View.Tree.URLColumn, }; diff --git a/tryton-sao.css b/tryton-sao.css index 06f5899..4c4c983 100644 --- a/tryton-sao.css +++ b/tryton-sao.css @@ -10362,6 +10362,110 @@ input.column-boolean { .progress { margin-bottom: 0px; } +.form-tolerance-gauge { + --tolerance-gauge-value: 50%; + --tolerance-gauge-center: 50%; + --tolerance-gauge-fill-left: 50%; + --tolerance-gauge-fill-width: 0%; + min-width: 180px; + color: #355154; +} +.form-tolerance-gauge-labels { + display: grid; + grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); + align-items: end; + gap: 8px; + margin-bottom: 4px; + color: #6a7b7a; + font-size: 11px; + line-height: 1.2; +} +.form-tolerance-gauge-label { + display: block; + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.form-tolerance-gauge-label-center { + color: #2b8c87; + font-weight: 600; + text-align: center; +} +.form-tolerance-gauge-label-max { + text-align: right; + text-align: end; +} +.form-tolerance-gauge-track { + position: relative; + height: 12px; + overflow: visible; + border: 1px solid #d6e4df; + border-radius: 8px; + background: linear-gradient(180deg, #f6fbf9 0%, #e7f2ed 100%); + box-shadow: inset 0 1px 2px rgba(53, 81, 84, 0.08); +} +.form-tolerance-gauge-fill { + position: absolute; + top: 2px; + bottom: 2px; + left: var(--tolerance-gauge-fill-left); + width: var(--tolerance-gauge-fill-width); + border-radius: 6px; + background: linear-gradient(90deg, #8fd4cc 0%, #2b8c87 100%); + box-shadow: 0 0 0 1px rgba(43, 140, 135, 0.12); +} +.form-tolerance-gauge-center-tick { + position: absolute; + top: -4px; + bottom: -4px; + left: var(--tolerance-gauge-center); + width: 2px; + border-radius: 2px; + background: #2b8c87; + transform: translateX(-1px); +} +.form-tolerance-gauge-marker { + position: absolute; + top: 50%; + left: var(--tolerance-gauge-value); + width: 12px; + height: 12px; + border: 2px solid #ffffff; + border-radius: 50%; + background: #2b8c87; + box-shadow: 0 2px 6px rgba(53, 81, 84, 0.28); + transform: translate(-50%, -50%); +} +.form-tolerance-gauge-value { + margin-top: 5px; + overflow: hidden; + color: #355154; + font-size: 12px; + font-weight: 600; + line-height: 1.2; + text-align: center; + text-overflow: ellipsis; + white-space: nowrap; +} +.form-tolerance-gauge.outside .form-tolerance-gauge-fill, +.form-tolerance-gauge.outside .form-tolerance-gauge-marker { + background: #c94f4f; +} +.form-tolerance-gauge.outside .form-tolerance-gauge-value { + color: #9d3d3d; +} +.column-tolerance-gauge.form-tolerance-gauge { + min-width: 140px; + padding: 2px 4px; +} +.column-tolerance-gauge .form-tolerance-gauge-labels { + display: none; +} +.column-tolerance-gauge .form-tolerance-gauge-value { + margin-top: 3px; + font-size: 11px; +} .window-form .window-form-toolbar { text-align: right; text-align: end; @@ -12550,6 +12654,52 @@ html[data-theme-mode="dark"] .ag-grid-filter-logic-operator { color: #8fe1d8; } +html[data-theme-mode="dark"] .form-tolerance-gauge { + color: #dce7e2; +} + +html[data-theme-mode="dark"] .form-tolerance-gauge-labels { + color: #aebfba; +} + +html[data-theme-mode="dark"] .form-tolerance-gauge-label-center { + color: #8fe1d8; +} + +html[data-theme-mode="dark"] .form-tolerance-gauge-track { + border-color: #304643; + background: linear-gradient(180deg, #213130 0%, #1a2726 100%); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.28); +} + +html[data-theme-mode="dark"] .form-tolerance-gauge-fill { + background: linear-gradient(90deg, #57c1b9 0%, #2b8c87 100%); + box-shadow: 0 0 0 1px rgba(143, 225, 216, 0.18); +} + +html[data-theme-mode="dark"] .form-tolerance-gauge-center-tick, +html[data-theme-mode="dark"] .form-tolerance-gauge-marker { + background: #57c1b9; +} + +html[data-theme-mode="dark"] .form-tolerance-gauge-marker { + border-color: #162220; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.34); +} + +html[data-theme-mode="dark"] .form-tolerance-gauge-value { + color: #dce7e2; +} + +html[data-theme-mode="dark"] .form-tolerance-gauge.outside .form-tolerance-gauge-fill, +html[data-theme-mode="dark"] .form-tolerance-gauge.outside .form-tolerance-gauge-marker { + background: #e06a6a; +} + +html[data-theme-mode="dark"] .form-tolerance-gauge.outside .form-tolerance-gauge-value { + color: #ffb1b1; +} + html[data-theme-mode="dark"] .ag-grid-tree-host { border-color: #2a3f3d; --ag-background-color: #101817; diff --git a/tryton-sao.js b/tryton-sao.js index 2d0fe7d..4c0a020 100644 --- a/tryton-sao.js +++ b/tryton-sao.js @@ -19840,6 +19840,169 @@ function eval_pyson(value){ } }); + Sao.View.ToleranceGaugeMixin = { + _number: function(value) { + if ((value === null) || (value === undefined) || (value === '')) { + return null; + } + value = Number(value); + if (isNaN(value)) { + return null; + } + return value; + }, + _field_value: function(record, name) { + if (!name || !record || !record.model.fields[name]) { + return null; + } + return this._number(record.model.fields[name].get(record)); + }, + _bound_value: function(record, literal, field_name, fallback) { + var value = this._field_value(record, field_name); + if (value === null) { + value = this._number(literal); + } + if (value === null) { + value = fallback; + } + return value; + }, + _bounds: function(record) { + var min = this._bound_value( + record, this.attributes.min, this.attributes.min_field, null); + var max = this._bound_value( + record, this.attributes.max, this.attributes.max_field, null); + if ((min === null) && (max !== null)) { + min = -Math.abs(max); + } + if ((max === null) && (min !== null)) { + max = Math.abs(min); + } + if (min === null) { + min = -1; + } + if (max === null) { + max = 1; + } + if (min == max) { + min -= 1; + max += 1; + } + if (min > max) { + var swap = min; + min = max; + max = swap; + } + return [min, max]; + }, + _position: function(value, min, max) { + return Math.max(0, Math.min(100, ((value - min) / (max - min)) * 100)); + }, + _format_number: function(value) { + if ((value === null) || (value === undefined) || isNaN(value)) { + return ''; + } + return (value * Number(this.attributes.factor || 1)).toLocaleString( + Sao.i18n.BC47(Sao.i18n.getlang()), { + maximumFractionDigits: Number( + this.attributes.digits || 6), + useGrouping: true + }); + }, + _set_gauge: function(record, value, text) { + var bounds = this._bounds(record); + var min = bounds[0]; + var max = bounds[1]; + var center = this._number(this.attributes.center); + if (center === null) { + center = 0; + } + var current = this._number(value); + if (current === null) { + current = center; + } + + var current_position = this._position(current, min, max); + var center_position = this._position(center, min, max); + var fill_left = Math.min(current_position, center_position); + var fill_width = Math.abs(current_position - center_position); + var outside = (current < min) || (current > max); + var title = text || this._format_number(current); + + this.el.toggleClass('outside', outside); + this.el.toggleClass('under', current < min); + this.el.toggleClass('over', current > max); + this.el.css('--tolerance-gauge-value', current_position + '%'); + this.el.css('--tolerance-gauge-center', center_position + '%'); + this.el.css('--tolerance-gauge-fill-left', fill_left + '%'); + this.el.css('--tolerance-gauge-fill-width', fill_width + '%'); + this.min_label.text(this._format_number(min)); + this.center_label.text(this._format_number(center)); + this.max_label.text(this._format_number(max)); + this.value_label.text(title); + this.track.attr('aria-valuemin', min); + this.track.attr('aria-valuemax', max); + this.track.attr('aria-valuenow', current); + this.track.attr('aria-valuetext', title); + this.el.attr('title', title); + } + }; + + Sao.View.Form.ToleranceGauge = Sao.class_(Sao.View.Form.Widget, { + class_: 'form-tolerance-gauge', + init: function(view, attributes) { + Sao.View.Form.ToleranceGauge._super.init.call( + this, view, attributes); + this.el = jQuery('
', { + 'class': this.class_ + }); + var labels = jQuery('
', { + 'class': this.class_ + '-labels' + }).appendTo(this.el); + this.min_label = jQuery('', { + 'class': this.class_ + '-label ' + this.class_ + '-label-min' + }).appendTo(labels); + this.center_label = jQuery('', { + 'class': this.class_ + '-label ' + this.class_ + '-label-center' + }).appendTo(labels); + this.max_label = jQuery('', { + 'class': this.class_ + '-label ' + this.class_ + '-label-max' + }).appendTo(labels); + this.track = jQuery('
', { + 'class': this.class_ + '-track', + 'role': 'meter', + 'tabindex': 0 + }).appendTo(this.el); + jQuery('
', { + 'class': this.class_ + '-fill' + }).appendTo(this.track); + jQuery('
', { + 'class': this.class_ + '-center-tick' + }).appendTo(this.track); + jQuery('
', { + 'class': this.class_ + '-marker' + }).appendTo(this.track); + this.value_label = jQuery('
', { + 'class': this.class_ + '-value' + }).appendTo(this.el); + }, + display: function() { + Sao.View.Form.ToleranceGauge._super.display.call(this); + var record = this.record; + var field = this.field; + var value = 0; + var text = ''; + if (field) { + value = field.get(record); + text = field.get_client(record); + } + this._set_gauge(record, value, text); + } + }); + jQuery.extend( + Sao.View.Form.ToleranceGauge.prototype, + Sao.View.ToleranceGaugeMixin); + Sao.View.Form.Dict = Sao.class_(Sao.View.Form.Widget, { class_: 'form-dict', expand: true, @@ -21685,6 +21848,7 @@ function eval_pyson(value){ 'time': Sao.View.Form.Time, 'timedelta': Sao.View.Form.TimeDelta, 'timestamp': Sao.View.Form.DateTime, + 'tolerance_gauge': Sao.View.Form.ToleranceGauge, 'url': Sao.View.Form.URL, }; Sao.View.FormXMLViewParser.WIDGETS['html_viewer'] = Sao.View.Form.HTMLViewer; @@ -29510,6 +29674,61 @@ function eval_pyson(value){ } }); + Sao.View.Tree.ToleranceGauge = Sao.class_(Sao.View.Tree.CharColumn, { + class_: 'column-tolerance-gauge form-tolerance-gauge', + get_cell: function() { + var cell = jQuery('
', { + 'class': this.class_, + 'tabindex': 0 + }); + var labels = jQuery('
', { + 'class': 'form-tolerance-gauge-labels' + }).appendTo(cell); + jQuery('', { + 'class': 'form-tolerance-gauge-label form-tolerance-gauge-label-min' + }).appendTo(labels); + jQuery('', { + 'class': 'form-tolerance-gauge-label form-tolerance-gauge-label-center' + }).appendTo(labels); + jQuery('', { + 'class': 'form-tolerance-gauge-label form-tolerance-gauge-label-max' + }).appendTo(labels); + var track = jQuery('
', { + 'class': 'form-tolerance-gauge-track', + 'role': 'meter' + }).appendTo(cell); + jQuery('
', { + 'class': 'form-tolerance-gauge-fill' + }).appendTo(track); + jQuery('
', { + 'class': 'form-tolerance-gauge-center-tick' + }).appendTo(track); + jQuery('
', { + 'class': 'form-tolerance-gauge-marker' + }).appendTo(track); + jQuery('
', { + 'class': 'form-tolerance-gauge-value' + }).appendTo(cell); + return cell; + }, + get_textual_value: function(record) { + return this.field.get_client(record); + }, + update_text: function(cell, record) { + this.el = cell; + this.min_label = cell.find('.form-tolerance-gauge-label-min'); + this.center_label = cell.find('.form-tolerance-gauge-label-center'); + this.max_label = cell.find('.form-tolerance-gauge-label-max'); + this.track = cell.find('.form-tolerance-gauge-track'); + this.value_label = cell.find('.form-tolerance-gauge-value'); + this._set_gauge( + record, this.field.get(record), this.get_textual_value(record)); + } + }); + jQuery.extend( + Sao.View.Tree.ToleranceGauge.prototype, + Sao.View.ToleranceGaugeMixin); + Sao.View.Tree.ButtonColumn = Sao.class_(Object, { init: function(view, attributes) { this.view = view; @@ -29597,6 +29816,7 @@ function eval_pyson(value){ 'text': Sao.View.Tree.TextColum, 'time': Sao.View.Tree.TimeColumn, 'timedelta': Sao.View.Tree.TimeDeltaColumn, + 'tolerance_gauge': Sao.View.Tree.ToleranceGauge, 'url': Sao.View.Tree.URLColumn, };