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.
- package/CHANGELOG.md +37 -0
- package/package.json +1 -1
- package/src/command/ASyncBaseCommand.js +4 -0
- package/src/common/component/editor/CharacteristicLoaderPlugin.js +12 -2
- package/src/common/field/combo/CommandComboBox.js +20 -0
- package/src/report/component/settings/ReportPropertiesGrid.js +22 -0
- package/src/report/component/settings/ReportPropertiesGridController.js +60 -1
- package/src/report/component/settings/context/ReportFormContextParametersGrid.js +73 -88
- package/src/report/plugin/configPanel/ExecuteCommandButtonPluginConfigPanel.js +92 -59
- package/src/report/plugin/grid/ExecuteCommandButtonPlugin.js +23 -8
- package/src/report/plugin/grid/ReportColumnStatePlugin.js +10 -7
- package/src/uielement/component/UiCustomController.js +6 -15
- package/src/uielement/component/settings/UiAceEditor.js +1 -1
- package/src/uielement/component/settings/UiAceEditorPanel.js +6 -1
- package/src/uielement/component/settings/plugin/UiCustomPanelPluginPanel.scss +19 -0
- package/src/uielement/plugin/ExecuteCommandPlugin.js +5 -3
- package/src/uielement/plugin/configPanel/executeCommand/DataMappingPanel.js +215 -0
- package/src/uielement/plugin/configPanel/executeCommand/ExecuteCommandPluginConfigPanelFormEditor.js +625 -0
- package/src/uielement/plugin/configPanel/executeCommand/ExecuteCommandPluginConfigPanelFormEditor.scss +22 -0
- package/src/util.js +4 -3
- package/src/version.js +1 -1
- 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:
|
|
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
|
-
|
|
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 +=
|
|
90
|
+
paramsTextContent += parameter + '=' + vm.get(parameter) + '&';
|
|
94
91
|
}
|
|
95
92
|
|
|
96
|
-
|
|
97
|
-
|
|
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) {
|
|
@@ -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
|
|
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
|
-
|
|
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
|
|
164
|
+
vm.set(this.dataMapping[name], Coon.util.getByPath(data, name));
|
|
165
165
|
}
|
|
166
166
|
break;
|
|
167
167
|
case 'data':
|
|
168
|
-
|
|
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
|
+
});
|