ru.coon 2.7.49 → 2.7.51

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 CHANGED
@@ -1,3 +1,23 @@
1
+ # Version 2.7.51, [link](http://gitlab-dbr.sigma-it.local/dbr/ru.coon/-/commit/f2e71615ea5c7b78a79c11ea26b2b15e11127867)
2
+ * ## Fixes
3
+ * <span style='color:red'> [plugin: CopyRowsFromGrid] - поддержка colspan/rowspan в заголовке таблицы при выгрузке в xls/xlsx. Closes HT-9675.</span> ([d1b173], [link](http://gitlab-dbr.sigma-it.local/dbr/ru.coon/-/commit/d1b173d87a987618448b111c546786ab65aec59d))
4
+ * <span style='color:red'> BFL-14768 fix ? when empty url</span> ([99562a], [link](http://gitlab-dbr.sigma-it.local/dbr/ru.coon/-/commit/99562abc55ebc833c86bf4ddeee38fcbf6f9f1ba))
5
+
6
+ * update: CHANGELOG.md ([dea3b2], [link](http://gitlab-dbr.sigma-it.local/dbr/ru.coon/-/commit/dea3b278f2bdc595be261cb07709fda36dc1c574))
7
+
8
+ # Version 2.7.50, [link](http://gitlab-dbr.sigma-it.local/dbr/ru.coon/-/commit/54c521efd1c8eac4614d89e87afb4168a19f6bff)
9
+ * ## Features
10
+ * <span style='color:green'>feat: TR-69252: fix itemId param in opened view, make doInit in panel if it has</span> ([1b2a44], [link](http://gitlab-dbr.sigma-it.local/dbr/ru.coon/-/commit/1b2a4406cb49489303e707705b958ddb70689aa2))
11
+ * <span style='color:green'>feat: TR-69252: fix itemId param in opened view, make doInit in panel if it has</span> ([b35243], [link](http://gitlab-dbr.sigma-it.local/dbr/ru.coon/-/commit/b3524303e203486f1c393f2174967c652d2f8c33))
12
+
13
+ * ## Fixes
14
+ * <span style='color:red'>Revert "feat: TR-69252: fix itemId param in opened view, make doInit in panel if it has"
15
+
16
+ This reverts commit b3524303e203486f1c393f2174967c652d2f8c33.</span> ([0bfe61], [link](http://gitlab-dbr.sigma-it.local/dbr/ru.coon/-/commit/0bfe6125e7624a46a2a24190b889837255b72d61))
17
+
18
+ * HT-8767 fix: Исправление ошибок в GridEditorsPlugin ([1c432b], [link](http://gitlab-dbr.sigma-it.local/dbr/ru.coon/-/commit/1c432b64b66c1dd8e21c2e337164f35a4b174e96))
19
+ * update: CHANGELOG.md ([2f020b], [link](http://gitlab-dbr.sigma-it.local/dbr/ru.coon/-/commit/2f020b8a2b6d2e2150329164ac7cef4d686de162))
20
+
1
21
  # Version 2.7.49, [link](http://gitlab-dbr.sigma-it.local/dbr/ru.coon/-/commit/f1191865e9e52331596a93e7bcf3ba36c85940f6)
2
22
  * ## Fixes
3
23
  * <span style='color:red'> HT-9084 ReportColumnStatePlugin column width</span> ([b10a75], [link](http://gitlab-dbr.sigma-it.local/dbr/ru.coon/-/commit/b10a75f78f92262543be268863961fda1113d9d5))
@@ -26,6 +46,7 @@
26
46
  * <span style='color:red'> Added required deps. Related to TR-68743, TR-63848.</span> ([27be06], [link](http://gitlab-dbr.sigma-it.local/dbr/ru.coon/-/commit/27be06f608741d363f0c7e8521e94aefb2e9ba81))
27
47
 
28
48
  * HT-9325 Контрагент - добавление подсказки для полей, имеющих определенное количество символов ([3b8085], [link](http://gitlab-dbr.sigma-it.local/dbr/ru.coon/-/commit/3b8085665232b2b937129dde2173bbbc3734ce36))
49
+ * HT-9063 :fix Исправление GridFiltersPlugin в части фильтрации по списку ([5807d6], [link](http://gitlab-dbr.sigma-it.local/dbr/ru.coon/-/commit/5807d684e9d344dbf55fe162e133779f5912aced))
29
50
  * HT-9325 Контрагент - добавление подсказки для полей, имеющих определенное количество символов ([2491d0], [link](http://gitlab-dbr.sigma-it.local/dbr/ru.coon/-/commit/2491d05dca04c86a97b5d9da3c1720fd5fe55d78))
30
51
  * update: CHANGELOG.md ([882183], [link](http://gitlab-dbr.sigma-it.local/dbr/ru.coon/-/commit/882183d4ad048bfc623600f3235a14081a2c6629))
31
52
 
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "name": "ru.coon"
5
5
  },
6
6
  "description": "",
7
- "version": "2.7.49",
7
+ "version": "2.7.51",
8
8
  "repository": {
9
9
  "type": "git",
10
10
  "url": "git+http://gitlab-dbr.sigma-it.local/dbr/ru.coon"
@@ -54,7 +54,6 @@ Ext.define('Coon.app.component.CenterViewController', {
54
54
  return cached;
55
55
  }
56
56
  }
57
-
58
57
  const paramsObject = this.paramsToObject(params);
59
58
  const filterDefaults =
60
59
  (paramsObject && Object.assign(paramsObject, {doFilter: true})) || {};
@@ -94,7 +93,7 @@ Ext.define('Coon.app.component.CenterViewController', {
94
93
  );
95
94
  }
96
95
  config = Object.assign(
97
- {xtype: config.xtype},
96
+ {xtype: config.xtype, itemId: id},
98
97
  config.propertyData
99
98
  );
100
99
  if (config.xtype === 'ReportPanel') {
@@ -107,8 +106,7 @@ Ext.define('Coon.app.component.CenterViewController', {
107
106
  ),
108
107
  },
109
108
  });
110
- }
111
- if (config.xtype === 'UiCustomPanel') {
109
+ } else if (config.xtype === 'UiCustomPanel') {
112
110
  Object.assign(config, {
113
111
  listeners: {
114
112
  'router:activate': this.onActivateComponent.bind(
@@ -119,6 +117,13 @@ Ext.define('Coon.app.component.CenterViewController', {
119
117
  Coon.Function.executeComponentDoInit(panel, paramsObject),
120
118
  },
121
119
  });
120
+ } else {
121
+ Object.assign(config, {
122
+ listeners: {
123
+ 'afterrender': (panel) =>
124
+ Coon.Function.executeComponentDoInit(panel, paramsObject),
125
+ },
126
+ });
122
127
  }
123
128
  }
124
129
  } catch (e) {
@@ -4,11 +4,6 @@ Ext.define('Coon.report.plugin.configPanel.CopyRowsFromGridConfigPanel', {
4
4
  uses: [],
5
5
  requires: [],
6
6
  alternateClassName: 'Sigma.common.grid.plugin.CopyRowsFromGridConfigPanel',
7
- listeners: {
8
- 'boxready': function() {
9
- this.onChangeFormat(null, 'xls');
10
- },
11
- },
12
7
  description: 'Экспорт в Excel.<br>' +
13
8
  'Возможно указать верхний и нижний колонтитулы для отчета в формате HTML.<br>' +
14
9
  'Также возможно подставлять данные из отчета и другие параметры.<br>' +
@@ -37,7 +32,23 @@ Ext.define('Coon.report.plugin.configPanel.CopyRowsFromGridConfigPanel', {
37
32
  ],
38
33
  },
39
34
  },
40
-
35
+ viewModel: {
36
+ data: {
37
+ format: 'xls',
38
+ activeEditor: 'xls',
39
+ askFormat: false,
40
+ },
41
+ },
42
+ controller: {
43
+ bindings: {
44
+ onChangeFormat: '{format}',
45
+ },
46
+ onChangeFormat(format) {
47
+ if (!this.getViewModel().get('askFormat')) {
48
+ this.getViewModel().set('activeEditor', format);
49
+ }
50
+ },
51
+ },
41
52
  createItems: function() {
42
53
  return [
43
54
  {
@@ -104,12 +115,6 @@ Ext.define('Coon.report.plugin.configPanel.CopyRowsFromGridConfigPanel', {
104
115
  });
105
116
  }
106
117
  },
107
- onChangeFormat: function(cmp, newValue) {
108
- const fields = Ext.ComponentQuery.query('[xtype="htmleditor"]', this);
109
- const fieldsXlsx = Ext.ComponentQuery.query('[xtype="EditorJsField"]', this);
110
- fieldsXlsx.forEach((field) => field.setHidden(newValue === 'xls'));
111
- fields.forEach((field) => field.setHidden(newValue === 'xlsx'));
112
- },
113
118
  createFormatField: function() {
114
119
  return {
115
120
  xtype: 'fieldset',
@@ -133,12 +138,17 @@ Ext.define('Coon.report.plugin.configPanel.CopyRowsFromGridConfigPanel', {
133
138
  allowBlank: false,
134
139
  width: 430,
135
140
  value: 'xls',
141
+ bind: {
142
+ value: '{format}',
143
+ },
136
144
  },
137
145
  {
138
146
  xtype: 'checkbox',
139
147
  boxLabel: 'Спрашивать формат перед выгрузкой',
140
148
  name: 'showFormatSelectDialog',
141
- value: false,
149
+ bind: {
150
+ value: '{askFormat}',
151
+ },
142
152
  }
143
153
  ],
144
154
  };
@@ -272,21 +282,25 @@ Ext.define('Coon.report.plugin.configPanel.CopyRowsFromGridConfigPanel', {
272
282
  width: 1100,
273
283
  height: 200,
274
284
  plugins: [Ext.create('Coon.report.plugin.htmlEditor.ToolbarCombo', {element: element})],
285
+ bind: {
286
+ hidden: '{activeEditor !=="xls"}',
287
+ },
275
288
  };
276
289
  },
277
290
  createEditorFlag: function() {
278
291
  return {
279
292
  xtype: 'ConstantList',
280
- value: 'xls',
281
- data: [
282
- ['xls', 'xls'],
283
- ['xlsx', 'xlsx']
284
- ],
285
293
  fieldLabel: 'Отобразить редактор',
286
294
  local: true,
287
- allowBlank: true,
288
- listeners: {
289
- change: this.onChangeFormat.bind(this),
295
+ data: [
296
+ ['xls', 'xls - старый формат'],
297
+ ['xlsx', 'xlsx - новый формат']
298
+ ],
299
+ name: 'activeEditor',
300
+ width: 430,
301
+ bind: {
302
+ value: '{activeEditor}',
303
+ disabled: '{!askFormat}',
290
304
  },
291
305
  };
292
306
  },
@@ -298,6 +312,9 @@ Ext.define('Coon.report.plugin.configPanel.CopyRowsFromGridConfigPanel', {
298
312
  name: name,
299
313
  width: '100%',
300
314
  height: 300,
315
+ bind: {
316
+ hidden: '{activeEditor !=="xlsx"}',
317
+ },
301
318
  };
302
319
  },
303
320
 
@@ -10,6 +10,7 @@ Ext.define('Coon.report.plugin.configPanel.GridEditorPluginConfig', {
10
10
 
11
11
  description: 'Плагин позволяет задать редактор для столбцов',
12
12
  tags: ['Редактирование'],
13
+ referenceHolder: true,
13
14
 
14
15
  config: {
15
16
  pluginTypeSettings: {
@@ -26,7 +27,6 @@ Ext.define('Coon.report.plugin.configPanel.GridEditorPluginConfig', {
26
27
  hideLabel: true,
27
28
  allowBlank: false,
28
29
  });
29
- const ns = Coon.report.model.CharacteristicBeanFields;
30
30
  this.grid = Ext.create('Ext.grid.Panel', {
31
31
  flex: 1,
32
32
  region: 'center',
@@ -56,7 +56,7 @@ Ext.define('Coon.report.plugin.configPanel.GridEditorPluginConfig', {
56
56
  columns: [
57
57
  {
58
58
  header: 'Поле',
59
- dataIndex: ns.$type,
59
+ dataIndex: 'type',
60
60
  xtype: 'hintColumn',
61
61
  editor: this.fieldEditor,
62
62
  flex: 1,
@@ -66,16 +66,9 @@ Ext.define('Coon.report.plugin.configPanel.GridEditorPluginConfig', {
66
66
  {ptype: 'cellediting', clicksToEdit: 2}
67
67
  ],
68
68
  listeners: {
69
- select: function(grid, record) {
70
- Coon.Function.clearAllFieldsOnForm(this.editForm);
71
- const recordConfig = this.editorConfig.find((el) => el.type === record.get(ns.$type));
72
- Coon.Function.fillFormFields(this.editForm, recordConfig);
73
- if (recordConfig && recordConfig[ns.$mask]) {
74
- this.editForm.down('UiAceEditor').setValue(recordConfig[ns.$mask]);
75
- }
76
- this.editForm.setDisabled(!record);
77
- }.bind(this),
78
- deselect: this.setEditorConfig.bind(this),
69
+ select: this.onSelectRecord.bind(this),
70
+ deselect: this.onDeselectRecord.bind(this),
71
+ beforedeselect: this.onBeforeDeselect.bind(this),
79
72
  },
80
73
  });
81
74
 
@@ -95,8 +88,9 @@ Ext.define('Coon.report.plugin.configPanel.GridEditorPluginConfig', {
95
88
  items: [
96
89
  {
97
90
  fieldLabel: 'Тип редактора',
98
- name: ns.$typeOfValue,
91
+ name: 'typeOfValue',
99
92
  xtype: 'lookupCombo',
93
+ reference: 'typeOfValue',
100
94
  lookupId: 'ADHOC_CHAR_TYPE_FLG',
101
95
  submitFormat: false,
102
96
  allowBlank: false,
@@ -104,7 +98,7 @@ Ext.define('Coon.report.plugin.configPanel.GridEditorPluginConfig', {
104
98
  },
105
99
  {
106
100
  boxLabel: 'Значение обязательно',
107
- name: ns.$required,
101
+ name: 'required',
108
102
  xtype: 'checkbox',
109
103
  },
110
104
  {
@@ -121,34 +115,99 @@ Ext.define('Coon.report.plugin.configPanel.GridEditorPluginConfig', {
121
115
  flex: 1,
122
116
  },
123
117
  items: [
124
- {
125
- xtype: 'checkbox',
126
- boxLabel: 'Редактировать если значение поля false/пусто',
127
- name: 'invertValue',
128
- },
129
118
  this.createFieldColumns({
130
119
  name: 'dependsOnFieldName',
131
120
  }),
132
121
  {
133
- boxLabel: 'Выделить редактируемые ячейки',
134
- name: 'highlightEditableCells',
135
- xtype: 'checkbox',
122
+ xtype: 'label',
123
+ text: 'Редактировать, если значение поля:',
124
+ },
125
+ {
126
+ xtype: 'segmentedbutton',
127
+ allowMultiple: false,
128
+ name: 'invertValue',
129
+ reference: 'invertValueButton',
130
+ items: [
131
+ {
132
+ text: 'Заполнено',
133
+ ui: 'FilterSegmentedButton',
134
+ tooltip: 'Заполнено любым значением',
135
+ pressed: true,
136
+ value: false,
137
+ },
138
+ {
139
+ text: 'Пустое',
140
+ tooltip: 'false или пустая строка',
141
+ ui: 'FilterSegmentedButton',
142
+ value: true,
143
+ }
144
+ ],
136
145
  }
137
146
  ],
138
147
  },
148
+ {
149
+ boxLabel: 'Выделить редактируемую ячейку',
150
+ name: 'highlightEditableCells',
151
+ xtype: 'checkbox',
152
+ listeners: {
153
+ render: function(field) {
154
+ Ext.create('Ext.tip.ToolTip', {
155
+ target: field.el,
156
+ html: 'При наведении указателя мыши на строку таблицы редактируемые ячейки подсвечиваются',
157
+ });
158
+ },
159
+ },
160
+ },
139
161
  {
140
162
  xtype: 'fieldset',
163
+ bind: {
164
+ disabled: '{!typeOfValue.selection}',
165
+ },
141
166
  title: 'Конфиг',
142
- height: 200,
143
- flex: 1,
144
- layout: 'fit',
167
+ height: 300,
168
+ layout: {
169
+ type: 'vbox',
170
+ align: 'stretch',
171
+ },
145
172
  scrollable: true,
146
173
  items: [
147
174
  {
148
175
  xtype: 'UiAceEditor',
149
176
  useLinter: true,
150
- name: ns.$mask,
177
+ name: 'mask',
151
178
  value: {},
179
+ height: 200,
180
+ },
181
+ {
182
+ xtype: 'button',
183
+ iconCls: 'x-fa fa-question',
184
+ maxWidth: 30,
185
+ handler: this.showDescription.bind(this),
186
+ description: `
187
+ В конфиге можно указать дополнительную конфигурацию свойств компонента,
188
+ который настроен в качестве редактора ячейки (настройка "тип редактора").
189
+ <br>Пример для типа редактора "дата и время":
190
+ <pre>
191
+ {
192
+ defaultTime: "09:00"
193
+ }
194
+ </pre>
195
+ Некоторые свойства конфига можно сделать зависимыми от других полей редактируемой строки. Для этого нужно
196
+ использовать настройку dependField.
197
+ Пример для типа редактора "дата и время":
198
+ <pre>
199
+ {
200
+ dependField: {
201
+ CNT_DATE: 'minValue'
202
+ }
203
+ }
204
+ </pre>
205
+ В этом примере для текущего редактора свойство minValue (минимальное значение даты) зависит от поля CNT_DATE
206
+ текущей строки. При такой конфигурации в редакторе ячейки в календаре даты, меньше значения поля CNT_DATE будут
207
+ недоступны.
208
+ <br>Свойства, для которых есть поддержка зависимости: minValue, maxValue.
209
+ <br>Свойства редактора, заданные в этом конфиге, имеют высший приоритет при создании редактора.
210
+ `,
152
211
  }
153
212
  ],
154
213
  }
@@ -184,13 +243,16 @@ Ext.define('Coon.report.plugin.configPanel.GridEditorPluginConfig', {
184
243
  },
185
244
 
186
245
  addHandler: function() {
187
- const ns = Coon.report.model.CharacteristicBeanFields;
188
- const data = {};
189
- data[ns.$entity] = 'ADV';
190
- const newRecord = Ext.create('Coon.report.model.CharacteristicBean', data);
191
- this.grid.getStore().add(newRecord);
192
- const editor = this.grid.findPlugin('cellediting');
193
- editor.startEditByPosition({row: this.grid.getStore().getCount() - 1, column: 0});
246
+ const editorConfig = {
247
+ type: undefined,
248
+ entity: 'ADV',
249
+ mask: '',
250
+ typeOfValue: '',
251
+ };
252
+ const newRecord = this.grid.getStore().add(editorConfig);
253
+ this.grid.getSelectionModel().select(newRecord);
254
+ const plugin = this.grid.findPlugin('cellediting');
255
+ plugin && plugin.startEditByPosition({row: this.grid.getStore().getCount() - 1, column: 0});
194
256
  },
195
257
 
196
258
  deleteHandler: function() {
@@ -208,24 +270,51 @@ Ext.define('Coon.report.plugin.configPanel.GridEditorPluginConfig', {
208
270
  this.grid.getStore().remove(record);
209
271
  },
210
272
 
211
- setEditorConfig: function() {
212
- const ns = Coon.report.model.CharacteristicBeanFields;
213
- const record = this.grid.getSelection()[0];
273
+ setEditorConfig: function(record) {
214
274
  if (!record || record.get('isDeleted')) {
215
275
  return;
216
276
  }
217
- record.set(ns.$mask, this.editForm.down('UiAceEditor').getValue());
218
- const foundIndex = this.editorConfig.findIndex((el) => el.type === record.get(ns.$type));
277
+ record.set('mask', this.editForm.down('UiAceEditor').getValue());
278
+ const foundIndex = this.editorConfig.findIndex((el) => el.type === record.get('type'));
219
279
  const deleteCount = foundIndex === -1 ? 0 : 1;
220
280
  const position = foundIndex === -1 ? this.editorConfig.length : foundIndex;
221
281
  this.editorConfig.splice(position, deleteCount, Object.assign(
222
282
  record.getData(),
223
- Coon.Function.getDataFromForm(this.editForm)));
283
+ Coon.Function.getDataFromForm(this.editForm),
284
+ {invertValue: this.lookup('invertValueButton').getValue()}
285
+ ));
224
286
  },
225
287
 
226
288
  getConfiguration: function() {
227
- this.setEditorConfig();
228
- const config = {editorConfig: this.editorConfig};
229
- return config;
289
+ const record = this.grid.getSelection()[0];
290
+ this.setEditorConfig(record);
291
+ return {editorConfig: this.editorConfig};
292
+ },
293
+
294
+ showDescription: function(cmp) {
295
+ Ext.Msg.alert('Описание свойства', cmp.description);
296
+ },
297
+
298
+ onSelectRecord: function(grid, record) {
299
+ Coon.Function.clearAllFieldsOnForm(this.editForm);
300
+ const recordConfig = this.editorConfig.find((el) => el.type === record.get('type'));
301
+ Coon.Function.fillFormFields(this.editForm, recordConfig);
302
+ const maskField = this.editForm.down('UiAceEditor');
303
+ if (recordConfig && recordConfig['mask']) {
304
+ maskField.setValue(recordConfig['mask']);
305
+ } else {
306
+ maskField.setValue('{}');
307
+ }
308
+ const invertValueButton = this.lookup('invertValueButton');
309
+ Ext.isObject(recordConfig) && invertValueButton.setValue(recordConfig.invertValue);
310
+ this.editForm.setDisabled(!record);
311
+ },
312
+
313
+ onDeselectRecord: function(grid, record) {
314
+ this.setEditorConfig(record);
315
+ },
316
+
317
+ onBeforeDeselect: function() {
318
+ return this.lookup('typeOfValue').isValid();
230
319
  },
231
320
  });
@@ -245,16 +245,15 @@ Ext.define('Coon.report.plugin.grid.CopyRowsFromGrid', {
245
245
  },
246
246
  /**
247
247
  * Формируем заголовок
248
- * @returns {string}
248
+ * @returns {Object[] || []}
249
249
  */
250
250
  collectHeaderJson: function(columnCount, workbook) {
251
251
  const reportPanel = this.component.up('ReportPanel');
252
- let result = [];
252
+ const result = [];
253
253
  // Работа с отображением выгрузок
254
254
  if (this.addHeader === true) {
255
- const nameReport = reportPanel.title;
256
- result = {
257
- value: nameReport,
255
+ result.push({
256
+ value: reportPanel.title,
258
257
  mergeAcross: columnCount || 1,
259
258
  styleId: workbook.addCellStyle({
260
259
  font: {
@@ -262,7 +261,7 @@ Ext.define('Coon.report.plugin.grid.CopyRowsFromGrid', {
262
261
  size: 17,
263
262
  },
264
263
  }),
265
- };
264
+ });
266
265
  }
267
266
  return result;
268
267
  },
@@ -333,23 +332,28 @@ Ext.define('Coon.report.plugin.grid.CopyRowsFromGrid', {
333
332
  return result;
334
333
  },
335
334
  collectGridDataAsObject: function(selections, workbook) {
336
- let resultObj = [];
335
+ const dataRows = [];
336
+ let headerRows = [];
337
+ let footerRows = [];
337
338
  const dataForTemplate = this.getDataForTemplate();
338
339
  const grid = this.component;
339
340
  const columnModel = grid.getColumns();
340
341
  const columnCount = grid.getColumns().length;
341
342
  if (this.addHeader === true) {
342
- resultObj = resultObj.concat(this.collectHeaderJson(columnCount, workbook));
343
+ headerRows = this.collectHeaderJson(columnCount, workbook);
343
344
  }
344
345
  if (this.addFilters === true) {
345
- resultObj = resultObj.concat(this.collectFiltersJson(columnCount, workbook));
346
+ headerRows = headerRows.concat(
347
+ this.collectFiltersJson(columnCount, workbook)
348
+ );
346
349
  }
347
350
  if (this.headerXlsx) {
348
351
  const headerXlsx = this.parseJsEditorObj(this.headerXlsx, workbook);
349
- const tmpl = new Ext.XTemplate(this.processingTemplate(JSON.stringify(headerXlsx))).apply(dataForTemplate);
350
- resultObj = resultObj.concat(JSON.parse(tmpl));
352
+ const tmpl = new Ext.XTemplate(
353
+ this.processingTemplate(JSON.stringify(headerXlsx))
354
+ ).apply(dataForTemplate);
355
+ headerRows = headerRows.concat(JSON.parse(tmpl));
351
356
  }
352
- const headers = [];
353
357
  const dataIndexToColumn = [];
354
358
  const visibleColumns = [];
355
359
  const columnIndexToDataIndex = [];
@@ -361,30 +365,32 @@ Ext.define('Coon.report.plugin.grid.CopyRowsFromGrid', {
361
365
  visibleColumns.push(c);
362
366
  columnIndexToDataIndex[c] = dataIndex;
363
367
  dataIndexToColumn[dataIndex] = columnModel[c];
364
- const value = columnModel[c].text || columnModel[c].header;
365
- headers.push({
366
- value: this.getRenderedValue(value, 'string'),
367
- styleId: workbook.addCellStyle({
368
- alignment: {
369
- wrapText: true,
370
- },
371
- }),
372
- });
373
368
  }
374
369
  }
375
370
  }
376
- resultObj.push(headers);
377
371
  selections.forEach(function(record, i) {
378
- resultObj.push(
379
- this.collectColumns(grid, record, visibleColumns, columnIndexToDataIndex, columnModel, dataIndexToColumn, i, true, workbook)
372
+ dataRows.push(
373
+ this.collectColumns(
374
+ grid,
375
+ record,
376
+ visibleColumns,
377
+ columnIndexToDataIndex,
378
+ columnModel,
379
+ dataIndexToColumn,
380
+ i,
381
+ true,
382
+ workbook
383
+ )
380
384
  );
381
385
  }, this);
382
386
  if (this.footerXlsx) {
383
387
  const footerXlsx = this.parseJsEditorObj(this.footerXlsx, workbook);
384
- const tmpl = new Ext.XTemplate(this.processingTemplate(JSON.stringify(footerXlsx))).apply(dataForTemplate);
385
- resultObj = resultObj.concat(JSON.parse(tmpl));
388
+ const tmpl = new Ext.XTemplate(
389
+ this.processingTemplate(JSON.stringify(footerXlsx))
390
+ ).apply(dataForTemplate);
391
+ footerRows = JSON.parse(tmpl);
386
392
  }
387
- return resultObj;
393
+ return {headerRows, dataRows, footerRows};
388
394
  },
389
395
  execute: function() {
390
396
  const reportPanel = this.component.up('ReportPanel');
@@ -415,7 +421,11 @@ Ext.define('Coon.report.plugin.grid.CopyRowsFromGrid', {
415
421
  });
416
422
  } else {
417
423
  filename += '.xls';
418
- const blob = new Blob(this.collectGridDataAsArray(this.getSelected()), {
424
+ const exporter = Ext.create('Ext.exporter.text.Html', {fileName: filename});
425
+ const blob = new Blob(this.collectGridDataAsArray(
426
+ this.getSelected(),
427
+ this.getTableHeaderRows(exporter, 'xls')
428
+ ), {
419
429
  type: 'text/xls;charset=UTF-8',
420
430
  });
421
431
  Coon.util.downloadFileFromBlob(blob, filename);
@@ -484,7 +494,10 @@ Ext.define('Coon.report.plugin.grid.CopyRowsFromGrid', {
484
494
  exporter.worksheet = exporter.excel.addWorksheet({
485
495
  name: 'Лист 1',
486
496
  });
487
- exporter.jsonData = this.collectGridDataAsObject(this.getSelected(), exporter.excel);
497
+ const {headerRows, dataRows, footerRows} =
498
+ this.collectGridDataAsObject(this.getSelected(), exporter.excel);
499
+ const tableHeaderRows = this.getTableHeaderRows(exporter);
500
+ exporter.jsonData = [...headerRows, ...tableHeaderRows, ...dataRows, ...footerRows];
488
501
  exporter.getContent = this.getContent.bind(exporter);
489
502
  return exporter;
490
503
  },
@@ -504,7 +517,48 @@ Ext.define('Coon.report.plugin.grid.CopyRowsFromGrid', {
504
517
 
505
518
  return me.excel.render();
506
519
  },
507
-
520
+ getTableHeaderRows(exporter, type = 'xlsx') {
521
+ let exporterPlugin = this.component.plugins.find(
522
+ (p) => p.ptype === 'gridexporter'
523
+ );
524
+ if (!exporterPlugin) {
525
+ exporterPlugin = Ext.create('Ext.grid.plugin.Exporter');
526
+ exporterPlugin.init(this.component);
527
+ }
528
+ exporter.setData(exporterPlugin.prepareData({}));
529
+ if (type === 'xls') {
530
+ const config = exporter.getConfig();
531
+ exporter.doc = new Ext.exporter.file.html.Doc({
532
+ title: config.title,
533
+ author: config.author,
534
+ tpl: config.tpl,
535
+ styles: [config.defaultStyle, config.titleStyle, config.groupHeaderStyle,
536
+ config.groupFooterStyle, config.tableHeaderStyle, config.tableFooterStyle],
537
+ });
538
+ }
539
+ const header = exporter.buildHeader();
540
+ return type === 'xls' ? header : header.map((row) => {
541
+ row.cells.forEach((cell) => {
542
+ Object.assign(cell, {
543
+ styleId: exporter.excel.addCellStyle(
544
+ {
545
+ alignment: {
546
+ wrapText: true,
547
+ horizontal: 'Center',
548
+ vertical: 'Automatic',
549
+ },
550
+ font: {
551
+ fontName: 'Arial',
552
+ family: 'Swiss',
553
+ bold: true,
554
+ },
555
+ }
556
+ ),
557
+ });
558
+ });
559
+ return row.cells;
560
+ });
561
+ },
508
562
  getTitle: function() {
509
563
  return this.addHeader === true ? this.component.up('ReportPanel').title : '';
510
564
  },
@@ -808,9 +862,10 @@ Ext.define('Coon.report.plugin.grid.CopyRowsFromGrid', {
808
862
  /**
809
863
  * Формируем данные для экспорта в файл в виде массива строк, чтобы преодолеть максимальный размер строки, допустимый в браузере.
810
864
  * @param selections
865
+ * @param tableHeaderRows
811
866
  * @returns {*[]}
812
867
  */
813
- collectGridDataAsArray: function(selections) {
868
+ collectGridDataAsArray: function(selections, tableHeaderRows = []) {
814
869
  const result = [];
815
870
  const grid = this.component;
816
871
  const columnCount = grid.getColumns().length;
@@ -838,10 +893,7 @@ Ext.define('Coon.report.plugin.grid.CopyRowsFromGrid', {
838
893
  if (!Ext.isEmpty(this.header)) {
839
894
  result.push(new Ext.XTemplate(this.processingTemplate(this.headerTemplate.html)).apply(dataForTemplates));
840
895
  }
841
- result.push('<table border="1">');
842
- result.push('<tr>');
843
896
  // собираем заголовки
844
- const headers = [];
845
897
  const dataIndexToColumn = [];
846
898
  const visibleColumns = [];
847
899
  const columnIndexToDataIndex = [];
@@ -854,13 +906,22 @@ Ext.define('Coon.report.plugin.grid.CopyRowsFromGrid', {
854
906
  visibleColumns.push(c);
855
907
  columnIndexToDataIndex[c] = dataIndex;
856
908
  dataIndexToColumn[dataIndex] = columnModel[c];
857
- const value = columnModel[c].text || columnModel[c].header;
858
- headers.push('<td style="' + this.getHeaderStyle(value, 'string') + '">' + this.getRenderedValue(value, 'string') + '</td>');
859
909
  }
860
910
  }
861
911
  }
862
- result.push(headers.join(''));
863
- result.push('</tr>');
912
+ result.push('<table border="1">');
913
+ /* eslint-disable max-len */
914
+ const headerTpl = new Ext.XTemplate(
915
+ '<tpl for="columns">',
916
+ ' <tr>\n',
917
+ '<tpl for=".">',
918
+ ' <th<tpl if="width"> width="{width}"</tpl><tpl if="mergeAcross"> colSpan="{mergeAcross}"</tpl><tpl if="mergeDown"> rowSpan="{mergeDown}"</tpl>>{text}</th>\n',
919
+ '</tpl>',
920
+ ' </tr>\n',
921
+ '</tpl>'
922
+ );
923
+ /* eslint-enable max-len */
924
+ result.push(headerTpl.apply({columns: tableHeaderRows}));
864
925
  let chunk = '';
865
926
  selections.forEach(function(record, i) {
866
927
  const row = [];
@@ -30,6 +30,28 @@ Ext.define('Coon.report.plugin.grid.GridEditorsPlugin', {
30
30
  init(grid) {
31
31
  this.grid = grid;
32
32
  this.grid.on('afterrender', this.setEditors, this);
33
+ this.grid.on('beforeedit', function(editor, context) {
34
+ const fieldName = context.field;
35
+ const record = context.record;
36
+ const foundConfig = this.getEditorConfig().find((config) => config.type===fieldName);
37
+ const dependField = Ext.isObject(foundConfig.mask) && foundConfig.mask.dependField;
38
+ if (Ext.isObject(dependField)) {
39
+ for (const [dependentFieldName, propName] of Object.entries(dependField)) {
40
+ const value = record.get(dependentFieldName);
41
+ const _editor = this.grid.getColumnModel().findColumnByDataIndex(fieldName).getEditor();
42
+ if (_editor && value) {
43
+ switch (propName) {
44
+ case 'minValue':
45
+ _editor.setMinValue(value);
46
+ break;
47
+ case 'maxValue':
48
+ _editor.setMaxValue(value);
49
+ break;
50
+ }
51
+ }
52
+ }
53
+ }
54
+ }, this);
33
55
  },
34
56
 
35
57
  setEditors() {
@@ -50,12 +72,19 @@ Ext.define('Coon.report.plugin.grid.GridEditorsPlugin', {
50
72
  const needComboRenderer = editor.isXType('BaseComboBox') && column.useComboRenderer !== false;
51
73
  const customStyle = column.renderer && column.renderer.customStyle;
52
74
  const columnFormat = column.format;
75
+ const isEditable = function(value) {
76
+ if (Ext.isString(value) && value.trim().toLowerCase()==='false') {
77
+ value = false;
78
+ }
79
+
80
+ return !!value;
81
+ };
53
82
  column.renderer = (value, metaData, record) => {
54
83
  let editable = true;
55
84
  if (editorConfig.dependsOnField && editorConfig.dependsOnFieldName) {
56
85
  const dependsOnFieldName = editorConfig.dependsOnFieldName;
57
86
  const invertValue = editorConfig.invertValue;
58
- editable = invertValue === !record.get(dependsOnFieldName);
87
+ editable = invertValue === !isEditable(record.get(dependsOnFieldName));
59
88
  if (editorConfig.highlightEditableCells) {
60
89
  metaData.tdCls = editable ? 'editable-cell' : 'hover-cell';
61
90
  }
@@ -132,10 +161,6 @@ Ext.define('Coon.report.plugin.grid.GridEditorsPlugin', {
132
161
  };
133
162
  break;
134
163
  }
135
- } else if (entity === 'DFV') {
136
-
137
- } else if (entity === 'FKV') {
138
-
139
164
  }
140
165
  if (!config) {
141
166
  throw new Ext.Error('Нет обработчика данного типа поля');
@@ -26,7 +26,7 @@ Ext.define('Coon.report.plugin.grid.GridFiltersPlugin', {
26
26
  for (let i = 0; i < this.columns.length; i++) {
27
27
  const column = this.columns[i];
28
28
  for (let j = 0; j < this.configFilters.length; j++) {
29
- if (column.dataIndex == this.configFilters[j].dataIndex) {
29
+ if (column.dataIndex === this.configFilters[j].dataIndex) {
30
30
  column.filter = this.getFilterType(this.configFilters[j].type);
31
31
  }
32
32
  }
@@ -87,17 +87,9 @@ Ext.define('Coon.report.plugin.grid.GridFiltersPlugin', {
87
87
  const parentTable = menu.up('tablepanel');
88
88
  const filter = this.getMenuFilter(parentTable.headerCt);
89
89
  if (!Ext.isEmpty(filter)) {
90
- if (filter.type == 'list') {
90
+ if (filter.type === 'list' && !filter.active) {
91
91
  this.changeFilter(filter.type, menu.ownerCmp.dataIndex);
92
92
  }
93
- if (filter.type === 'string') {
94
- filter.itemDefaults.emptyText = 'Введите текст...';
95
- }
96
- if (filter.type === 'date') {
97
- filter.fields.lt.text = 'До';
98
- filter.fields.gt.text = 'После';
99
- filter.fields.eq.text = 'На';
100
- }
101
93
  }
102
94
  this.callParent([menu]);
103
95
 
@@ -106,7 +98,7 @@ Ext.define('Coon.report.plugin.grid.GridFiltersPlugin', {
106
98
  filterType = (filterType === 'auto') ? 'string' : filterType;
107
99
 
108
100
  this.filterTypeMenu.items.each(function(item) {
109
- if (item.type == filterType) {
101
+ if (item.type === filterType) {
110
102
  item.setChecked(true, true);
111
103
  return false;
112
104
  }
@@ -118,12 +110,9 @@ Ext.define('Coon.report.plugin.grid.GridFiltersPlugin', {
118
110
  },
119
111
 
120
112
  getFilterType: function(filterType) {
121
- if (filterType == 'int' ||
122
- filterType == 'number' ||
123
- filterType == 'float') {
113
+ if (['int', 'number', 'float'].includes(filterType)) {
124
114
  filterType = 'numeric';
125
- } else if (filterType == 'list' ||
126
- filterType == 'DynamicList') {
115
+ } else if (['list', 'DynamicList'].includes(filterType)) {
127
116
  filterType = 'list';
128
117
  }
129
118
  return filterType;
@@ -137,7 +126,7 @@ Ext.define('Coon.report.plugin.grid.GridFiltersPlugin', {
137
126
  filter.setActive(false);
138
127
  }
139
128
 
140
- this.changeFilter(item.type, item.ownerCt.ownerCmp.ownerCt.ownerCmp.dataIndex);
129
+ this.changeFilter(item.type, item.up('gridcolumn').dataIndex);
141
130
  },
142
131
 
143
132
  changeFilter: function(type, dataIndex) {
@@ -147,7 +136,7 @@ Ext.define('Coon.report.plugin.grid.GridFiltersPlugin', {
147
136
  dataIndex: dataIndex,
148
137
  };
149
138
 
150
- if (newFilter.type == 'list') {
139
+ if (newFilter.type === 'list') {
151
140
  newFilter.gridStore = this.grid.getStore();
152
141
  }
153
142
  this.addFilter(newFilter, true);
@@ -28,7 +28,7 @@ Ext.define('Coon.report.plugin.grid.OpenURLButtonPlugin', {
28
28
  if (!Ext.isEmpty(this.dynamicContextField) && !Ext.isEmpty(context.record)) {
29
29
  url += context.record.get(this.dynamicContextField);
30
30
  }
31
- let paramsURL = this.url.indexOf('?') == -1 ? '?' : '';
31
+ let paramsURL = this.url && this.url.indexOf('?') == -1 ? '?' : '';
32
32
  for (const paramName in params) {
33
33
  if (params.hasOwnProperty(paramName)) {
34
34
  if (!Ext.isEmpty(params)) {
package/src/version.js CHANGED
@@ -1,4 +1,4 @@
1
1
  Ext.define('Coon.version', {
2
2
  singleton: true,
3
- number: '2.7.49',
3
+ number: '2.7.51',
4
4
  });