ru.coon 2.7.1 → 2.7.3

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 (22) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/package.json +1 -1
  3. package/src/command/ASyncBaseCommand.js +4 -0
  4. package/src/common/component/editor/CharacteristicLoaderPlugin.js +12 -2
  5. package/src/common/field/combo/CommandComboBox.js +20 -0
  6. package/src/report/component/settings/ReportPropertiesGrid.js +22 -0
  7. package/src/report/component/settings/ReportPropertiesGridController.js +60 -1
  8. package/src/report/component/settings/context/ReportFormContextParametersGrid.js +73 -88
  9. package/src/report/plugin/configPanel/ExecuteCommandButtonPluginConfigPanel.js +92 -59
  10. package/src/report/plugin/grid/ExecuteCommandButtonPlugin.js +23 -8
  11. package/src/report/plugin/grid/ReportColumnStatePlugin.js +10 -7
  12. package/src/uielement/component/UiCustomController.js +6 -15
  13. package/src/uielement/component/settings/UiAceEditor.js +1 -1
  14. package/src/uielement/component/settings/UiAceEditorPanel.js +6 -1
  15. package/src/uielement/component/settings/plugin/UiCustomPanelPluginPanel.scss +19 -0
  16. package/src/uielement/plugin/ExecuteCommandPlugin.js +5 -3
  17. package/src/uielement/plugin/configPanel/executeCommand/DataMappingPanel.js +215 -0
  18. package/src/uielement/plugin/configPanel/executeCommand/ExecuteCommandPluginConfigPanelFormEditor.js +625 -0
  19. package/src/uielement/plugin/configPanel/executeCommand/ExecuteCommandPluginConfigPanelFormEditor.scss +22 -0
  20. package/src/util.js +4 -3
  21. package/src/version.js +1 -1
  22. package/src/uielement/plugin/configPanel/ExecuteCommandPluginConfigPanelFormEditor.js +0 -332
@@ -64,21 +64,17 @@ Ext.define('Coon.uielement.component.UiCustomController', {
64
64
  view.tools.push({
65
65
  tooltip: 'Скопировать ссылку на форму',
66
66
  iconCls: 'svg-icon svg-icon-bg-white svg-icon-link',
67
- callback: function() {
68
- me.copyLinkToBuffer();
69
- },
67
+ callback: me.copyLinkToBuffer.bind(view),
70
68
  });
71
69
  }
72
70
  },
73
71
 
