ru.coon 2.8.65 → 3.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/CHANGELOG.md +319 -6
  2. package/package.json +1 -1
  3. package/src/Function.js +1 -1
  4. package/src/VisualLinker.js +610 -0
  5. package/src/VisualLinker.scss +219 -0
  6. package/src/app/Application.js +1 -0
  7. package/src/app/ApplicationSettings.js +49 -0
  8. package/src/app/Config.js +60 -0
  9. package/src/app/Router.js +37 -21
  10. package/src/app/viewPort/CVWrapperPanel.js +53 -0
  11. package/src/app/viewPort/CenterView.js +153 -46
  12. package/src/app/viewPort/CenterView.scss +151 -0
  13. package/src/app/viewPort/ComponentContextManager.js +24 -0
  14. package/src/app/viewPort/Main.js +4 -1
  15. package/src/app/viewPort/Routing.d2 +23 -0
  16. package/src/app/viewPort/TabHistory.js +81 -0
  17. package/src/common/ComponentFactory.js +167 -0
  18. package/src/common/button/DropdownContentButton.js +146 -0
  19. package/src/common/button/DropdownContentButton.scss +92 -0
  20. package/src/common/button/DropdownContentButtonController.js +60 -0
  21. package/src/common/component/editor/EditorFactory.js +3 -1
  22. package/src/common/component/formeditor/UiCustomFilterForm.scss +0 -1
  23. package/src/common/component/settings/modules/settingClosePageConfirmation.js +1 -3
  24. package/src/common/component/settings/modules/settingFavoritePanelShow.js +21 -0
  25. package/src/common/component/settings/modules/settingReportCalculator.js +22 -0
  26. package/src/common/component/settings/modules/settingShowNeedReloadMessage.js +1 -3
  27. package/src/common/component/settings/modules/settingwindowHolder.js +2 -3
  28. package/src/common/panel/WindowWrap.js +19 -11
  29. package/src/common/tree/BaseContextMenu.js +4 -3
  30. package/src/log.js +4 -5
  31. package/src/nav/AppNavCalcButton.js +23 -0
  32. package/src/nav/AppNavCalcButton.scss +6 -0
  33. package/src/nav/AppNavigationBar.js +1 -1
  34. package/src/nav/AppNavigationMenuController.js +2 -2
  35. package/src/nav/AppNavigationMenuMinimized.js +61 -0
  36. package/src/nav/AppNavigationPanel.js +115 -0
  37. package/src/nav/AppNavigationPanel.scss +178 -0
  38. package/src/nav/AppNavigationPanelController.js +386 -0
  39. package/src/nav/FavoriteCfg.js +18 -0
  40. package/src/nav/MenuEntity.js +23 -15
  41. package/src/nav/MenuFavoritesBar.js +100 -0
  42. package/src/nav/MenuFavoritesBar.scss +92 -0
  43. package/src/nav/editor/NavigateElementEditorView.js +2 -2
  44. package/src/nav/editor/workspace/NavWorkspaceListView.js +1 -4
  45. package/src/nav/menu/WorkspaceMenuViewMinimized.js +22 -0
  46. package/src/overrides/panel/TabPanel.js +36 -0
  47. package/src/overrides/panel/TabPanel.scss +65 -0
  48. package/src/report/component/ClearFiltersButton.js +4 -1
  49. package/src/report/component/CopyCellValueMenuItem.js +18 -0
  50. package/src/report/component/ReportFieldMap.js +274 -0
  51. package/src/report/component/ReportPanel.js +73 -44
  52. package/src/report/component/ReportPanel.scss +2 -2
  53. package/src/report/component/ReportTagLookup.js +59 -2
  54. package/src/report/component/calculator/ReportCalculatorController.js +266 -0
  55. package/src/report/component/calculator/ReportCalculatorField.js +47 -0
  56. package/src/report/component/calculator/ReportCalculatorHistoryPlugin.js +128 -0
  57. package/src/report/component/calculator/ReportCalculatorHistoryPlugin.scss +33 -0
  58. package/src/report/component/calculator/ReportCalculatorMenuItem.js +101 -0
  59. package/src/report/component/calculator/ReportCalculatorMenuItem.scss +41 -0
  60. package/src/report/component/calculator/ReportCalculatorPanel.js +363 -0
  61. package/src/report/component/calculator/ReportCalculatorPanel.scss +86 -0
  62. package/src/report/component/reportpanel/CopyReportPanelController.js +1 -1
  63. package/src/report/component/reportpanel/FilterPanel.js +13 -15
  64. package/src/report/component/reportpanel/FilterPanel.scss +5 -1
  65. package/src/report/component/reportpanel/FormFieldFocusPlugin.js +157 -0
  66. package/src/report/component/reportpanel/FormFieldFocusPlugin.scss +14 -0
  67. package/src/report/component/reportpanel/NorthPanel.js +16 -17
  68. package/src/report/component/reportpanel/NorthPanel.scss +1 -1
  69. package/src/report/component/reportpanel/ReportContextMenu.js +219 -0
  70. package/src/report/component/reportpanel/ReportGrid.js +1 -0
  71. package/src/report/component/reportpanel/ReportGrid.scss +4 -0
  72. package/src/report/component/settings/field/ReportFormFieldsGrid.js +2 -2
  73. package/src/report/component/settings/field/ReportFormFieldsGridController.js +2 -2
  74. package/src/report/component/settings/property/ReportPropertiesPanelController.js +1 -1
  75. package/src/report/component/settings/property/ReportPropertyDictionary.js +7 -0
  76. package/src/report/plugin/configPanel/AddFilterConditionPluginConfigPanel.js +34 -11
  77. package/src/report/plugin/configPanel/GridFiltersPluginConfigPanelFiltersGrid.js +3 -2
  78. package/src/report/plugin/configPanel/openCustomPanelButtonPlugin/OpenCustomPanelButtonPluginConfigPanel.js +274 -255
  79. package/src/report/plugin/configPanel/openCustomPanelButtonPlugin/OpenCustomPanelButtonPluginConfigPanel.scss +17 -0
  80. package/src/report/plugin/grid/AddFilterConditionPlugin.js +530 -87
  81. package/src/report/plugin/grid/CalculatorPlugin.js +90 -0
  82. package/src/report/plugin/grid/GridContextMenu.js +12 -10
  83. package/src/report/plugin/grid/GridRowCountPlugin.js +0 -1
  84. package/src/report/plugin/grid/GridToolbarButtonPlugin.js +11 -2
  85. package/src/report/plugin/grid/OpenCustomPanelButtonPlugin.js +126 -89
  86. package/src/report/plugin/grid/ReportCharacteristicBindPlugin.js +6 -4
  87. package/src/report/plugin/grid/ReportColumnStatePlugin.js +15 -3
  88. package/src/report/plugin/grid/SetSingleParameterPlugin.js +1 -1
  89. package/src/report/plugin/grid/ToolbarButtonPlugin.js +1 -1
  90. package/src/report/plugin/grid/addFilterConditionPlugin/AdvancedSearchPanel.js +55 -0
  91. package/src/report/plugin/grid/addFilterConditionPlugin/AdvancedSearchPanelController.js +226 -0
  92. package/src/report/plugin/grid/addFilterConditionPlugin/FilterConfigMixin.js +138 -0
  93. package/src/report/plugin/grid/addFilterConditionPlugin/FilterFieldFactory.js +223 -0
  94. package/src/report/plugin/grid/addFilterConditionPlugin/FilterItem.js +164 -0
  95. package/src/report/plugin/grid/addFilterConditionPlugin/FilterItem.scss +21 -0
  96. package/src/report/plugin/grid/addFilterConditionPlugin/FilterMenu.js +29 -0
  97. package/src/report/plugin/grid/addFilterConditionPlugin/FilterWrapPanel.js +53 -0
  98. package/src/report/plugin/grid/addFilterConditionPlugin/FilterWrapPanelController.js +57 -0
  99. package/src/report/plugin/grid/addFilterConditionPlugin/InfoMenuItem.js +111 -0
  100. package/src/report/plugin/grid/addFilterConditionPlugin/InfoMenuItem.scss +83 -0
  101. package/src/report/plugin/grid/addFilterConditionPlugin/SelectColumnPanel.js +102 -0
  102. package/src/report/selectionModels/MixedRowSelectionModel.js +36 -45
  103. package/src/report/toolbar/dropdown/ToolbarOverflowButton.js +16 -5
  104. package/src/report/toolbar/dropdown/ToolbarOverflowPanel.scss +26 -14
  105. package/src/report/toolbar/layout/ReportToolbarOverflow.js +5 -2
  106. package/src/ringBuffer.js +7 -3
  107. package/src/uielement/command/GetUIElementCommand.js +0 -1
  108. package/src/uielement/component/UiCPWrapper.js +26 -36
  109. package/src/uielement/component/UiCustomController.js +7 -0
  110. package/src/uielement/component/UiCustomPanel.js +46 -2
  111. package/src/uielement/component/settings/UiCustomPanelEditorController.js +35 -29
  112. package/src/uielement/component/settings/plugin/UiCustomPanelPluginGrid.js +146 -33
  113. package/src/uielement/component/settings/plugin/UiCustomPanelPluginGrid.scss +28 -0
  114. package/src/uielement/component/settings/plugin/UiCustomPanelPluginGridController.js +366 -22
  115. package/src/uielement/component/settings/plugin/UiCustomPanelPluginModel.js +1 -0
  116. package/src/uielement/component/settings/plugin/UiCustomPanelPluginPanel.js +10 -4
  117. package/src/uielement/component/settings/plugin/UiCustomPanelPluginPanelController.js +28 -30
  118. package/src/uielement/plugin/UnifiedButtonToolbarPlugin.js +203 -22
  119. package/src/uielement/plugin/configPanel/ExecuteFunctionPluginConfigPanelFormEditor.js +4 -36
  120. package/src/uielement/plugin/configPanel/FireEventPluginConfigPanelFormEditor.js +5 -36
  121. package/src/uielement/plugin/configPanel/MethodChainPluginConfigPanelFormEditor.js +4 -36
  122. package/src/uielement/plugin/configPanel/OpenPanelPluginConfigPanelFormEditor.js +2 -38
  123. package/src/uielement/plugin/configPanel/PrintPdfPluginConfigPanelFormEditor.js +2 -35
  124. package/src/uielement/plugin/configPanel/UiCPPluginFormPanel.js +54 -0
  125. package/src/uielement/plugin/configPanel/UnifiedButtonToolbarPluginConfigPanelFormEditor.js +28 -18
  126. package/src/userSettings.js +1 -0
  127. package/src/util/ContextManager.js +109 -0
  128. package/src/util.js +96 -15
  129. package/src/version.js +1 -1
  130. package/src/app/viewPort/CenterViewController.js +0 -158
