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,157 @@
1
+ /**
2
+ * Плагин нормализует поведение переноса фокуса с поля на поле в FilterPanel по нажатию TAB и SHIFT+TAB.
3
+ * Включает на полях формы свойство enableKeyEvents.
4
+ */
5
+ Ext.define('Coon.report.component.reportpanel.FormFieldFocusPlugin', {
6
+ extend: 'Ext.AbstractPlugin',
7
+ alias: 'plugin.FormFieldFocusPlugin',
8
+ id: 'FormFieldFocusPlugin',
9
+ // Установить фокус по умолчанию на первое поле
10
+ defaultFocusFirstField: true,
11
+ // Установить фокус на это поле.
12
+ defaultFocusField: undefined,
13
+ // Отключение плагина можно сделать путем установки свойства репорта formFieldFocusPluginConfig
14
+ disabled: false,
15
+
16
+ constructor: function(config) {
17
+ Ext.apply(this, config || {});
18
+ this.callParent([config]);
19
+ },
20
+
21
+ init: function(formPanel) {
22
+ if (this.disabled) {
23
+ Coon.log.debug('FormFieldFocusPlugin disabled!');
24
+ return;
25
+ }
26
+ this.fields = Coon.Function.getFormFields(formPanel);
27
+ if (!this.fields.length) {
28
+ return;
29
+ }
30
+
31
+ this.getCmp().on('afterrender', function() {
32
+ this.preprocessFields();
33
+ this.setFocus();
34
+ const centerView = this.getCmp().up('centerview');
35
+ if (centerView) {
36
+ const container = centerView.getLayout().getActiveItem();
37
+ container.on('activate', this.restoreFocus, this);
38
+ }
39
+ }, this);
40
+ formPanel.addCls('panel-with-form-field-focus-plugin');
41
+ },
42
+
43
+ getAvailableFields() {
44
+ return this.fields.filter((field) => this.isFieldFocusable(field));
45
+ },
46
+
47
+ getFields() {
48
+ return this.fields;
49
+ },
50
+
51
+ buildFieldFocusIds() {
52
+ this.getFields().forEach((field, idx) => {
53
+ this.clearFieldFocusId(field);
54
+ });
55
+ this.getAvailableFields().forEach((field, idx) => {
56
+ this.setFieldFocusId(field, idx);
57
+ });
58
+ },
59
+
60
+ setFieldFocusId(field, idx) {
61
+ const fieldsCount = this.getAvailableFields().length;
62
+ field.prevFocusId = idx === 0 ? fieldsCount - 1 : idx - 1;
63
+ field.focusId = idx;
64
+ field.nextFocusId = idx === fieldsCount - 1 ? 0 : idx + 1;
65
+ },
66
+
67
+ clearFieldFocusId(field) {
68
+ field.prevFocusId = undefined;
69
+ field.focusId = undefined;
70
+ field.nextFocusId = undefined;
71
+ },
72
+
73
+ preprocessFields() {
74
+ this.buildFieldFocusIds();
75
+ this.getFields()
76
+ .forEach((field, idx) => {
77
+ if (field.defaultFocus) {
78
+ this.defaultFocusField = field;
79
+ }
80
+ field.enableKeyEvents = true;
81
+ field.on({
82
+ specialkey: this.onSpecialkeyPress,
83
+ focus: function(f) {
84
+ this.setLastFocus(f.focusId);
85
+ }.bind(this),
86
+ show: this.buildFieldFocusIds,
87
+ hide: this.buildFieldFocusIds,
88
+ enable: this.buildFieldFocusIds,
89
+ disable: this.buildFieldFocusIds,
90
+ scope: this,
91
+ });
92
+ });
93
+ },
94
+
95
+ setFocus() {
96
+ const visibleFields = this.getAvailableFields();
97
+ if (!visibleFields.length) {
98
+ return;
99
+ }
100
+ if (this.defaultFocusFirstField) {
101
+ let fieldForFocus = this.defaultFocusField;
102
+ if (!fieldForFocus && this.defaultFocusFirstField) {
103
+ if (this.isFieldFocusable(visibleFields[0])) {
104
+ fieldForFocus = visibleFields[0].focus(false, 100);
105
+ } else {
106
+ fieldForFocus = this.getNextField(visibleFields[0]);
107
+ }
108
+ }
109
+ if (fieldForFocus && this.isFieldFocusable(fieldForFocus)) {
110
+ fieldForFocus.focus(false, 100);
111
+ }
112
+ }
113
+ },
114
+
115
+ restoreFocus() {
116
+ const lastFocusedField = this.getLastFocusedField();
117
+ if (lastFocusedField) {
118
+ lastFocusedField.focus(false, 100);
119
+ }
120
+ },
121
+
122
+ getFieldByFocusId(focusId) {
123
+ return this.getCmp().down(`[focusId=${focusId}]`);
124
+ },
125
+
126
+ getNextField(field) {
127
+ return this.getFieldByFocusId(field.nextFocusId);
128
+ },
129
+
130
+ getPrevField(field) {
131
+ return this.getFieldByFocusId(field.prevFocusId);
132
+ },
133
+
134
+ setLastFocus(focusId) {
135
+ this.lastFocusId = focusId;
136
+ },
137
+
138
+ getLastFocusedField() {
139
+ const field = this.getFieldByFocusId(this.lastFocusId);
140
+ return this.isFieldFocusable(field) && field;
141
+ },
142
+
143
+ onSpecialkeyPress: function(field, e) {
144
+ const shiftKey = e.shiftKey;
145
+ if (e.keyCode === e.TAB) {
146
+ e.stopEvent();
147
+ const nextFocusField = shiftKey ? this.getPrevField(field) : this.getNextField(field);
148
+ if (nextFocusField) {
149
+ nextFocusField.focus(false, 100);
150
+ }
151
+ }
152
+ },
153
+
154
+ isFieldFocusable(field) {
155
+ return field && !field.isHidden() && !field.isDisabled() && !field.readOnly && field.focusable;
156
+ },
157
+ });
@@ -0,0 +1,14 @@
1
+ $focus-background-color: rgba(254, 249, 233, 1) !default;
2
+ .panel-with-form-field-focus-plugin {
3
+ .x-field:has(*:focus) {
4
+ background-color: $focus-background-color;
5
+ background-clip: content-box;
6
+
7
+ .x-form-item-body {
8
+ background-color: $focus-background-color;
9
+ }
10
+ }
11
+ .x-form-cb-wrap-inner:has(*:focus) {
12
+ background-color: $focus-background-color;
13
+ }
14
+ }
@@ -31,7 +31,7 @@ Ext.define('Coon.report.component.report.NorthPanel', {
31
31
  cls: 'x-unselectable btn-toggle',
32
32
  style: {
33
33
  backgroundColor: 'transparent!important',
34
- marginRight: '20px',
34
+ marginRight: '8px',
35
35
  },
36
36
  scale: 'small',
37
37
  hidden: true,
@@ -97,7 +97,7 @@ Ext.define('Coon.report.component.report.NorthPanel', {
97
97
  },
98
98
  cls: 'buttonsContainer',
99
99
  defaults: {
100
- margin: '0 16 0 0',
100
+ margin: '0 8px 0 0',
101
101
  xtype: 'button',
102
102
  },
103
103
  items: [
@@ -137,17 +137,12 @@ Ext.define('Coon.report.component.report.NorthPanel', {
137
137
  }
138
138
  ];
139
139
 
140
- /**
141
- * Только при добавлении компонента в ReportPanel можно получить ссылку на родителя
142
- */
143
- this.on('added', function() {
144
- this.reportPanel = this.findParentByType('ReportPanel') || this.findParentByType('ReportFilterForm');
145
- this.searchButton.handler = this.reportPanel ? Ext.bind(this.reportPanel.filterHandler, this.reportPanel) : Ext.emptyFn;
146
- this.clearButton.handler = Ext.bind(function() {
147
- this.clearFilter();
148
- this.clearData();
149
- }, this.reportPanel);
150
- }, this);
140
+ this.reportPanel = this.up('ReportPanel,ReportFilterForm');
141
+ this.searchButton.handler = this.reportPanel ? Ext.bind(this.reportPanel.filterHandler, this.reportPanel) : Ext.emptyFn;
142
+ this.clearButton.handler = Ext.bind(function() {
143
+ this.clearFilter();
144
+ this.clearData();
145
+ }, this.reportPanel);
151
146
 
152
147
  this.callParent();
153
148
  },
@@ -166,21 +161,25 @@ Ext.define('Coon.report.component.report.NorthPanel', {
166
161
  },
167
162
 
168
163
  configureFilterPanel: function(reportFormBean) {
169
- const ns = Coon.report.model.ReportBeanFields;
170
- const properties = Coon.Function.convertAdvancedProperties(reportFormBean[ns.$properties]) || {};
164
+ const report = this.up('ReportPanel');
165
+ const properties = report && report.configProperties ||
166
+ Coon.Function.convertAdvancedProperties(reportFormBean.properties) || {};
171
167
  Ext.merge(this, properties);
172
168
  this.filterPlugins.push({
173
169
  ptype: 'EnterConfirmFormPlugin',
174
170
  confirmHandler: this.reportPanel ? Ext.bind(this.reportPanel.filterHandler, this.reportPanel) : Ext.emptyFn,
175
171
  });
172
+ this.filterPlugins.push(Ext.apply({
173
+ ptype: 'FormFieldFocusPlugin',
174
+ }, properties.formFieldFocusPluginConfig || {}, {defaultFocusFirstField: true}));
176
175
 
177
176
  const [enableHighlightingRequiredFields, hiddenLegend] = this.hasPropertiesFilterPanel(reportFormBean.plugins, properties);
178
177
  this.hiddenLegend = !!hiddenLegend;
179
178
  this.enableHighlightingRequiredFields = enableHighlightingRequiredFields;
180
179
  const filterPanel = Ext.widget('FilterPanel', {
181
- configurationList: reportFormBean[ns.$parameters],
180
+ configurationList: reportFormBean.parameters,
182
181
  itemsOnRow: properties['filterItemsOnRow'] || 2,
183
- enableHighlightingRequiredFields: enableHighlightingRequiredFields,
182
+ enableHighlightingRequiredFields,
184
183
  plugins: this.filterPlugins,
185
184
  });
186
185
  this.filterPanel = filterPanel;
@@ -14,7 +14,7 @@
14
14
  min-height: 0px !important;
15
15
  }
16
16
  .UiCFCell{
17
- margin: 0px 2px !important;
17
+ margin: 0 4px 0 0 !important;
18
18
  }
19
19
 
20
20
  @include sigma-button-small-ui(
@@ -0,0 +1,219 @@
1
+ /**
2
+ * Компонент контекстного меню репорта
3
+ * Меню содержит несколько групп. Порядок следования групп определен в конфигурации меню.
4
+ * Для каждой группы реализован вспомогательный метод для добавления в группу пункта меню.
5
+ * При первом отображении пункты меню сортируются единожды и при необходимости добавляются горизонтальные разделители между группами.
6
+ * У группы pluginbuttons в основном меню есть ограничение на 5 (maxMenuGroupItems) видимых пунктов меню. Если у этой группы появляется 6-й видимый
7
+ * пункт меню, то создается подменю с пунктами, которые не поместились в основное меню.
8
+ */
9
+ Ext.define('Coon.report.component.reportpanel.ReportContextMenu', {
10
+ extend: 'Ext.menu.Menu',
11
+ alias: 'widget.ReportContextMenu',
12
+ uses: [],
13
+ requires: [],
14
+ orderOfGroups: {
15
+ // Кнопка "Копировать" CopyCellValueMenuItem
16
+ copy: {
17
+ order: 1, // порядковый номер группы
18
+ hidden: false, // видимость группы
19
+ separator: true, // наличие разделителя после группы
20
+ },
21
+ // AddFilterConditionPlugin
22
+ advancedsearch: {order: 2, hidden: false, separator: true},
23
+ // CalculatorPlugin
24
+ calc: {order: 4, hidden: false, separator: true},
25
+ // GridToolbarButtonPlugin
26
+ pluginbuttons: {order: 3, hidden: false, separator: true},
27
+ },
28
+ sorted: false,
29
+ maxMenuGroupItems: 2,
30
+
31
+ initComponent() {
32
+ this.callParent(arguments);
33
+ this.on({
34
+ beforehide: 'onBeforeHideMenu',
35
+ scope: this,
36
+ });
37
+ },
38
+
39
+ onBeforeHideMenu() {
40
+ this.unfoldReportPluginButtons();
41
+ },
42
+
43
+ addToAdvancedSearch(item) {
44
+ this.addMenuItem('advancedsearch', item);
45
+ },
46
+
47
+ addCalcMenuItem(item) {
48
+ this.addMenuItem('calc', item);
49
+ },
50
+
51
+ addPluginButton(item) {
52
+ this.addMenuItem('pluginbuttons', item);
53
+ },
54
+
55
+ addCopyButton(item) {
56
+ this.addMenuItem('copy', item);
57
+ },
58
+
59
+ addMenuItem(group, item) {
60
+ if (!Ext.isString(group) || !Object.keys(this.orderOfGroups).includes(group)) {
61
+ return Coon.log.warn('Пункт меню не добавлен. Ошибочная группа: ', group);
62
+ }
63
+ item.group = group;
64
+ this.add(item);
65
+ },
66
+
67
+ sortFn(a, b) {
68
+ if (!a.group) {
69
+ a.group = 0;
70
+ }
71
+ if (!b.group) {
72
+ b.group = 0;
73
+ }
74
+ const orderA = this.orderOfGroups[a.group] && this.orderOfGroups[a.group].order;
75
+ const orderB = this.orderOfGroups[b.group] && this.orderOfGroups[b.group].order;
76
+ let ord; let sortsequenceA; let sortsequenceB;
77
+ if (a.group==='pluginbuttons' && b.group==='pluginbuttons') {
78
+ sortsequenceA = a.config.sortSequence;
79
+ sortsequenceB = b.config.sortSequence;
80
+ ord = (sortsequenceA > sortsequenceB) ? 1 : ((sortsequenceB > sortsequenceA) ? -1 : 0);
81
+ }
82
+ const groupSort = (orderA > orderB) ? 1 : ((orderB > orderA) ? -1 : 0);
83
+ if (Ext.isDefined(ord) && groupSort===0) {
84
+ return ord;
85
+ }
86
+ return groupSort;
87
+ },
88
+
89
+ isItemHidden(item) {
90
+ if (Ext.isFunction(item.isValid)) {
91
+ return !item.isValid();
92
+ } else if (Ext.isFunction(item.isItemHidden)) {
93
+ return item.isItemHidden();
94
+ } else {
95
+ return false;
96
+ }
97
+ },
98
+
99
+ isItemDisabled(item) {
100
+ if (Ext.isFunction(item.isItemDisabled)) {
101
+ return item.isItemDisabled();
102
+ } else {
103
+ return false;
104
+ }
105
+ },
106
+
107
+ hasGroupVisibleItems(group) {
108
+ return this.items.findBy(function(item) {
109
+ return item.xtype!=='menuseparator' && item.group === group && !item.isHidden();
110
+ }, this);
111
+ },
112
+
113
+ processItems() {
114
+ if (!this.items) {
115
+ return;
116
+ }
117
+ if (!this.sorted) {
118
+ this.sortAndSeparate();
119
+ }
120
+ this.items.each(function(item) {
121
+ if (item.xtype !== 'menuseparator') {
122
+ const group = item.group;
123
+ const groupHidden = this.orderOfGroups[group].hidden;
124
+ const isItemHidden = groupHidden || this.isItemHidden(item);
125
+ item.setHidden(isItemHidden);
126
+ !isItemHidden && (item.setDisabled(this.isItemDisabled(item)));
127
+ } else {
128
+ item.setVisible(!!this.hasGroupVisibleItems(item.group));
129
+ }
130
+ }, this);
131
+ this.foldReportPluginButtons();
132
+ },
133
+
134
+ foldReportPluginButtons() {
135
+ let i = 0;
136
+ this.lastUnfoldedItem = undefined;
137
+ this.items.each(function(item) {
138
+ if (item.group==='pluginbuttons' && item.xtype!=='menuseparator' && !this.isItemHidden(item)) {
139
+ i++;
140
+ if (i > this.maxMenuGroupItems) {
141
+ this.foldItem(item, this.lastUnfoldedItem);
142
+ } else {
143
+ this.lastUnfoldedItem = item;
144
+ }
145
+ }
146
+ }, this);
147
+ },
148
+
149
+ foldItem(item, after) {
150
+ if (!this.submenu) {
151
+ this.submenu = new Ext.menu.Item({text: 'Другие пункты меню', group: 'pluginbuttons', menu: {items: []}});
152
+ this.add(this.submenu);
153
+ this.moveAfter(this.submenu, after);
154
+ }
155
+ this.moveBetweenMenus(this, this.submenu.menu, item);
156
+ },
157
+
158
+ /**
159
+ * Перенос пункта меню из одного меню в другое.
160
+ * @param {Ext.menu.Menu} fromMenu
161
+ * @param {Ext.menu.Menu} toMenu
162
+ * @param item
163
+ * @param after поместить после этого пункта меню
164
+ */
165
+ moveBetweenMenus(fromMenu, toMenu, item, after) {
166
+ if (!item) {
167
+ return;
168
+ }
169
+ fromMenu.remove(item, {destroy: false});
170
+ toMenu.add(item);
171
+ if (after) {
172
+ toMenu.moveAfter(item, after);
173
+ }
174
+ },
175
+
176
+ /**
177
+ * Перенос при необходимости пунктов из подменю в основное меню
178
+ */
179
+ unfoldReportPluginButtons() {
180
+ if (this.submenu && this.submenu.menu.items.getCount() > 0) {
181
+ this.submenu.menu.items.getRange().reverse().forEach(function(item) {
182
+ this.moveBetweenMenus(this.submenu.menu, this, item, this.lastUnfoldedItem);
183
+ }, this);
184
+ }
185
+ this.remove(this.submenu);
186
+ this.submenu = undefined;
187
+ },
188
+
189
+ /**
190
+ * Сортировка и добавление разделителей
191
+ */
192
+ sortAndSeparate() {
193
+ this.items.sortBy(this.sortFn.bind(this));
194
+ this.sorted = true;
195
+ let curGroup;
196
+ let increment = 0;
197
+ this.items.each(function(item, index) {
198
+ if (item.group !== curGroup && curGroup) {
199
+ this.addSeparator(index + increment, curGroup);
200
+ increment++;
201
+ }
202
+ curGroup = item.group;
203
+ }, this);
204
+ },
205
+
206
+ addSeparator(index, group) {
207
+ this.insert(index, {xtype: 'menuseparator', group});
208
+ },
209
+
210
+ show(xy) {
211
+ if (Ext.isArray(xy)) {
212
+ this.processItems();
213
+ this.showAt(xy);
214
+ } else {
215
+ this.callParent(arguments);
216
+ }
217
+ },
218
+
219
+ });
@@ -24,6 +24,7 @@ Ext.define('Coon.report.component.reportpanel.ReportGrid', {
24
24
  checkedRecords: [],
25
25
  },
26
26
  url: '/ReportFormData/get',
27
+ contextMenuItemsAdded: false,
27
28
 
28
29
  initComponent: function() {
29
30
  this.store = Ext.create('Coon.report.component.reportpanel.ReportStore', {
@@ -49,4 +49,8 @@
49
49
  font-size: 16px !important
50
50
  }
51
51
  }
52
+ // Класс для визуального обозначения колонки, по которой есть локальный фильтр
53
+ .x-grid-cell.filtered-cell {
54
+ //background-color: #fff6e8;
55
+ }
52
56
  }
@@ -63,14 +63,14 @@ Ext.define('Coon.report.component.settings.field.ReportFormFieldsGrid', {
63
63
  xtype: 'button',
64
64
  ui: 'blue-text-button-border',
65
65
  text: 'Добавить',
66
- id: 'addField',
66
+ itemId: 'addField',
67
67
  handler: 'addHandler',
68
68
  },
69
69
  {
70
70
  xtype: 'button',
71
71
  ui: 'blue-text-button-border',
72
72
  text: 'Добавить группу',
73
- id: 'addGroup',
73
+ itemId: 'addGroup',
74
74
  handler: 'addGroupHandler',
75
75
  },
76
76
  {
@@ -61,7 +61,7 @@ Ext.define('Coon.report.component.settings.ReportFormFieldsGridController', {
61
61
 
62
62
  addHandler: function(button) {
63
63
  const view = this.getView();
64
- const parent = button.id === 'addField' ? view.getStore().getRoot() : view.getSelectionModel().getSelection()[0];
64
+ const parent = button.itemId === 'addField' ? view.getStore().getRoot() : view.getSelectionModel().getSelection()[0];
65
65
  parent.appendChild({
66
66
  isNew: true,
67
67
  properties: [],
@@ -98,7 +98,7 @@ Ext.define('Coon.report.component.settings.ReportFormFieldsGridController', {
98
98
  {
99
99
  text: 'Сохранить',
100
100
  handler: function() {
101
- const parent = button.id === 'addGroup' ? view.getStore().getRoot() : view.getSelectionModel().getSelection()[0];
101
+ const parent = button.itemId === 'addGroup' ? view.getStore().getRoot() : view.getSelectionModel().getSelection()[0];
102
102
  parent.appendChild({
103
103
  isNew: true,
104
104
  groupName: win.down('textfield').getValue(),
@@ -119,7 +119,7 @@ Ext.define('Coon.report.component.settings.property.ReportPropertiesPanelControl
119
119
  const editor = this.getPropertyValueEditor(record);
120
120
  if (editor && typeof editor.setValue === 'function') {
121
121
  this.lookup('propertyValueContainer').add(editor);
122
- editor.setBind({value: '{propertyGrid.selection.value}'});
122
+ editor.setBind({value: '{propertyGrid.selection.value || propertyGrid.selection.defaultVal}'});
123
123
  } else {
124
124
  Coon.log.debug('HASN`T EDITOR', record.getData(), editor);
125
125
  }
@@ -193,6 +193,13 @@ Ext.define('Coon.report.component.settings.property.ReportPropertyDictionary', {
193
193
  leaf: true,
194
194
  singleValue: true,
195
195
  description: 'Свойство даёт возможность скрывать/показывать признак обязательности заполнения полей.',
196
+ },
197
+ {
198
+ id: 'formFieldFocusPluginConfig',
199
+ leaf: true,
200
+ defaultVal: '{disabled: false, defaultFocusFirstField: true}',
201
+ description: 'Свойства, передаваемые плагину formFieldFocusPlugin, используемому в фильтр панели репорта ',
202
+ propertyValueType: 'object',
196
203
  }
197
204
  ],
198
205
  },
@@ -122,13 +122,36 @@ Ext.define('Coon.report.plugin.configPanel.AddFilterConditionPluginConfigPanel',
122
122
  ],
123
123
  });
124
124
 
125
+ this.filterAllVisibleField = this.getFilterAllVisibleCheckbox();
126
+ this.filterAllVisibleField.on('change', this.onAllVisibleChange, this);
127
+
125
128
  return [
129
+ this.filterAllVisibleField,
126
130
  this.addToContextMenu,
127
131
  this.filterField,
128
132
  this.grid
129
133
  ];
130
134
  },
131
135
 
136
+ getFilterAllVisibleCheckbox() {
137
+ const checked = true;
138
+ this.toggleFilterableColumn(!checked);
139
+ return Ext.create('Ext.form.field.Checkbox', {
140
+ boxLabel: 'Есть возможность фильтровать все видимые колонки',
141
+ name: 'filterAllVisible',
142
+ inputValue: true,
143
+ checked,
144
+ });
145
+ },
146
+
147
+ onAllVisibleChange(checkbox, value) {
148
+ this.toggleFilterableColumn(!value);
149
+ },
150
+
151
+ toggleFilterableColumn(visible) {
152
+ this.grid.getColumnModel().findColumnByDataIndex('byCellValueFilterable').setVisible(visible);
153
+ },
154
+
132
155
  filter: function(_, value) {
133
156
  const store = this.grid.getStore();
134
157
  store.clearFilter();
@@ -180,16 +203,16 @@ Ext.define('Coon.report.plugin.configPanel.AddFilterConditionPluginConfigPanel',
180
203
  },
181
204
 
182
205
  getConfiguration() {
183
- return {
184
- filterOptions: JSON.stringify(this.grid.getStore().getRange().reduce(
185
- function(acc, current) {
186
- if (current.get('byCellValueFilterable')) {
187
- acc[current.get('reportFieldCd')] = current.get('byCellValueFilterable');
188
- }
189
- return acc;
190
- },
191
- {}
192
- )),
193
- };
206
+ const config = this.callParent();
207
+ config['filterOptions'] = JSON.stringify(this.grid.getStore().getRange().reduce(
208
+ function(acc, current) {
209
+ if (current.get('byCellValueFilterable')) {
210
+ acc[current.get('reportFieldCd')] = current.get('byCellValueFilterable');
211
+ }
212
+ return acc;
213
+ },
214
+ {}
215
+ ));
216
+ return config;
194
217
  },
195
218
  });
@@ -93,9 +93,10 @@ Ext.define('Coon.report.plugin.configPanel.GridFiltersPluginConfigPanelFiltersGr
93
93
  },
94
94
 
95
95
  addHandler: function() {
96
- this.getStore().add(Ext.create('Coon.report.model.ComboValueWrapper'));
96
+ const record = this.getStore().insert(0, {})[0];
97
97
  const editor = this.findPlugin('cellediting');
98
- editor.startEditByPosition({row: this.getStore().getCount() - 1, column: 0});
98
+ const rowIndex = this.getStore().indexOf(record);
99
+ editor.startEditByPosition({row: rowIndex, column: 0});
99
100
  },
100
101
 
101
102
  deleteHandler: function() {