74
72
  copyLinkToBuffer: function() {
75
73
  const vm = this.content.getViewModel();
76
- const area = document.createElement('textarea');
77
74
  const curDate = new Date(vm.get('effectiveDate'));
78
75
  const newDate = Ext.Date.format(curDate, 'Y-m-d');
79
76
  const curUrl = document.location.href;
80
77
  const curMenu = curUrl.substring(curUrl.search('#'), curUrl.length);
81
-
82
78
  const regUrl = '/#';
83
79
  const regIndex = curUrl.search(regUrl) + 1;
84
80
  const newUrl = curUrl.substring(0, regIndex);
@@ -87,20 +83,15 @@ Ext.define('Coon.uielement.component.UiCustomController', {
87
83
  const params = this.content.plugins.find((el) => el.ptype === 'AddDoInitSupportPlugin').parametersToModel;
88
84
  let paramsTextContent = '';
89
85
  for (let i = 0; i < params.length; i++) {
90
- if (params[i] === 'effectiveDate' || vm.get(params[i]) === null) {
86
+ const parameter = typeof params[i] === 'string' ? params[i]: params[i]['valuePath'];
87
+ if (parameter === 'effectiveDate' || vm.get(parameter) === null) {
91
88
  continue;
92
89
  }
93
- paramsTextContent += params[i] + '=' + vm.get(params[i]) + '&';
90
+ paramsTextContent += parameter + '=' + vm.get(parameter) + '&';
94
91
  }
95
92
 
96
- event.target.textContent = newUrl + curMenu + '|ui:' + ui + '?' + paramsTextContent + 'effectiveDate=' + newDate;
97
- const BtnText = event.target.textContent;
98
-
99
- event.target.appendChild(area);
100
- area.value = BtnText;
101
- area.select();
102
- document.execCommand('copy');
103
- event.target.removeChild(area);
93
+ const url = newUrl + curMenu + '|ui:' + ui + '?' + paramsTextContent + 'effectiveDate=' + newDate;
94
+ Coon.util.copyToClipboard(url);
104
95
  Ext.toast('Ссылка скопирована в буфер обмена!');
105
96
  },
106
97
  applyRestrictions(map) {
@@ -173,7 +173,7 @@ Ext.define('Coon.uielement.component.settings.UiAceEditor', {
173
173
  return '';
174
174
  },
175
175
 
176
- flush: function(rest) {
176
+ flush: function() {
177
177
  if (this.isValid()) {
178
178
  this.value = this.editor.getValue();
179
179
  this.publishState('value', this.value);
@@ -47,7 +47,12 @@ Ext.define('Coon.uielement.component.settings.UiAceEditorPanel', {
47
47
  },
48
48
 
49
49
  setValue(value) {
50
- this.links && this.links.editor.editor.setValue(value);
50
+ if (this.links && this.links.editor) {
51
+ const editor = this.links.editor;
52
+ if (Ext.isFunction(editor.setValue)) {
53
+ editor.setValue(value);
54
+ }
55
+ }
51
56
  },
52
57
 
53
58
  initComponent() {
@@ -8,4 +8,23 @@
8
8
  .x-docked.x-panel-header-collapsed {
9
9
  padding: 8px 4px!important;
10
10
  }
11
+
12
+ .deletedRecord {
13
+ color: darkred;
14
+ text-decoration: line-through;
15
+ }
16
+ .readOnlyRecord {
17
+ .x-grid-td {
18
+ background-color: #f5f5f5;
19
+ color: #555;
20
+ }
21
+ }
22
+
23
+ .readOnlyDeletedRecord {
24
+ .x-grid-td {
25
+ color: darkred;
26
+ text-decoration: line-through;
27
+ background-color: #f5f5f5;
28
+ }
29
+ }
11
30
  }
@@ -145,7 +145,7 @@ Ext.define('Coon.uielement.plugin.ExecuteCommandPlugin', {
145
145
  fn();
146
146
  }
147
147
  } else {
148
- console.warn('Не определена команда');
148
+ Coon.log.warn('Не определена команда');
149
149
  reject(new Error('Не определена команда'));
150
150
  }
151
151
  });
@@ -161,11 +161,13 @@ Ext.define('Coon.uielement.plugin.ExecuteCommandPlugin', {
161
161
  switch (this.getMappingMode()) {
162
162
  case 'map':
163
163
  for (const name in this.dataMapping) {
164
- vm.set(this.dataMapping[name], data[name]);
164
+ vm.set(this.dataMapping[name], Coon.util.getByPath(data, name));
165
165
  }
166
166
  break;
167
167
  case 'data':
168
- vm.setData(data);
168
+ if (Ext.isObject(data)) {
169
+ vm.setData(data);
170
+ }
169
171
  case 'object':
170
172
  default:
171
173
  let propertyPath = this.getPropertyPath();
@@ -0,0 +1,215 @@
1
+ Ext.define('Coon.uielement.plugin.configPanel.executeCommand.DataMappingPanel', {
2
+ extend: 'Ext.grid.Panel',
3
+ xtype: 'DataMappingPanel',
4
+
5
+ viewModel: {
6
+ data: {
7
+ selected: 0,
8
+ },
9
+ stores: {
10
+ mappingGridStore: {
11
+ model: Ext.create('Ext.data.Model', {
12
+ idProperty: 'viewModelPath',
13
+ fields: [
14
+ {name: 'resultPath', type: 'string'},
15
+ {name: 'viewModelPath', type: 'string'}
16
+ ],
17
+ }),
18
+ },
19
+ },
20
+ },
21
+
22
+ bind: {
23
+ store: '{mappingGridStore}',
24
+ },
25
+
26
+ viewConfig: {
27
+ getRowClass: function(rec) {
28
+ return rec.get('isDeleted') ? 'deletedRecord' : '';
29
+ },
30
+ },
31
+
32
+ tbar: [
33
+ {
34
+ text: 'Добавить',
35
+ ui: 'orange-button',
36
+ handler: 'onAddRow',
37
+ },
38
+ {
39
+ text: 'Удалить',
40
+ reference: 'deleteButton',
41
+ ui: 'blue-button',
42
+ bind: {
43
+ disabled: '{!selected}',
44
+ },
45
+ handler: 'onRemove',
46
+ },
47
+ {
48
+ text: '{}',
49
+ tooltip: 'Открыть в редакторе',
50
+ ui: 'blue-text-button-border',
51
+ handler: 'onOpenInEditor',
52
+ }
53
+ ],
54
+ columns: {
55
+ defaults: {
56
+ flex: 1,
57
+ editor: {
58
+ field: {
59
+ xtype: 'textfield', allowBlank: false,
60
+ },
61
+ },
62
+ },
63
+ items: [
64
+ {
65
+ text: 'Путь в результате команды', dataIndex: 'resultPath',
66
+ },
67
+ {
68
+ text: 'Путь во viewModel', dataIndex: 'viewModelPath',
69
+ }
70
+ ],
71
+ },
72
+ plugins: [
73
+ {
74
+ ptype: 'cellediting',
75
+ clicksToEdit: 2,
76
+ }
77
+ ],
78
+ listeners: {
79
+ selectionchange: 'onSelectionChanged',
80
+ },
81
+
82
+ initComponent() {
83
+ this.callParent();
84
+ this.doInit = Ext.bind(this.getController().doInit, this.getController());
85
+ this.getMapping = Ext.bind(this.getController().getMapping, this.getController());
86
+ },
87
+
88
+ controller: {
89
+ doInit: function(v) {
90
+ if (v) {
91
+ const store = this.getViewModel().getStore('mappingGridStore');
92
+ store.loadData(this.dataForStore(v));
93
+ }
94
+ },
95
+
96
+ /**
97
+ * Возвращает значение маппинга
98
+ * @returns {string}
99
+ */
100
+ getMapping: function() {
101
+ const grid = this.getView();
102
+
103
+ const editor = grid.findPlugin('cellediting');
104
+ editor.completeEdit();
105
+
106
+ return this.dataFromStore();
107
+ },
108
+
109
+ /**
110
+ * Сериализация объекта
111
+ * @param {Object} data
112
+ * @returns {string}
113
+ */
114
+ serializeData(data) {
115
+ return JSON5.stringify(data, {
116
+ space: 4,
117
+ quote: '\'',
118
+ });
119
+ },
120
+
121
+ /**
122
+ * Возвращает сериализованные данные стора.
123
+ * @returns {string}
124
+ */
125
+ dataFromStore: function() {
126
+ const store = this.getViewModel().getStore('mappingGridStore');
127
+ const data = store.getRange().reduce((acc, cur) => {
128
+ acc[cur.get('resultPath')] = cur.get('viewModelPath');
129
+ return acc;
130
+ }, {});
131
+
132
+ return this.serializeData(data);
133
+ },
134
+
135
+ dataForStore: function(data) {
136
+ const records = [];
137
+ let parsed = {};
138
+ try {
139
+ parsed = JSON5.parse(data);
140
+ } catch (e) {
141
+ Coon.log.error(e);
142
+ }
143
+
144
+ for (const [resultPath, viewModelPath] of Object.entries(parsed)) {
145
+ records.push({resultPath, viewModelPath});
146
+ }
147
+
148
+ return records;
149
+ },
150
+
151
+ onAddRow: function() {
152
+ this.getViewModel().getStore('mappingGridStore').insert(0, {});
153
+ const grid = this.getView();
154
+ const editor = grid.findPlugin('cellediting');
155
+ editor.startEditByPosition({row: 0, column: 0});
156
+ },
157
+
158
+ onRemove: function() {
159
+ const grid = this.getView();
160
+ if (grid.getSelectionModel().getSelection()[0]) {
161
+ grid.getStore().remove(grid.getSelectionModel().getSelection()[0]);
162
+ }
163
+ },
164
+
165
+ onSelectionChanged: function(grid, selected) {
166
+ this.getViewModel().set('selected', selected.length);
167
+ },
168
+
169
+ onOpenInEditor: function() {
170
+ const editor = Ext.create('widget.ReportPropertiesAceEditor', {
171
+ propertyRecords: this.getDataForAceEditor(),
172
+ });
173
+ editor.on('changesComplete', this.loadChangesFromEditor, this);
174
+ },
175
+
176
+ getDataForAceEditor: function() {
177
+ return this.getViewModel().getStore('mappingGridStore').getRange()
178
+ .filter((record) => !record.get('isDeleted'))
179
+ .map((record) => {
180
+ return {
181
+ key: record.get('resultPath'), value: record.get('viewModelPath'),
182
+ };
183
+ });
184
+ },
185
+
186
+ /**
187
+ * Загрузка изменений, внесенных в редакторе кода, в store.
188
+ * @param {Object} data
189
+ */
190
+ loadChangesFromEditor: function(data) {
191
+ const store = this.getViewModel().getStore('mappingGridStore');
192
+ const keys = new Set();
193
+ Object.entries(data || {}).forEach(function([key, value]) {
194
+ keys.add(key);
195
+ value = typeof value === 'string' ? value : JSON5.stringify(value);
196
+ const exist = store.findRecord('resultPath', key);
197
+ if (exist) {
198
+ exist.set({viewModelPath: value, isDeleted: false});
199
+ } else {
200
+ store.add({resultPath: key, viewModelPath: value, isNew: true});
201
+ }
202
+ }, this);
203
+ store.getRange()
204
+ .filter((el) => !keys.has(el.get('resultPath')))
205
+ .forEach((record) => this.deleteAction(record));
206
+ },
207
+
208
+ deleteAction: function(record) {
209
+ const store = this.getViewModel().getStore('mappingGridStore');
210
+ record.get('isNew') ? store.remove(record) :
211
+ record.set('isDeleted', !record.get('isDeleted'));
212
+ this.lookup('deleteButton').setText(record.get('isDeleted') ? 'Восстановить' : 'Удалить');
213
+ },
214
+ },
215
+ });