@@ -0,0 +1,266 @@
1
+ Ext.define('Coon.report.component.calculator.ReportCalculatorController', {
2
+ extend: 'Ext.app.ViewController',
3
+ alias: 'controller.ReportCalculatorController',
4
+
5
+ statics: {
6
+ ERROR_MESSAGE: 'Ошибка',
7
+ REGEX: /[×÷+=-]/,
8
+ IS_OPERATOR: /[/*+-]/,
9
+ IS_NUMBER: /^[0-9]$/,
10
+ },
11
+
12
+ init() {
13
+ this.vm = this.getViewModel();
14
+ this.history = [];
15
+ this.textfield = this.getView().down('textfield');
16
+ this.lastButton = '';
17
+ this.lastOperator = '';
18
+ window.addEventListener('keydown', (e) => {
19
+ if (!this.getView().containsFocus) {
20
+ return;
21
+ }
22
+ const button = {};
23
+ button.text = String(e.key);
24
+ if (this.self.IS_NUMBER.test(e.key)) {
25
+ this.enterNumber(button);
26
+ }
27
+ if (this.self.IS_OPERATOR.test(e.key)) {
28
+ this.selectOperator(button);
29
+ }
30
+ if (e.code === 'NumpadEnter' || e.code === 'Enter') {
31
+ this.calculate();
32
+ }
33
+ if (e.code === 'NumpadDecimal') {
34
+ this.enterSeparator(button);
35
+ }
36
+ if (e.code === 'Backspace') {
37
+ e.preventDefault();
38
+ this.deleteSymbol(button);
39
+ }
40
+ });
41
+ },
42
+
43
+ deleteSymbol(button) {
44
+ const newStr = this.textfield.getValue() === this.self.ERROR_MESSAGE ?
45
+ 0 :
46
+ String(this.textfield.getValue()).replaceAll(/\s+/g, '').slice(0, -1);
47
+ newStr && newStr !== '-' ? this.textfield.setValue(window.Decimal(newStr)) : this.textfield.setValue(0);
48
+ this.lastButton = button.text;
49
+ this.textfield.focus();
50
+ },
51
+
52
+ deleteTextfield(button) {
53
+ this.textfield.setValue(0);
54
+ this.lastButton = button.text;
55
+ this.textfield.focus();
56
+ },
57
+
58
+ resetViewModelData() {
59
+ this.vm.set({
60
+ operand1: null,
61
+ operand2: null,
62
+ operator: '',
63
+ equal: ' ',
64
+ });
65
+ },
66
+
67
+ deleteAll() {
68
+ this.textfield.setValue(0);
69
+ this.resetViewModelData();
70
+ this.lastButton = 'C';
71
+ this.lastOperator = '';
72
+ this.textfield.focus();
73
+ },
74
+
75
+ enterNumber(button) {
76
+ const maxLength = 17;
77
+ this.textfield.getValue() === this.self.ERROR_MESSAGE ? this.textfield.setValue(0) : '';
78
+ if (Number(button.text) === 0 && String(this.textfield.getValue()) === '0') {
79
+ return;
80
+ }
81
+ if (String(this.textfield.getValue()).length >= maxLength && !this.self.REGEX.test(this.lastButton)) {
82
+ return;
83
+ }
84
+ if (this.lastButton === '=') {
85
+ this.resetViewModelData();
86
+ }
87
+ const oldValue = this.self.REGEX.test(this.lastButton) ? '' : String(this.textfield.getValue()).replaceAll(/\s+/g, '');
88
+ const newValue = String(oldValue) !== '0' ? String(oldValue) + button.text : button.text;
89
+ this.textfield.setValue(newValue);
90
+ this.lastButton = button.text;
91
+ this.textfield.focus();
92
+ },
93
+
94
+ enterSeparator(button) {
95
+ const maxLength = 17;
96
+ if (String(this.textfield.getValue()).length >= maxLength) {
97
+ return;
98
+ }
99
+ const oldText = this.textfield.getValue() === this.self.ERROR_MESSAGE ? 0 : this.textfield.getValue();
100
+ if (oldText && !String(oldText).includes('.')) {
101
+ this.textfield.setValue(oldText + '.');
102
+ this.lastButton = button.text;
103
+ }
104
+ this.textfield.focus();
105
+ },
106
+
107
+ selectOperator(button) {
108
+ this.textfield.setValue(window.Decimal(this.textfield.getValue() === this.self.ERROR_MESSAGE ?
109
+ 0 :
110
+ String(this.textfield.getValue()).replaceAll(/\s+/g, '')));
111
+ this.textfield.focus();
112
+ button.text === '—' ? button.text = '-' : '';
113
+ button.text === '*' ? button.text = '×' : '';
114
+ button.text === '/' ? button.text = '÷' : '';
115
+ if (!this.textfield.getValue()) {
116
+ return;
117
+ }
118
+ if (this.self.REGEX.test(this.lastButton) && this.lastButton !== '=') {
119
+ this.vm.set('operator', button.text);
120
+ this.lastButton = button.text;
121
+ this.lastOperator = button.text;
122
+ return;
123
+ }
124
+ if (this.lastOperator && this.lastOperator !== '=') {
125
+ this.calculate();
126
+ }
127
+ this.vm.set('equal', ' ');
128
+ this.vm.set('operand2', null);
129
+ if (this.textfield.getValue() === this.self.ERROR_MESSAGE) {
130
+ return;
131
+ }
132
+ this.vm.set('operand1', String(this.textfield.getValue()).replaceAll(/\s+/g, ''));
133
+ this.vm.set('operator', button.text);
134
+ this.lastButton = button.text;
135
+ this.lastOperator = button.text;
136
+ },
137
+
138
+ calculate() {
139
+ this.textfield.setValue(window.Decimal(this.textfield.getValue() === this.self.ERROR_MESSAGE ?
140
+ 0 :
141
+ String(this.textfield.getValue()).replaceAll(/\s+/g, '')));
142
+ this.lastButton === '=' ? '' : this.vm.set('operand2', String(this.textfield.getValue()).replaceAll(/\s+/g, ''));
143
+ if (!this.vm.get('operand1') || !this.vm.get('operator') || !this.vm.get('operand2')) {
144
+ this.textfield.focus();
145
+ return;
146
+ }
147
+ const num1 = this.lastButton === '=' ?
148
+ window.Decimal(String(this.textfield.getValue()).replaceAll(/\s+/g, '')) :
149
+ window.Decimal(this.vm.get('operand1'));
150
+ const num2 = window.Decimal(this.vm.get('operand2'));
151
+ const oldAcc = String(this.textfield.getValue()).replaceAll(/\s+/g, '');
152
+ switch (this.vm.get('operator')) {
153
+ case '+':
154
+ this.textfield.setValue(num1.plus(num2));
155
+ break;
156
+ case '-':
157
+ this.textfield.setValue(num1.minus(num2));
158
+ break;
159
+ case '×':
160
+ this.textfield.setValue(num1.times(num2));
161
+ break;
162
+ case '÷':
163
+ if (Number(num2) !== 0) {
164
+ this.textfield.setValue(num1.div(num2));
165
+ } else {
166
+ this.deleteAll();
167
+ this.textfield.setValue(this.self.ERROR_MESSAGE);
168
+ }
169
+ break;
170
+ }
171
+ this.lastButton === '=' ? this.vm.set('operand1', oldAcc) : '';
172
+ this.lastButton = '=';
173
+ this.lastOperator = '=';
174
+ if (this.textfield.getValue() !== this.self.ERROR_MESSAGE) {
175
+ this.vm.set('equal', '=');
176
+ this.pushHistory(this.getHistoryItemString());
177
+ }
178
+ this.textfield.focus();
179
+ },
180
+
181
+ formatNumber(value) {
182
+ return Coon.format.bigNumFormat(value, '.', ' ');
183
+ },
184
+
185
+ getHistoryItemString() {
186
+ const operand1 = this.formatNumber(this.vm.get('operand1'));
187
+ const operand2 = this.formatNumber(this.vm.get('operand2'));
188
+ return `${operand1} ${this.vm.get('operator')} ${operand2} = ${String(this.textfield.getValue()).replaceAll(/s+/g, '')}`;
189
+ },
190
+
191
+ pushHistory(elem) {
192
+ if (this.history.length >= 10) {
193
+ this.history.splice(9, 1);
194
+ }
195
+ this.history.unshift(elem);
196
+ const values = this.history;
197
+ this.getView().fireEvent('changeHistory', values);
198
+ },
199
+
200
+ toggleSign(button) {
201
+ if (this.lastButton === '=') {
202
+ this.resetViewModelData();
203
+ }
204
+ this.textfield.getValue() === this.self.ERROR_MESSAGE ? this.textfield.setValue(0) : '';
205
+ this.textfield.setValue(String(this.textfield.getValue()).replaceAll(/\s+/g, '') * -1);
206
+ this.lastButton = 'toggle';
207
+ this.textfield.focus();
208
+ },
209
+
210
+ enterMemoryValue() {
211
+ this.vm.get('memory') ? this.textfield.setValue(window.Decimal(this.vm.get('memory'))) : '';
212
+ if (this.lastButton === '=') {
213
+ this.resetViewModelData();
214
+ }
215
+ this.lastButton = '';
216
+ this.lastOperator = '';
217
+ this.textfield.focus();
218
+ },
219
+
220
+ setMemory(button) {
221
+ this.vm.set('memory', this.textfield.getValue() === this.self.ERROR_MESSAGE ? 0 : String(this.textfield.getValue()).replaceAll(/\s+/g, ''));
222
+ this.lastButton = 'memory';
223
+ this.textfield.focus();
224
+ },
225
+
226
+ addMemory(button) {
227
+ this.calculateMemory('+');
228
+ this.textfield.focus();
229
+ },
230
+
231
+ subtractMemory(button) {
232
+ this.calculateMemory('-');
233
+ this.textfield.focus();
234
+ },
235
+
236
+ calculateMemory(operator) {
237
+ this.textfield.getValue() === this.self.ERROR_MESSAGE ?
238
+ this.textfield.setValue(0) :
239
+ this.textfield.setValue(String(this.textfield.getValue()).replaceAll(/\s+/g, ''));
240
+ this.lastButton = 'memory';
241
+ if (!this.vm.get('memory')) {
242
+ return;
243
+ }
244
+ switch (operator) {
245
+ case '+':
246
+ this.vm.set('memory', window.Decimal(this.vm.get('memory')).plus(window.Decimal(this.textfield.getValue())));
247
+ break;
248
+ case '-':
249
+ this.vm.set('memory', window.Decimal(this.vm.get('memory')).minus(window.Decimal(this.textfield.getValue())));
250
+ break;
251
+ }
252
+ },
253
+
254
+ swapOperands() {
255
+ if (this.vm.get('operand1') && this.textfield.getValue() && !this.vm.get('operand2')) {
256
+ const operand = this.vm.get('operand1');
257
+ this.vm.set('operand1', String(this.textfield.getValue()).replaceAll(/\s+/g, ''));
258
+ this.textfield.setValue(operand);
259
+ }
260
+ this.textfield.focus();
261
+ },
262
+
263
+ onFieldChange(field, newValue) {
264
+ this.getViewModel().set('isDisabledAll', newValue === 'Ошибка');
265
+ },
266
+ });
@@ -0,0 +1,47 @@
1
+ Ext.define('Coon.report.component.calculator.ReportCalculatorField', {
2
+ extend: 'Ext.form.field.Text',
3
+ xtype: 'ReportCalculatorField',
4
+ value: 0,
5
+ flex: 1,
6
+ maxLength: 17,
7
+ maskRe: /^[]$/,
8
+ enforceMaxLength: true,
9
+ enableKeyEvents: true, // нужен для отслеживания paste
10
+ labelAlign: 'top',
11
+ emptyText: ' ',
12
+ defaultListenerScope: true,
13
+ fieldStyle: {
14
+ fontWeight: 'bold',
15
+ },
16
+ listeners: {
17
+ paste: 'onPasteValue',
18
+ render: 'onRenderField',
19
+ },
20
+ plugins: ['formplug'],
21
+
22
+ valueToRaw: function(newValue) {
23
+ if (newValue === 'Ошибка') {
24
+ return newValue;
25
+ }
26
+ const value = String(newValue).replaceAll(/\s+/g, '');
27
+ const formatedValue = new Intl.NumberFormat('ru-RU', {
28
+ maximumFractionDigits: 16,
29
+ }).format(Number(value)).replaceAll(',', '.');
30
+ return value.endsWith('.') ? formatedValue + '.' : formatedValue;
31
+ },
32
+
33
+ onPasteValue: function() {
34
+ navigator.clipboard.readText()
35
+ .then((text) => {
36
+ if (!Number(text)) {
37
+ this.setValue('Ошибка');
38
+ }
39
+ });
40
+ },
41
+
42
+ onRenderField() {
43
+ this.getEl().on('contextmenu', (e) => {
44
+ e.preventDefault();
45
+ });
46
+ },
47
+ });
@@ -0,0 +1,128 @@
1
+ Ext.define('Coon.report.component.calculator.ReportCalculatorHistoryPlugin', {
2
+ extend: 'Ext.plugin.Abstract',
3
+ alias: 'plugin.formplug',
4
+
5
+ statics: {
6
+ MENU_OFFSET: 48,
7
+ },
8
+
9
+ init(field) {
10
+ this.calculator = field.up();
11
+ this.contextMenu = null;
12
+ this.field = field;
13
+ this.vm = this.calculator.getViewModel();
14
+ this.addTrigger();
15
+ this.calculator.on('changeHistory', this.updateTriggerState, this);
16
+ },
17
+
18
+ updateTriggerState(history) {
19
+ const triggerEl = this.field.getTriggers().history.el;
20
+ if (history.length) {
21
+ triggerEl.removeCls('disabled-trigger');
22
+ } else {
23
+ triggerEl.addCls('disabled-trigger');
24
+ }
25
+ },
26
+
27
+ addTrigger() {
28
+ const triggers = this.field.getTriggers();
29
+ triggers.history = {
30
+ cls: 'svg-icon svg-icon-expand-bottom disabled-trigger',
31
+ handler: () => {
32
+ this.openHistory();
33
+ },
34
+ };
35
+ this.field.setTriggers(triggers);
36
+ },
37
+
38
+ openHistory() {
39
+ if (this.contextMenu) {
40
+ return;
41
+ }
42
+ const history = this.calculator.getController().history;
43
+ const historyItems = [];
44
+ if (!history.length) {
45
+ this.updateTriggerState([]);
46
+ return;
47
+ }
48
+
49
+ for (const [index, element] of history.entries()) {
50
+ const item = Ext.create('Ext.container.Container', {
51
+ layout: 'hbox',
52
+ cls: 'history-container',
53
+ items: [
54
+ {
55
+ xtype: 'displayfield',
56
+ value: element,
57
+ index: index,
58
+ cls: 'history-item-field',
59
+ flex: 1,
60
+ },
61
+ {
62
+ xtype: 'button',
63
+ iconCls: 'svg-icon svg-icon-cancel-small',
64
+ cls: 'history-item-remove-button',
65
+ tooltip: 'Удалить из истории',
66
+ handler: () => {
67
+ history.splice(index, 1);
68
+ this.destroyContextMenu();
69
+ this.openHistory(this.field);
70
+ },
71
+ }
72
+ ],
73
+ });
74
+ historyItems.push(item);
75
+ }
76
+
77
+ this.contextMenu = Ext.create('Ext.menu.Menu', {
78
+ id: 'historyMenu',
79
+ cls: 'historyMenu',
80
+ width: this.field.getWidth(),
81
+ items: historyItems,
82
+ listeners: {
83
+ hide: () => {
84
+ setTimeout(() => {
85
+ this.destroyContextMenu();
86
+ }, 100);
87
+ },
88
+ click: (menu, item) => {
89
+ this.selectHistoryItem(item, history);
90
+ },
91
+ },
92
+ });
93
+ this.showContextMenu();
94
+ },
95
+
96
+ selectHistoryItem(item, history) {
97
+ if (!item) {
98
+ return;
99
+ }
100
+ const parsedExpression = item.items.items[0].getValue().split(' ');
101
+ const indexOfExpression = item.items.items[0].index;
102
+ history.splice(0, 0, history.splice(indexOfExpression, 1)[0]);
103
+ this.destroyContextMenu();
104
+ this.openHistory(this.field);
105
+ this.vm.set({
106
+ operand1: parsedExpression[0],
107
+ operand2: parsedExpression[2],
108
+ operator: parsedExpression[1],
109
+ equal: parsedExpression[3],
110
+ });
111
+ this.field.setValue(parsedExpression[4]);
112
+ },
113
+
114
+ showContextMenu() {
115
+ const menuY = this.field.getY() + this.self.MENU_OFFSET;
116
+ this.contextMenu.showAt([this.field.getX(), menuY]);
117
+ const calculator = Ext.getCmp('ReportCalculatorPanel');
118
+ if (this.contextMenu.getY() !== menuY) {
119
+ calculator.showAt([calculator.getX(), calculator.getY() - Math.abs(this.contextMenu.getY() - menuY)]);
120
+ this.contextMenu.showAt([this.field.getX(), this.contextMenu.getY()]);
121
+ }
122
+ },
123
+
124
+ destroyContextMenu() {
125
+ this.contextMenu.destroy();
126
+ this.contextMenu = null;
127
+ },
128
+ });
@@ -0,0 +1,33 @@
1
+ .historyMenu {
2
+ padding: 0;
3
+
4
+ .history-container {
5
+ left: 0 !important;
6
+ width: 354px !important;
7
+ padding-left: 16px;
8
+ cursor: pointer;
9
+ .x-box-inner {
10
+ width: 338px !important;
11
+ }
12
+ }
13
+
14
+ .history-item-field {
15
+ margin-top: 3px !important;
16
+ }
17
+
18
+ .history-container:hover {
19
+ background-color: #EBECEE;
20
+ }
21
+
22
+ .history-item-remove-button {
23
+ margin-top: 2px !important;
24
+ left: 289px !important;
25
+ z-index: 2;
26
+ }
27
+
28
+ .history-item-remove-button.x-btn-over {
29
+ background-color: #EBECEE !important;
30
+ color: #111111 !important;
31
+ }
32
+ }
33
+
@@ -0,0 +1,101 @@
1
+ Ext.define('Coon.report.component.calculator.ReportCalculatorMenuItem', {
2
+ extend: 'Ext.panel.Panel',
3
+ alias: 'widget.ReportCalculatorMenuItem',
4
+ xtype: 'ReportCalculatorMenuItem',
5
+ cls: 'ReportCalculatorMenuItem',
6
+ defaultListenerScope: true,
7
+ viewModel: {
8
+ data: {
9
+ isHiddenAll: false,
10
+ },
11
+ },
12
+ margin: '0 0 0 48',
13
+ bodyPadding: '5 0 0 0',
14
+ layout: {type: 'hbox'},
15
+ items: [
16
+ {
17
+ xtype: 'container',
18
+ layout: {type: 'hbox', align: 'stretch'},
19
+ defaults: {
20
+ margin: '0 0 0 6',
21
+ cls: 'calculator-contextmenu-button-type1',
22
+ },
23
+ items: [
24
+ {
25
+ xtype: 'button',
26
+ margin: '0 0 0 0',
27
+ iconCls: 'svg-icon svg-icon-calculator',
28
+ eventName: 'openCalculator',
29
+ handler: 'onClickButton',
30
+ },
31
+ {
32
+ xtype: 'button',
33
+ text: 'M=',
34
+ eventName: 'setMemory',
35
+ handler: 'onClickButton',
36
+ width: 46,
37
+ hidden: true,
38
+ bind: {
39
+ hidden: '{isHiddenAll}',
40
+ },
41
+ },
42
+ {
43
+ xtype: 'button',
44
+ text: 'M+',
45
+ eventName: 'addMemory',
46
+ handler: 'onClickButton',
47
+ width: 46,
48
+ hidden: true,
49
+ bind: {
50
+ hidden: '{isHiddenAll}',
51
+ },
52
+ },
53
+ {
54
+ xtype: 'button',
55
+ text: 'M-',
56
+ eventName: 'subtractMemory',
57
+ handler: 'onClickButton',
58
+ width: 46,
59
+ margin: '0 6 0 6',
60
+ hidden: true,
61
+ bind: {
62
+ hidden: '{isHiddenAll}',
63
+ },
64
+ }
65
+ ],
66
+ },
67
+ {
68
+ // hack: Невидимая кнопка для получения фокуса
69
+ // Установка фокуса на компоненте решает проблему снятия фокуса при переводе указателя мыши с другого пункта меню.
70
+ xtype: 'button',
71
+ cls: 'hidden-focus-button',
72
+ itemId: 'hiddenButton',
73
+ width: 0,
74
+ }
75
+ ],
76
+ listeners: {
77
+ afterrender: 'setButtonFocus',
78
+ },
79
+
80
+ // hack: Установка фокуса на компоненте решает проблему снятия фокуса при переводе указателя мыши с другого пункта меню.
81
+ setButtonFocus: function(panel) {
82
+ panel.getEl().on('mouseover', function(e) {
83
+ this.down('#hiddenButton').focus();
84
+ }, this);
85
+ },
86
+
87
+ onClickButton(button) {
88
+ this.fireEvent(button.eventName, button.text);
89
+ },
90
+
91
+ setHiddenMemoryButtons(isHidden) {
92
+ this.getViewModel().set('isHiddenAll', isHidden);
93
+ },
94
+
95
+ isItemHidden() {
96
+ return false;
97
+ },
98
+ isItemDisabled() {
99
+ return false;
100
+ },
101
+ });
@@ -0,0 +1,41 @@
1
+ .ReportCalculatorMenuItem {
2
+ .hidden-focus-button.x-btn-default-small {
3
+ padding: 0 !important;
4
+ }
5
+
6
+ // стили для кнопок калькулятора в контекстном меню
7
+ .calculator-contextmenu-button-type1 {
8
+ border: 1px solid #8B8B8B !important;
9
+ border-radius: 6px;
10
+ padding: 6px 12px;
11
+ .x-btn-inner-default-small {
12
+ font-size: 13px;
13
+ font-weight: 400 !important;
14
+ line-height: 16px;
15
+ padding: 0;
16
+ }
17
+ .x-btn-inner {
18
+ color: #888888;
19
+ }
20
+ .svg-icon {
21
+ background-color: #888888 !important;
22
+ }
23
+ &.x-btn-over {
24
+ background-color: #F5F5F5;
25
+ border: 1px solid #707070 !important;
26
+ .x-btn-inner {
27
+ color: #707070 !important;
28
+ }
29
+ }
30
+ &.x-btn-pressed {
31
+ background-color: #ECECEC !important;
32
+ border: 1px solid #707070 !important;
33
+ .x-btn-inner {
34
+ color: #707070 !important;
35
+ }
36
+ }
37
+ &:has(.x-btn-no-text) {
38
+ padding: 6px 6px;
39
+ }
40
+ }
41
+ }