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,164 @@
1
+ Ext.define('Coon.report.plugin.grid.addFilterConditionPlugin.FilterItem', {
2
+ extend: 'Ext.panel.Panel',
3
+ alias: 'widget.FilterItem',
4
+ requires: [
5
+ 'Coon.report.plugin.grid.addFilterConditionPlugin.FilterFieldFactory'
6
+ ],
7
+ cls: 'FilterItem',
8
+ closable: true,
9
+ bodyPadding: '10 8',
10
+ margin: '0 10 4 10',
11
+ frame: true,
12
+ defaultListenerScope: true,
13
+ referenceHolder: true,
14
+ layout: {
15
+ type: 'hbox', align: 'stretch',
16
+ },
17
+ listeners: {
18
+ boxready: 'onReady',
19
+ },
20
+ bind: {
21
+ title: '{titleFormula}',
22
+ },
23
+ viewModel: {
24
+ data: {
25
+ filter: {},
26
+ },
27
+ formulas: {
28
+ titleFormula: {
29
+ get: function(data) {
30
+ let columnGroup = Ext.isObject(data('filter')) && data('filter').columnGroup;
31
+ columnGroup = Ext.isString(columnGroup) ? columnGroup.replaceAll(';', ' / ') + ' / ': '';
32
+ return columnGroup + data('filter').columnName;
33
+ },
34
+ },
35
+ conditionHidden: {
36
+ get: function(data) {
37
+ const filter = data('filter');
38
+ return !!(Ext.isObject(filter) && ['list', 'boolean'].includes(filter.type));
39
+ },
40
+ },
41
+ valueToDisabled: {
42
+ bind: {
43
+ bindTo: '{filter}',
44
+ deep: true,
45
+ },
46
+ get: function(filter) {
47
+ return !!(Ext.isObject(filter) && filter.operator!=='between');
48
+ },
49
+ },
50
+ notfilledDisabled: {
51
+ bind: {
52
+ bindTo: '{filter}',
53
+ deep: true,
54
+ },
55
+ get: function(filter) {
56
+ return !!(Ext.isObject(filter) && filter.operator==='notfilled');
57
+ },
58
+ },
59
+ },
60
+ },
61
+
62
+ initComponent() {
63
+ this.factory = Ext.create('Coon.report.plugin.grid.addFilterConditionPlugin.FilterFieldFactory');
64
+ this.callParent();
65
+ this.getViewModel().bind('{filter.type}', function(type) {
66
+ if (typeof type === 'string') {
67
+ this.lookup('condition').getStore().setFilters({
68
+ property: 'columnFilterType',
69
+ value: type,
70
+ operator: 'like',
71
+ });
72
+ }
73
+ }, this);
74
+ this.getViewModel().set({filter: this.filter});
75
+ },
76
+
77
+ getFilter() {
78
+ this.clearFilterValue();
79
+ return this.getViewModel().get('filter');
80
+ },
81
+
82
+ clearFilterValue() {
83
+ const operator = this.getViewModel().get('filter.operator');
84
+ if (operator === 'notfilled') {
85
+ this.getViewModel().set('filter.value', undefined);
86
+ this.getViewModel().set('filter.fromValue', undefined);
87
+ }
88
+ },
89
+
90
+ onReady() {
91
+ this.add(this.getItems());
92
+ },
93
+
94
+ getItems() {
95
+ return [
96
+ {
97
+ xtype: 'container',
98
+ reference: 'valueContainer',
99
+ flex: 2,
100
+ layout: {
101
+ type: 'hbox', // align: 'stretch',
102
+ },
103
+ defaults: {flex: 1},
104
+ items: this.getFieldsByType(),
105
+ },
106
+ this.getConditions()
107
+ ];
108
+ },
109
+
110
+ getConditions() {
111
+ return Ext.create({
112
+ xtype: 'BaseComboBox',
113
+ reference: 'condition',
114
+ flex: 1,
115
+ fieldLabel: 'Условие',
116
+ forceSelection: true,
117
+ bind: {
118
+ value: '{filter.operator}',
119
+ hidden: '{conditionHidden}',
120
+ },
121
+ displayField: 'description',
122
+ valueField: 'value',
123
+ listeners: {
124
+ change: 'changeOperator',
125
+ },
126
+ store: {
127
+ fields: ['value', 'description'],
128
+ data: [
129
+ {value: 'eq', description: 'равно', columnFilterType: 'numeric,date,string'},
130
+ {value: 'ne', description: 'не равно', columnFilterType: 'numeric,date,string'},
131
+ {value: 'notfilled', description: 'не заполнено', columnFilterType: 'numeric,date,string'},
132
+ {value: 'between', description: 'от / до', columnFilterType: 'numeric,date'},
133
+ {value: 'like', description: 'по части строки', columnFilterType: 'string'}
134
+ ],
135
+ },
136
+ });
137
+ },
138
+
139
+ changeOperator(combo, value) {
140
+ const container = this.lookup('valueContainer');
141
+ if (value) {
142
+ container.removeAll();
143
+ const fields = this.getFieldsByType();
144
+ const comps = container.add(
145
+ fields
146
+ );
147
+ this.fireEvent('fieldsadded', Array.isArray(comps) ? comps: [comps]);
148
+ }
149
+ },
150
+
151
+ getFieldsByType() {
152
+ const filter = this.getViewModel().get('filter');
153
+ const type = filter.type;
154
+ const operator = this.lookup('condition') && this.lookup('condition').getValue();
155
+ const booleanLabels = filter.booleanLabels;
156
+ const listData = filter.listData;
157
+ const useCombo = filter.useCombo && operator==='eq';
158
+ return this.factory.getFields(type, {booleanLabels, listData, useCombo});
159
+ },
160
+
161
+ isValid() {
162
+ return Coon.Function.validateAllFieldsOnForm(this);
163
+ },
164
+ });
@@ -0,0 +1,21 @@
1
+ .FilterItem {
2
+ .x-panel-header-title-default-framed > .x-title-text-default-framed {
3
+ color: #111111 !important;
4
+ font-size: 16px;
5
+
6
+ }
7
+ .x-panel-header-default-framed-top {
8
+ padding: 8px 8px 8px 8px;
9
+ }
10
+ .x-tool-tool-el {
11
+ width: 20px;
12
+ height: 20px;
13
+ }
14
+ .x-tool-img.x-tool-close {
15
+ background-color: #707070 !important;
16
+ min-height: 20px !important;
17
+ min-width: 20px !important;
18
+ mask-size: 20px;
19
+ }
20
+
21
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * В базовом меню Ext.menu.Menu шаблонный метод processFocusableContainerKeyEvent меняет
3
+ * поведение по нажатию TAB. По TAB и shift TAB работает навигация вверх/вниз по пунктам меню.
4
+ * В классе FilterMenu по нажатию TAB и shift+TAB требуется переход по полям формы, так как
5
+ * единственным пунктом этого меню является форма простого поиска.
6
+ */
7
+ Ext.define('Coon.report.plugin.grid.addFilterConditionPlugin.FilterMenu', {
8
+ extend: 'Ext.menu.Menu',
9
+ alias: 'widget.FilterMenu',
10
+
11
+ privates: {
12
+ processFocusableContainerKeyEvent(e) {
13
+ // ESC may be from input fields, and FocusableContainers ignore keys from
14
+ // input fields. We do not want to ignore ESC. ESC hide menus.
15
+ if (e.keyCode === e.ESC) {
16
+ e.target = this.el.dom;
17
+ } else if (e.keyCode === e.TAB && Ext.fly(e.target).is('input[type=text],textarea')) {
18
+ if (!Ext.fly(e.target).isInputField()) {
19
+ return e;
20
+ }
21
+ return undefined;
22
+ } else {
23
+ return this.callParent([e]);
24
+ }
25
+
26
+ return e;
27
+ },
28
+ },
29
+ });
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Панель, которая отображается в контекстном меню по пункту Поиск.
3
+ * В зависимости от типа фильтра колонки конструируется наполнение панели. Для каждого типа фильтра (string, boolean, date, list, numeric)
4
+ */
5
+ Ext.define('Coon.report.plugin.grid.addFilterConditionPlugin.FilterWrapPanel', {
6
+ extend: 'Ext.panel.Panel',
7
+ alias: 'widget.FilterWrapPanel',
8
+ cls: 'FilterWrapPanel',
9
+
10
+ viewModel: {
11
+ data: {
12
+ // Валидация кнопки 'Ok'. Поиск возможен, если поле фильтра валидно (например дата в диапазоне минимальной и максимальной дат)
13
+ filterFieldValid: true,
14
+ },
15
+ },
16
+ controller: 'FilterWrapPanelController',
17
+
18
+ config: {
19
+ filter: {},
20
+ // ссылка на грид
21
+ reportGrid: undefined,
22
+ },
23
+ updateReportGrid(grid) {
24
+ if (grid) {
25
+ this.getController().report = grid.up('ReportPanel');
26
+ }
27
+ },
28
+ maxWidth: 600,
29
+ maxHeight: 400,
30
+ layout: {type: 'vbox', align: 'stretch'},
31
+ items: [],
32
+
33
+ buttons: [
34
+ {
35
+ xtype: 'button',
36
+ ui: 'orange-button',
37
+ text: 'Расширенный поиск',
38
+ handler: 'advancedSearchHandler',
39
+ },
40
+ {
41
+ xtype: 'tbfill',
42
+ },
43
+ {
44
+ xtype: 'button',
45
+ ui: 'orange-button',
46
+ text: 'Ok',
47
+ handler: 'okClickHandler',
48
+ bind: {
49
+ disabled: '{!filterFieldValid}',
50
+ },
51
+ }
52
+ ],
53
+ });
@@ -0,0 +1,57 @@
1
+ Ext.define('Coon.report.plugin.grid.addFilterConditionPlugin.FilterWrapPanelController', {
2
+ extend: 'Ext.app.ViewController',
3
+ alias: 'controller.FilterWrapPanelController',
4
+ mixins: ['Coon.report.plugin.grid.addFilterConditionPlugin.FilterConfigMixin'],
5
+
6
+ report: undefined,
7
+ init() {
8
+ this.cellValue = this.getView().cellValue;
9
+ this.dataIndex = this.getView().dataIndex;
10
+ const filter = this.getView().getFilter();
11
+ this.addFilterProperties(filter);
12
+ this.filterItem = Ext.create({
13
+ xtype: 'FilterItem',
14
+ flex: 1,
15
+ filter,
16
+ closable: false,
17
+ bodyPadding: '10 8',
18
+ margin: '0 0 0 10',
19
+ frame: false,
20
+ title: false,
21
+ bind: {
22
+ title: false,
23
+ },
24
+ });
25
+ const vm = this.getViewModel();
26
+ this.filterItem.on('fieldsadded', function(fields) {
27
+ fields.forEach(function(field) {
28
+ field.on('change', function() {
29
+ vm.set('filterFieldValid', field.isValid());
30
+ });
31
+ });
32
+ });
33
+ this.getView().add(this.filterItem);
34
+ },
35
+
36
+ filterReact() {
37
+ const filter = this.filterItem.getFilter();
38
+ const filterType = filter.type;
39
+ const condition = filter.operator || (filterType==='list' ? 'in' : 'eq');
40
+ const value = condition === 'between' ?
41
+ [filter.fromValue, filter.toValue].map(this.prepareValue):
42
+ this.prepareValue(filter.fromValue);
43
+ this.getView().fireEvent('dofilter', value, condition);
44
+ },
45
+
46
+ okClickHandler() {
47
+ this.filterReact();
48
+ },
49
+
50
+ isCurrent() {
51
+ return true;
52
+ },
53
+
54
+ advancedSearchHandler() {
55
+ this.fireViewEvent('advancedsearch');
56
+ },
57
+ });
@@ -0,0 +1,111 @@
1
+ Ext.define('Coon.report.plugin.grid.addFilterConditionPlugin.InfoMenuItem', {
2
+ extend: 'Ext.panel.Panel',
3
+ alias: 'widget.InfoMenuItem',
4
+ xtype: 'InfoMenuItem',
5
+ cls: 'InfoMenuItem',
6
+ focusableContainer: true,
7
+ viewModel: {
8
+ data: {
9
+ columnName: undefined,
10
+ filterPrefix: undefined,
11
+ filterText: undefined,
12
+ qTip: '',
13
+ },
14
+ },
15
+ margin: '0 0 0 0',
16
+ layout: {type: 'hbox', align: 'stretch'},
17
+
18
+ initComponent() {
19
+ this.removeButton = Ext.create({
20
+ xtype: 'button',
21
+ iconCls: 'svg-icon svg-icon-cancel-small',
22
+ cls: 'system-button-type',
23
+ handler: this.removeFilter.bind(this),
24
+ });
25
+ this.items = [
26
+ {
27
+ // hack: Невидимая кнопка для получения фокуса
28
+ // Установка фокуса на компоненте решает проблему снятия фокуса при переводе указателя мыши с другого пункта меню.
29
+ xtype: 'button',
30
+ text: 'X',
31
+ itemId: 'hiddenButton',
32
+ width: 0,
33
+ },
34
+ {
35
+ xtype: 'panel',
36
+ flex: 1,
37
+ bind: {
38
+ data: {
39
+ columnName: '{columnName}',
40
+ qTip: '{qTip}',
41
+ filterPrefix: '{filterPrefix}',
42
+ filterText: '{filterText}',
43
+ },
44
+ },
45
+
46
+ tpl: new Ext.XTemplate(
47
+ `<div class="menu-item-wrapper">`,
48
+ ` <div class="menu-text-container" data-qtip="{qTip}">`,
49
+ ` <b>{columnName}</b>`,
50
+ ` <tpl if="filterText">`,
51
+ ` <br><span class="filter-prefix">{filterPrefix}</span> {filterText}`,
52
+ ` </tpl>`,
53
+ ` </div>`,
54
+ `</div>`
55
+ ),
56
+ },
57
+ {
58
+ xtype: 'container',
59
+ width: 50,
60
+ layout: 'center',
61
+ items: [
62
+ this.removeButton
63
+ ],
64
+ }
65
+ ];
66
+ this.listeners = {
67
+ afterrender: this.setButtonFocus.bind(this),
68
+ };
69
+ this.callParent();
70
+ },
71
+
72
+ // hack: Установка фокуса на компоненте решает проблему снятия фокуса при переводе указателя мыши с другого пункта меню.
73
+ setButtonFocus: function(panel) {
74
+ panel.getEl().on('mouseover', function(e) {
75
+ this.down('#hiddenButton').focus();
76
+ }, this);
77
+ },
78
+ removeFilter() {
79
+ this.fireEvent('removefilter');
80
+ },
81
+ setFilterPrefix(value) {
82
+ this.getViewModel().set('filterPrefix', value);
83
+ },
84
+ setFilterText(value) {
85
+ this.getViewModel().set('filterText', value);
86
+ },
87
+ setColumnName(columnName) {
88
+ columnName = this.prepareText(columnName);
89
+ this.getViewModel().set('columnName', columnName);
90
+ },
91
+ setQTip(columnName, columnGroup, filterPrefix, filterText) {
92
+ columnName = this.prepareText(columnName);
93
+ columnGroup = this.prepareText(columnGroup);
94
+ filterText = Ext.String.htmlEncode(filterText);
95
+ const qTip = `<b>${columnGroup} ${columnName}</b> <br>${filterPrefix} ${filterText}`;
96
+ this.getViewModel().set('qTip', qTip);
97
+ },
98
+ removeQTip() {
99
+ this.getViewModel().set('qTip', 'Фильтр не задан');
100
+ },
101
+ buttonSetHidden(value) {
102
+ this.removeButton.setHidden(value);
103
+ },
104
+ prepareText(str) {
105
+ if (!Ext.isString(str)) {
106
+ return str;
107
+ }
108
+ const replaced = str.replace(/<br\s*\/?>/gi, ' ');
109
+ return Ext.util.Format.stripTags(replaced);
110
+ },
111
+ });
@@ -0,0 +1,83 @@
1
+ .InfoMenuItem {
2
+ $menu-background-color: #F5F5F5;
3
+ .filter-prefix {
4
+ color: rgba(0, 0, 0, 0.50);
5
+ }
6
+ .menu-item-wrapper {
7
+ padding: 8px 0;
8
+
9
+ .menu-text-container {
10
+ margin-left: 48px;
11
+ overflow: hidden;
12
+ white-space: nowrap;
13
+ text-overflow: ellipsis;
14
+ min-width: 200px;
15
+ max-width: 400px;
16
+ }
17
+ }
18
+
19
+ background-color: $menu-background-color;
20
+ .x-panel-body-default {
21
+ background-color: $menu-background-color;
22
+ }
23
+
24
+ .svg-icon-cancel-small {
25
+ min-height: 18px !important;
26
+ min-width: 18px !important;
27
+ mask-size: 15px;
28
+ }
29
+
30
+ .system-button-type {
31
+ border: 1px solid #888888 !important;
32
+ border-radius: 6px;
33
+ padding: 6px;
34
+ background-color: #FFFFFF;
35
+ width: 30px;
36
+ height: 30px;
37
+ }
38
+
39
+ .system-button-type.x-btn-over {
40
+ border: 1px solid #888888 !important;
41
+ border-radius: 6px;
42
+ padding: 6px;
43
+ background-color: #F5F7FA;
44
+ }
45
+
46
+ .system-button-type.x-btn-disabled {
47
+ border: 1px solid #A3AAB2 !important;
48
+ border-radius: 6px;
49
+ padding: 6px;
50
+ background-color: #FFFFFF;
51
+ }
52
+ .system-button-type.x-btn-disabled .x-btn-icon-el{
53
+ background-color: #A3AAB2;
54
+ }
55
+
56
+ .system-button-type.x-btn-menu-active {
57
+ border: 1px solid #3D78BF !important;
58
+ background-color: #D8E4F2;
59
+ border-radius: 6px;
60
+ }
61
+
62
+ .system-button-type .x-btn-icon-el {
63
+ //width: 18px;
64
+ //height: 18px;
65
+ }
66
+
67
+ .system-button-type .x-btn-split-right::before,
68
+ .system-button-type .x-btn-arrow-el::before {
69
+ width: 0 !important;
70
+ right: 0 !important;
71
+ }
72
+
73
+ .system-button-type {
74
+ .x-btn-split-right::after {
75
+ color: var(--base-dark-color) !important;
76
+ padding-left: 5px;
77
+ }
78
+
79
+ .x-btn-split-right > .x-btn-button::after {
80
+ border-right-color: var(--base-dark-color) !important;
81
+ }
82
+ }
83
+ }
@@ -0,0 +1,102 @@
1
+ Ext.define('Coon.report.plugin.grid.addFilterConditionPlugin.SelectColumnPanel', {
2
+ extend: 'Ext.tree.Panel',
3
+ title: 'Добавить фильтр',
4
+ alias: 'widget.SelectColumnPanel',
5
+ rootVisible: false,
6
+ hideHeaders: true,
7
+ rowLines: true,
8
+ store: {
9
+ type: 'tree',
10
+ filterer: 'bottomup',
11
+ root: {
12
+ expanded: true,
13
+ children: [],
14
+ },
15
+ },
16
+ autoLoad: false,
17
+ columns: {
18
+ items: [
19
+ {
20
+ xtype: 'treecolumn',
21
+ flex: 1,
22
+ dataIndex: 'text',
23
+ }
24
+ ],
25
+ },
26
+
27
+ initComponent: function() {
28
+ this.tbar = [
29
+ {
30
+ xtype: 'textfield',
31
+ fieldLabel: 'Поиск',
32
+ flex: 1,
33
+ triggers: {
34
+ clear: {
35
+ cls: 'svg-icon svg-icon-cancel-small',
36
+ tooltip: 'Очистить поле',
37
+ hidden: false,
38
+ handler: function() {
39
+ this.clear();
40
+ },
41
+ },
42
+ },
43
+ listeners: {
44
+ change: {
45
+ fn: this.onFilter.bind(this),
46
+ buffer: 200,
47
+ },
48
+ },
49
+ }
50
+ ];
51
+ this.buttons = [
52
+ {
53
+ text: 'Добавить',
54
+ ui: 'orange-button',
55
+ handler: this.onSelectColumn.bind(this),
56
+ },
57
+ {
58
+ text: 'Отменить',
59
+ ui: 'green-button',
60
+ handler: this.onClose.bind(this),
61
+ }
62
+ ];
63
+ this.callParent();
64
+ this.on('celldblclick', this.onCellClick, this);
65
+ this.on('itemkeydown', this.onItemKeyDown, this);
66
+ },
67
+
68
+ onCellClick: function() {
69
+ this.onSelectColumn();
70
+ },
71
+
72
+ onItemKeyDown: function(view, record, item, index, e) {
73
+ if (record.isLeaf() && e.keyCode === e.ENTER) {
74
+ this.onSelectColumn();
75
+ }
76
+ },
77
+
78
+ onSelectColumn() {
79
+ const record = this.getSelection()[0];
80
+ if (record && record.isLeaf()) {
81
+ this.fireEvent('selectColumn', {
82
+ dataIndex: record.get('id'),
83
+ });
84
+ this.onClose();
85
+ }
86
+ },
87
+
88
+ onClose() {
89
+ this.fireEvent('close');
90
+ },
91
+
92
+ onFilter(field, value) {
93
+ field.triggers.clear.setHidden(!value);
94
+ this.getStore().clearFilter();
95
+ const regexp = new RegExp(value, 'i');
96
+ this.getStore().filterBy(function(record) {
97
+ return (Ext.isString(record.get('text')) && regexp.test(record.get('text'))) ||
98
+ (Ext.isString(record.get('columnGroup')) && regexp.test(record.get('columnGroup')));
99
+ }, this);
100
+ },
101
+
102
+ });