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
@@ -25,7 +25,7 @@ Ext.define('Coon.uielement.component.settings.UiCustomPanelEditorController', {
25
25
  refreshModelView: '{previewTabs.activeTab}',
26
26
  },
27
27
 
28
- receiveMessage: function(event) {
28
+ receiveMessage(event) {
29
29
  if (event.data == 'give me elements') {
30
30
  if (!this.getView()) {
31
31
  return;
@@ -42,7 +42,7 @@ Ext.define('Coon.uielement.component.settings.UiCustomPanelEditorController', {
42
42
  }
43
43
  },
44
44
 
45
- init: function(view) {
45
+ init(view) {
46
46
  view.doInit = this.doInit.bind(this);
47
47
  this.lookup('pluginPanel').fireEvent('load', []);
48
48
  window.addEventListener('message', this.receiveMessage.bind(this), false);
@@ -55,17 +55,19 @@ Ext.define('Coon.uielement.component.settings.UiCustomPanelEditorController', {
55
55
  });
56
56
  const referencesStore = Ext.data.StoreManager.lookup('formReferences');
57
57
  referencesStore && referencesStore.removeAll();
58
- this.getView().down('UiCustomPanelPluginPanel').on('ExecuteFunctionPluginChange', this.onChangeExecuteFunctionPlugin, this);
58
+ grid.on('select', this.setUnusedHandlers, this);
59
59
  },
60
- onChangeExecuteFunctionPlugin: function() {
60
+
61
+ setUnusedHandlers() {
61
62
  const uiEditor = this.lookup('UiAceEditorPanel').lookup('uiEditor');
62
- uiEditor.setHandlerList(this.lookup('pluginPanel').down('UiCustomPanelPluginGrid').getStore().getRange());
63
+ uiEditor.setHandlerList(this.lookup('pluginPanel').down('UiCustomPanelPluginGrid').getStore().getDataSource().getRange());
63
64
  const unused = uiEditor.getHandlerList()
64
65
  .map((plugin) => plugin.handlerName)
65
66
  .filter(uiEditor.isHandlerUnused, this);
66
67
  this.getViewModel().set('unusedHandlers', unused);
67
68
  },
68
- onPluginStoreChanged: function(store) {
69
+
70
+ onPluginStoreChanged(store) {
69
71
  const handlerStoreData = store.getRange().map((record) => {
70
72
  if (record.get('handlerName') !== '-/-') {
71
73
  return {
@@ -161,6 +163,7 @@ Ext.define('Coon.uielement.component.settings.UiCustomPanelEditorController', {
161
163
  plugins.push(Object.assign({
162
164
  jsonProperties: plugin,
163
165
  isSingle: pluginsMap.get(plugin.ptype).isSingle,
166
+ isHandlerRequired: pluginsMap.get(plugin.ptype).getInitialConfig().hasOwnProperty('handlerName'),
164
167
  }, plugin));
165
168
  } else {
166
169
  aceEditorPlugins.push(plugin);
@@ -177,7 +180,7 @@ Ext.define('Coon.uielement.component.settings.UiCustomPanelEditorController', {
177
180
  this.getViewModel().set('aceEditorData', beatifiedValue);
178
181
  },
179
182
 
180
- loadUiElement: function(uiElementCd) {
183
+ loadUiElement(uiElementCd) {
181
184
  if (uiElementCd) {
182
185
  const uiElementCommand = Ext.create('command.GetUIElementCommand');
183
186
  uiElementCommand.on('complete', this.loadUiElementBean, this);
@@ -185,7 +188,7 @@ Ext.define('Coon.uielement.component.settings.UiCustomPanelEditorController', {
185
188
  }
186
189
  },
187
190
 
188
- checkVerifiedPluginClasses: function() {
191
+ checkVerifiedPluginClasses() {
189
192
  return Object.keys(Ext.ClassManager.classes).reduce((acc, key) => {
190
193
  const prototype = Ext.ClassManager.classes[key].prototype;
191
194
  if (prototype) {
@@ -199,7 +202,7 @@ Ext.define('Coon.uielement.component.settings.UiCustomPanelEditorController', {
199
202
  }, new Map());
200
203
  },
201
204
 
202
- doInit: function(uiElementCd) {
205
+ doInit(uiElementCd) {
203
206
  if (uiElementCd) {
204
207
  this.loadUiElement(uiElementCd);
205
208
  } else {
@@ -207,7 +210,7 @@ Ext.define('Coon.uielement.component.settings.UiCustomPanelEditorController', {
207
210
  }
208
211
  },
209
212
 
210
- saveHandler: function() {
213
+ saveHandler() {
211
214
  this.beatify();
212
215
  this.checkValidity()
213
216
  .then(() => {
@@ -228,7 +231,7 @@ Ext.define('Coon.uielement.component.settings.UiCustomPanelEditorController', {
228
231
  });
229
232
  },
230
233
 
231
- checkValidity: function() {
234
+ checkValidity() {
232
235
  const vm = this.getViewModel();
233
236
  const errors = [];
234
237
 
@@ -259,7 +262,7 @@ Ext.define('Coon.uielement.component.settings.UiCustomPanelEditorController', {
259
262
  }
260
263
  },
261
264
 
262
- isUsedUiElement: function() {
265
+ isUsedUiElement() {
263
266
  return Coon.util.promisifyCmd('command.GetUIElementCommand', this.lookup('uielementId').value, true)
264
267
  .then((uiElement) => {
265
268
  if (uiElement) {
@@ -269,7 +272,7 @@ Ext.define('Coon.uielement.component.settings.UiCustomPanelEditorController', {
269
272
  });
270
273
  },
271
274
 
272
- createAnnotationWindow: function(messages) {
275
+ createAnnotationWindow(messages) {
273
276
  const aceEditor = this.getView().down('UiAceEditor');
274
277
  const annotationWindow = Ext.create({
275
278
  xtype: 'UiCustomPanelAnnotationWindow',
@@ -311,15 +314,15 @@ Ext.define('Coon.uielement.component.settings.UiCustomPanelEditorController', {
311
314
  }, this);
312
315
  },
313
316
 
314
- closeHandler: function() {
317
+ closeHandler() {
315
318
  this.close();
316
319
  },
317
320
 
318
- close: function() {
321
+ close() {
319
322
  this.getView().fireEvent('close');
320
323
  },
321
324
 
322
- inputParameters: function() {
325
+ inputParameters() {
323
326
  return [
324
327
  {name: 'uiElementCd', description: 'uiElementCd', required: true}
325
328
  ];
@@ -329,7 +332,7 @@ Ext.define('Coon.uielement.component.settings.UiCustomPanelEditorController', {
329
332
  * @param {Ext.button.Button} component
330
333
  * @param {Event} e
331
334
  */
332
- beatify: function(component, e) {
335
+ beatify(component, e) {
333
336
  this.lookup('UiAceEditorPanel').down('UiAceEditor').flush();
334
337
  const vm = this.getViewModel();
335
338
  const value = vm.get('aceEditorData');
@@ -365,7 +368,7 @@ Ext.define('Coon.uielement.component.settings.UiCustomPanelEditorController', {
365
368
  UiAceEditor.on('linterReady', UiAceEditor.doLint, UiAceEditor);
366
369
  },
367
370
 
368
- updateHandlersStore: function(pluginsArr) {
371
+ updateHandlersStore(pluginsArr) {
369
372
  const handlerStoreData = [];
370
373
  pluginsArr.forEach((el) => {
371
374
  const {handlerName, ptype} = el;
@@ -376,7 +379,7 @@ Ext.define('Coon.uielement.component.settings.UiCustomPanelEditorController', {
376
379
  this.getViewModel().getStore('handlersStore').setData(handlerStoreData);
377
380
  },
378
381
 
379
- showPanel: function() {
382
+ showPanel() {
380
383
  this.beatify();
381
384
  const vm = this.getViewModel();
382
385
  const settings = vm.get('uiElement');
@@ -398,7 +401,7 @@ Ext.define('Coon.uielement.component.settings.UiCustomPanelEditorController', {
398
401
  }
399
402
  },
400
403
 
401
- autoloadChange: function(cb, newValue) {
404
+ autoloadChange(cb, newValue) {
402
405
  const vm = this.getViewModel();
403
406
  const isFrame = !vm.get('formEditorIsPage');
404
407
  const target = isFrame ? this.lookup('frame').getFrame().contentWindow : this.newPageRef;
@@ -407,7 +410,7 @@ Ext.define('Coon.uielement.component.settings.UiCustomPanelEditorController', {
407
410
  }
408
411
  },
409
412
 
410
- reloadFrame: function() {
413
+ reloadFrame() {
411
414
  this.beatify();
412
415
  const vm = this.getViewModel();
413
416
  if (!vm.get('formEditorIsPage')) {
@@ -417,7 +420,7 @@ Ext.define('Coon.uielement.component.settings.UiCustomPanelEditorController', {
417
420
  }
418
421
  },
419
422
 
420
- changeEditorLocation: function() {
423
+ changeEditorLocation() {
421
424
  const vm = this.getViewModel();
422
425
  if (!vm.get('formEditorIsPage')) {
423
426
  this.openNewPage();
@@ -426,7 +429,7 @@ Ext.define('Coon.uielement.component.settings.UiCustomPanelEditorController', {
426
429
  }
427
430
  },
428
431
 
429
- openNewPage: function() {
432
+ openNewPage() {
430
433
  const vm = this.getViewModel();
431
434
  if (this.newPageRef) {
432
435
  this.newPageRef.close();
@@ -440,7 +443,7 @@ Ext.define('Coon.uielement.component.settings.UiCustomPanelEditorController', {
440
443
  vm.set('formEditorIsPage', true);
441
444
  },
442
445
 
443
- destroy: function(...args) {
446
+ destroy(...args) {
444
447
  const me = this;
445
448
  if (me.newPageRef) {
446
449
  me.newPageRef.close();
@@ -448,7 +451,7 @@ Ext.define('Coon.uielement.component.settings.UiCustomPanelEditorController', {
448
451
  me.callParent(...args);
449
452
  },
450
453
 
451
- openFrameView: function() {
454
+ openFrameView() {
452
455
  const vm = this.getViewModel();
453
456
  if (this.newPageRef) {
454
457
  this.newPageRef.close();
@@ -464,7 +467,7 @@ Ext.define('Coon.uielement.component.settings.UiCustomPanelEditorController', {
464
467
  vm.set('formEditorIsPage', false);
465
468
  },
466
469
 
467
- needConfirmBeforeClose: function(view) {
470
+ needConfirmBeforeClose(view) {
468
471
  this.beatify();
469
472
  Ext.MessageBox.show({
470
473
  title: 'Закрыть',
@@ -484,11 +487,13 @@ Ext.define('Coon.uielement.component.settings.UiCustomPanelEditorController', {
484
487
  },
485
488
  });
486
489
  },
487
- copyHash: function() {
490
+
491
+ copyHash() {
488
492
  const hash = this.getViewModel().get('uiElementHash');
489
493
  Coon.util.copyToClipboard(hash);
490
494
  },
491
- checkEqualuty: function() {
495
+
496
+ checkEqualuty() {
492
497
  const field = this.lookup('insertHash');
493
498
  const hash = field.getValue();
494
499
  field.setValue(hash.replace(/[^A-Za-z0-9]/g, '').trim());
@@ -509,7 +514,8 @@ Ext.define('Coon.uielement.component.settings.UiCustomPanelEditorController', {
509
514
  );
510
515
  }
511
516
  },
512
- clearTrigger: function(field) {
517
+
518
+ clearTrigger(field) {
513
519
  field.clear();
514
520
  this.lookup('iconComponent').setHtml('');
515
521
  },
@@ -29,14 +29,21 @@ Ext.define('Coon.uielement.component.settings.plugin.UiCustomPanelPluginGrid', {
29
29
  },
30
30
 
31
31
  viewConfig: {
32
- getRowClass: function(rec) {
32
+ getRowClass: function(rec, i, rp, store) {
33
+ const rowClasses = [];
34
+
33
35
  if (rec.get('isDeleted')) {
34
- return 'deletedRecord';
36
+ rowClasses.push('deletedRecord');
35
37
  }
36
38
  if (rec.get('isNew')) {
37
- return 'newRecord';
39
+ rowClasses.push('newRecord');
40
+ }
41
+
42
+ if (rec.get('hasInvalidName')) {
43
+ rowClasses.push('invalidName');
38
44
  }
39
- return '';
45
+
46
+ return rowClasses.join(' ');
40
47
  },
41
48
  },
42
49
  setData: function(data) {
@@ -71,40 +78,107 @@ Ext.define('Coon.uielement.component.settings.plugin.UiCustomPanelPluginGrid', {
71
78
  dockedItems: [{
72
79
  xtype: 'toolbar',
73
80
  dock: 'top',
81
+ layout: {
82
+ type: 'vbox',
83
+ align: 'stretch',
84
+ },
74
85
  items: [
75
86
  {
76
- xtype: 'ForeignButton',
77
- text: 'Добавить',
78
- ui: 'blue-text-button-border',
79
- createSelectWindow: function() {
80
- return Ext.create('Coon.uielement.component.settings.plugin.UiCustomPanelPluginSelectWindow', {
81
- onlyVerifiedPlugins: true,
82
- exclude: {
83
- handler: 'excludePtypes',
84
- scope: this,
85
- },
86
- });
87
- },
88
- listeners: {
89
- select: 'addHandler',
87
+ xtype: 'container',
88
+ flex: 1,
89
+ margin: '0 0 5 0',
90
+ layout: {
91
+ type: 'hbox',
92
+ align: 'end',
90
93
  },
94
+ items: [
95
+ {
96
+ xtype: 'ForeignButton',
97
+ flex: 1,
98
+ text: 'Добавить',
99
+ ui: 'blue-text-button-border',
100
+ margin: '0 10 0 0',
101
+ createSelectWindow: function() {
102
+ return Ext.create('Coon.uielement.component.settings.plugin.UiCustomPanelPluginSelectWindow', {
103
+ onlyVerifiedPlugins: true,
104
+ exclude: {
105
+ handler: 'excludePtypes',
106
+ scope: this,
107
+ },
108
+ });
109
+ },
110
+ listeners: {
111
+ select: 'addHandler',
112
+ },
113
+ bind: {
114
+ disabled: '{favoriteButtonPressed}',
115
+ },
116
+ },
117
+ {
118
+ xtype: 'textfield',
119
+ itemId: 'searchInPlugins',
120
+ emptyText: 'фильтр по тексту в плагинах',
121
+ flex: 2,
122
+ triggers: {
123
+ clear: {
124
+ cls: 'svg-icon svg-icon-cancel-small',
125
+ tooltip: 'Очистить поле',
126
+ handler: function() {
127
+ this.clear();
128
+ },
129
+ },
130
+ },
131
+ }
132
+ ],
91
133
  },
92
134
  {
93
- xtype: 'textfield',
94
- emptyText: 'фильтр по тексту в плагинах',
135
+ xtype: 'container',
95
136
  flex: 1,
96
- listeners: {
97
- change: 'searchInPlugins',
137
+ layout: {
138
+ type: 'hbox',
98
139
  },
99
- triggers: {
100
- clear: {
101
- cls: 'svg-icon svg-icon-cancel-small',
102
- tooltip: 'Очистить поле',
103
- handler: function() {
104
- this.clear();
140
+ items: [
141
+ {
142
+ xtype: 'segmentedbutton',
143
+ allowToggle: false,
144
+ margin: '0 3 0 0',
145
+ bind: {
146
+ disabled: '{favoriteButtonPressed}',
105
147
  },
148
+ items: [
149
+ {
150
+ xtype: 'button',
151
+ itemId: 'historyButton',
152
+ iconCls: 'svg-fa svg-fa-arrow-rotate-left',
153
+ tooltip: 'Показать историю',
154
+ arrowVisible: false,
155
+ disabled: true,
156
+ allowToggle: false,
157
+ padding: '5 8',
158
+ },
159
+ {
160
+ xtype: 'button',
161
+ text: 'X',
162
+ itemId: 'clearHistoryButton',
163
+ tooltip: 'Очистить историю',
164
+ disabled: true,
165
+ }
166
+ ],
106
167
  },
107
- },
168
+ {
169
+ xtype: 'splitbutton',
170
+ ui: 'blue-text-button-border',
171
+ itemId: 'favoriteButton',
172
+ iconCls: 'svg-fa svg-fa-star',
173
+ tooltip: 'Показать избранное',
174
+ enableToggle: true,
175
+ disabled: true,
176
+ padding: '5 8',
177
+ bind: {
178
+ pressed: '{favoriteButtonPressed}',
179
+ },
180
+ }
181
+ ],
108
182
  }
109
183
  ],
110
184
  }],
@@ -151,18 +225,57 @@ Ext.define('Coon.uielement.component.settings.plugin.UiCustomPanelPluginGrid', {
151
225
  type: 'string',
152
226
  },
153
227
  renderer: function(value, metaData, record) {
154
- const unused = record.get('unusedHandler');
155
- if (unused) {
228
+ const tooltips = [];
229
+
230
+ if (record.get('unusedHandler')) {
156
231
  metaData.tdStyle = 'color: red';
157
- return Coon.format.withHint(value, 'Обработчик нигде не используется');
232
+ tooltips.push('Обработчик нигде не используется');
233
+ }
234
+ if (record.get('hasInvalidName')) {
235
+ tooltips.push('Имя обработчика отсутствует или дублируется');
236
+ }
237
+
238
+ if (tooltips.length) {
239
+ return Coon.format.withHint(value, `${tooltips.join('<br/>')}`);
240
+ } else {
241
+ return value;
158
242
  }
159
- return value;
160
243
  },
161
244
  sorter: function(v1, v2) {
162
245
  v1 = v1.get('handlerName');
163
246
  v2 = v2.get('handlerName');
164
247
  return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
165
248
  },
249
+ },
250
+ {
251
+ xtype: 'actioncolumn',
252
+ itemId: 'favoritesColumn',
253
+ width: 30,
254
+ menuDisabled: true,
255
+ sortable: false,
256
+ getClass: function(v, meta, record) {
257
+ const favorites = this.lookupController().favoritePlugins.items || {};
258
+ if (record.get('hasInvalidName')) {
259
+ return 'pointerNone';
260
+ }
261
+ if (favorites.hasOwnProperty(record.getId()) && favorites[record.getId()]) {
262
+ return 'svg-icon svg-icon-star';
263
+ } else {
264
+ return 'svg-icon svg-icon-bg-gray svg-icon-star';
265
+ }
266
+ },
267
+ getTip: function(v, meta, record) {
268
+ const favorites = this.lookupController().favoritePlugins.items || {};
269
+ if (record.get('hasInvalidName')) {
270
+ return 'Имя обработчика невалидно';
271
+ }
272
+ if (favorites.hasOwnProperty(record.getId()) && favorites[record.getId()]) {
273
+ return 'Удалить из избранного';
274
+ } else {
275
+ return 'Добавить в избранное';
276
+ }
277
+ },
278
+ handler: 'toggleFavoriteState',
166
279
  }
167
280
  ],
168
281
  },
@@ -8,4 +8,32 @@
8
8
  .newRecord {
9
9
  font-style:italic;
10
10
  }
11
+ .invalidName {
12
+ background-color: rgba(139, 0, 0, 0.1);
13
+ }
14
+ .x-ripple-container {
15
+ display: none;
16
+ }
17
+ .svg-icon-bg-gray {
18
+ opacity: 0.2;
19
+ }
20
+ .x-btn-wrap-blue-text-button-border-small.x-btn-split-right:after {
21
+ padding-left: 8px;
22
+ }
23
+ .x-segmented-button .x-segmented-button-item {
24
+ padding-left: 3px;
25
+ padding-right: 3px;
26
+ }
27
+ .pointerNone {
28
+ cursor: no-drop;
29
+ }
11
30
  }
31
+
32
+ .UICustomPanelPluginMenu {
33
+ .menuPluginItem .x-menu-item-text-default.x-menu-item-indent-no-separator {
34
+ margin-left: 15px;
35
+ }
36
+ .x-menu-item.menuPluginItemCurrent {
37
+ background-color: var(--base-light-color);
38
+ }
39
+ }