react-graph-grid 0.0.1 → 0.0.4

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/README.md CHANGED
@@ -1,3 +1,132 @@
1
1
  # react-graph-grid
2
2
 
3
- A React package containing a grid that can communicate with other grids through a connection graph
3
+ A React package containing a grid that can communicate with other grids through a connection graph
4
+
5
+ For all questions, please contact rmb@mail.ru
6
+
7
+ Installation
8
+
9
+ npm install react-grpah-grid
10
+
11
+
12
+ Example
13
+
14
+ import { GridFE } from '../../node_modules/react-graph-grid/src/GridFE';
15
+ import TestData from '../../node_modules/react-graph-grid/src/Tests/TestData';
16
+
17
+ ...
18
+
19
+ /*
20
+ * assuming the API returns something like this:
21
+ * const rows = [
22
+ * {
23
+ * Id: 1,
24
+ * Name: 'Mikle',
25
+ * SecondName: 'Razumtsev',
26
+ * Date: '26/01/1979'
27
+ * Comment: 'Me',
28
+ * Hometown: 'Voronezh',
29
+ * HometownId: 1,
30
+ * },
31
+ * {
32
+ * Id: 2,
33
+ * Name: 'Boris',
34
+ * SecondName: 'Razumtsev',
35
+ * Date: '14/06/1953'
36
+ * Comment: 'Father',
37
+ * Hometown: 'Grafskaya',
38
+ * HometownId: 2,
39
+ * },
40
+ * {
41
+ * Id: 3,
42
+ * Name: 'Ilia',
43
+ * SecondName: 'Razumtsev',
44
+ * Date: '16/09/1980'
45
+ * Comment: 'Brother',
46
+ * Hometown: 'Pskov',
47
+ * HometownId: 4,
48
+ * },
49
+ * ]
50
+ *
51
+ *
52
+ * e.params = [
53
+ * { key: 'pageSize', value: 10 },
54
+ * { key: 'pageNumber', value: 1 }
55
+ * ]
56
+ *
57
+ */
58
+
59
+ function loadRows(e) {
60
+ return new Promise(function (resolve, reject) {
61
+ const fetchParams = {
62
+ mode: 'cors',
63
+ method: 'post',
64
+ headers: {
65
+ 'Content-Type': 'application/json'
66
+ },
67
+ body: JSON.stringify(e.params)
68
+ };
69
+
70
+ fetch(`/awesome-api-url/`, fetchParams).then(
71
+ (response) => {
72
+ resolve(response.json());
73
+ }
74
+ )
75
+ .catch(error => {
76
+ reject(error);
77
+ });
78
+ });
79
+ };
80
+
81
+ function loadColumns() {
82
+ return [
83
+ { name: 'Id', sortable: true, filtrable: true },
84
+ { name: 'Name', sortable: true, filtrable: true },
85
+ { name: 'SecondName', sortable: true, filtrable: true },
86
+ { name: 'Date', sortable: true },
87
+ { name: 'Comment', sortable: true, filtrable: true },
88
+ { name: 'HometownId', visible: false },
89
+ {
90
+ name: 'Hometown',
91
+ sortable: true,
92
+ filtrable: true,
93
+ type: 'lookup',
94
+ keyField: 'HometownId',
95
+ refKeyField: 'Id',
96
+ refNameField: 'City',
97
+ getRows: (e) => {
98
+ return new Promise(function (resolve, reject) {
99
+
100
+ const rows = new TestData().getCity(e);
101
+
102
+ if (rows != null) {
103
+ resolve(rows);
104
+ } else {
105
+ reject(Error("Error getting rows"));
106
+ }
107
+ });
108
+ }
109
+ },
110
+ ]
111
+ };
112
+
113
+
114
+ <GridFE
115
+ getRows={loadRows}
116
+ getColumns={loadColumns}
117
+ allowEditGrid={true}
118
+ />
119
+
120
+
121
+ Some grid properties
122
+
123
+ uid - grid uid
124
+ parentGrids - parent grids uids
125
+ buttons - buttons array [{ id: 1, name: 'commit', title: 'Commit changes', label: 'Commit', img: Images.commit, click: (e) => grid.commitChanges(e), getDisabled: (e) => grid.commitChangesDisabled(e) }, ... ]
126
+ multi - rows multiselect through a pocket
127
+ renderCell - custom render grid cell
128
+ getDefaultLinkContent - returns an object containing a data using when child grid responds to the parent grid active record
129
+ pageSize - grid page size
130
+
131
+
132
+ For more examples see DebugApp.jsx
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "author": "Mikhail Razumtsev",
4
4
  "description": "A React package containing a grid that can communicate with other grids through a connection graph",
5
5
  "private": false,
6
- "version": "0.0.1",
6
+ "version": "0.0.4",
7
7
  "type": "module",
8
8
  "scripts": {
9
9
  "dev": "vite --port 4000",
package/src/FieldEdit.jsx CHANGED
@@ -43,8 +43,6 @@ export function FieldEdit(props) {
43
43
  fe.selectClass = props.selectClass || BaseComponent.theme.selectClass || '';
44
44
  fe.divContainerClass = props.divContainerClass || '';
45
45
 
46
- fe.datePickerDateFormat = props.datePickerDateFormat || 'dd.MM.yyyy';
47
-
48
46
  fe.w = props.w;
49
47
  fe.maxW = props.maxW;
50
48
  fe.h = fe.h || props.h || '1.6em';
@@ -120,33 +118,22 @@ export class FieldEditClass extends BaseComponent {
120
118
  }
121
119
  // -------------------------------------------------------------------------------------------------------------------------------------------------------------
122
120
  static _seq = 0;
123
- static _autoFocusColumn;
124
121
  // -------------------------------------------------------------------------------------------------------------------------------------------------------------
125
122
  render() {
126
123
  const fe = this;
127
124
 
128
- const isLookup = fe.column.type === 'lookup';
129
- const isReadonly = fe.column.readonly;
130
- const hasValue = fe.value != null && fe.value !== '';
131
- const noClear = fe.column.required || fe.column.readonly || !fe.multi && !hasValue;
132
-
133
- const needFocus = FieldEditClass._autoFocusColumn === fe.column;
134
- if (needFocus) {
135
- //FieldEditClass._autoFocusColumn = null;
136
- }
137
-
138
125
  return (
139
126
  <>
140
127
  <div
141
128
  key={`fieldEditDiv_${fe.id}_${fe.column.id}_`}
142
- className={fe.divContainerClass ? fe.divContainerClass : fe.large ? 'field-edit' : isLookup && !isReadonly ? 'grid-cell-lookup' : 'grid-cell-edit'}
129
+ className={fe.divContainerClass ? fe.divContainerClass : fe.large ? 'field-edit' : fe.column.type === 'lookup' && !fe.column.readonly ? 'grid-cell-lookup' : 'grid-cell-edit'}
143
130
  style={{
144
131
  border: 'none',
145
132
  height: !fe.inputClass ? fe.h : '',
146
133
  width: '100%',
147
134
  display: 'grid',
148
135
  gridColumn: fe.gridColumn || '',
149
- gridTemplateColumns: fe.large ? 'calc(100% - 4.6em) 2.2em 2.2em' : 'calc(100% - 2.8em) 1.4em 1.4em',
136
+ gridTemplateColumns: fe.getDivGridTemplateColumns(),
150
137
  maxWidth: fe.maxW ? fe.maxW : '',
151
138
  minHeight: fe.large ? '2.5em' : '',
152
139
  columnGap: fe.large ? '0.2em' : '',
@@ -155,86 +142,23 @@ export class FieldEditClass extends BaseComponent {
155
142
  }}
156
143
  >
157
144
  {
158
- isLookup && !isReadonly ?
159
- <>
160
- <input
161
- key={`fieldLookupTitle_${fe.id}_${fe.column.id}_`}
162
- style={{
163
- width: '100%',
164
- gridColumn: noClear ? !fe.comboboxValues ? 'span 2' : 'span 3' : 'span 1',
165
- overflowX: 'hidden',
166
- height: !fe.large ? '1.7em' : '2.2em',
167
- minHeight: !fe.inputClass ? fe.textareaH : fe.h,
168
- boxSizing: 'border-box',
169
- }}
170
- disabled={true}
171
- className={fe.large ? fe.inputClassLG : fe.inputClass || ''}
172
- value={!hasValue ? '' : fe.text != null && fe.text !== '' ? fe.text : fe.value}
173
- >
174
- </input>
175
- <button
176
- key={`fieldLookupButton_${fe.id}_${fe.column.id}_`}
177
- className={`${fe.large ? 'graph-filter-button' : 'grid-cell-button'} ${fe.clearButtonClass}`}
178
- style={{ width: !fe.large ? '1.6em' : '', height: !fe.large ? '1.6em' : '' }}
179
- onClick={(e) => {
180
- fe.openLookupField(e);
181
- }}
182
- disabled={fe.disabled}
183
- >
184
- {!fe.large ? '...' : Images.images.filterSelect()}
185
- </button>
186
- </>
187
- : //autoFocus={needFocus}
188
- <textarea
189
- key={`fieldTextarea_${fe.id}_${fe.column.id}_`}
190
- ref={fe.textareaRef}
191
- className={`${fe.large ? fe.inputClassLG : fe.inputClass}`}
192
- value={isLookup ? fe.text : fe.value || ''}
193
- style={{
194
- width: noClear ? 'calc(100% - 2px)' : '100%',
195
- minHeight: !fe.inputClass ? fe.textareaH : fe.minH,
196
- height: fe.h ? fe.h : !fe.large ? '1.7em' : '2.2em',
197
- padding: '0',
198
- boxSizing: 'border-box',
199
- gridColumn: noClear ? 'span 3' : 'span 2',
200
- resize: 'vertical',
201
- overflowX: 'hidden',
202
- }}
203
- onChange={(e) => {
204
- e.value = e.text = e.target.value;
205
- fe.value = fe.text = e.target.value;
206
- e.fe = fe;
207
- FieldEditClass._autoFocusColumn = fe.column;
208
-
209
- fe.selectionStart = e.target.selectionStart;
210
- fe._refocus = true;
211
-
212
- fe.onChange(e);
213
- fe.refreshState();
214
- }}
215
- disabled={fe.disabled || fe.column.readonly}
216
- >
217
- </textarea>
145
+ fe.renderInput()
218
146
  }
219
147
  {
220
- noClear || fe.column.readonly ? <></>
221
- :
148
+ fe.canClear() ?
222
149
  <button
223
150
  key={`fieldClearButton_${fe.id}_${fe.column.id}_`}
224
151
  className={`${fe.large ? 'graph-filter-clear' : 'grid-cell-button'} ${fe.clearButtonClass || ''}`}
225
152
  style={{ width: !fe.large ? '1.6em' : '', height: !fe.large ? '1.6em' : '' }}
226
153
  onClick={(e) => {
227
- e.value = e.text = '';
228
- fe.value = fe.text = '';
229
- e.fe = fe;
230
- fe.onChange(e);
231
- fe.refreshState();
154
+ fe.onClearClick(e);
232
155
  }}
233
156
  disabled={fe.disabled}
234
157
  >
235
158
  {!fe.large ? '×' : Images.images.filterClear()}
236
159
  </button>
237
-
160
+ :
161
+ <></>
238
162
  }
239
163
  </div >
240
164
  {
@@ -259,6 +183,79 @@ export class FieldEditClass extends BaseComponent {
259
183
  )
260
184
  }
261
185
  // -------------------------------------------------------------------------------------------------------------------------------------------------------------
186
+ renderInput() {
187
+ const fe = this;
188
+
189
+ const isLookup = fe.column.type === 'lookup';
190
+ const noClear = !fe.canClear();
191
+
192
+ return (
193
+ <>
194
+ {
195
+ isLookup && !fe.column.readonly ?
196
+ <>
197
+ <input
198
+ key={`fieldLookupTitle_${fe.id}_${fe.column.id}_`}
199
+ style={{
200
+ width: '100%',
201
+ gridColumn: noClear ? 'span 2' : 'span 1',
202
+ overflowX: 'hidden',
203
+ height: !fe.large ? '1.7em' : '2.2em',
204
+ minHeight: !fe.inputClass ? fe.textareaH : fe.h,
205
+ boxSizing: 'border-box',
206
+ }}
207
+ disabled={true}
208
+ className={fe.large ? fe.inputClassLG : fe.inputClass || ''}
209
+ value={fe.value == null || fe.value == '' ? '' : fe.text != null && fe.text !== '' ? fe.text : fe.value}
210
+ >
211
+ </input>
212
+ <button
213
+ key={`fieldLookupButton_${fe.id}_${fe.column.id}_`}
214
+ className={`${fe.large ? 'graph-filter-button' : 'grid-cell-button'} ${fe.clearButtonClass}`}
215
+ style={{ width: !fe.large ? '1.6em' : '', height: !fe.large ? '1.6em' : '' }}
216
+ onClick={(e) => {
217
+ fe.openLookupField(e);
218
+ }}
219
+ disabled={fe.disabled}
220
+ >
221
+ {!fe.large ? '...' : Images.images.filterSelect()}
222
+ </button>
223
+ </>
224
+ :
225
+ <textarea
226
+ key={`fieldTextarea_${fe.id}_${fe.column.id}_`}
227
+ ref={fe.textareaRef}
228
+ className={`${fe.large ? fe.inputClassLG : fe.inputClass}`}
229
+ value={isLookup ? fe.text : fe.value || ''}
230
+ style={{
231
+ width: noClear ? 'calc(100% - 2px)' : '100%',
232
+ minHeight: !fe.inputClass ? fe.textareaH : fe.minH,
233
+ height: fe.h ? fe.h : !fe.large ? '1.7em' : '2.2em',
234
+ padding: '0',
235
+ boxSizing: 'border-box',
236
+ gridColumn: noClear ? 'span 3' : 'span 2',
237
+ resize: 'vertical',
238
+ overflowX: 'hidden',
239
+ }}
240
+ onChange={(e) => {
241
+ e.value = e.text = e.target.value;
242
+ fe.value = fe.text = e.target.value;
243
+ e.fe = fe;
244
+
245
+ fe.selectionStart = e.target.selectionStart;
246
+ fe._refocus = true;
247
+
248
+ fe.onChange(e);
249
+ fe.refreshState();
250
+ }}
251
+ disabled={fe.disabled || fe.column.readonly}
252
+ >
253
+ </textarea>
254
+ }
255
+ </>
256
+ );
257
+ }
258
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
262
259
  renderLookupGrid(wnd) {
263
260
  const fe = this;
264
261
 
@@ -273,7 +270,7 @@ export class FieldEditClass extends BaseComponent {
273
270
  findGrid={() => { return fe.grid; }}
274
271
  onSelectValue={(e) => {
275
272
  fe._selectedOptions = e.values || [];
276
-
273
+
277
274
  fe.value = e.value;
278
275
  fe.text = e.text;
279
276
 
@@ -312,6 +309,26 @@ export class FieldEditClass extends BaseComponent {
312
309
  );
313
310
  }
314
311
  // -------------------------------------------------------------------------------------------------------------------------------------------------------------
312
+ getDivGridTemplateColumns() {
313
+ const fe = this;
314
+ return fe.large ? 'calc(100% - 4.6em) 2.2em 2.2em' : 'calc(100% - 2.8em) 1.4em 1.4em';
315
+ }
316
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
317
+ canClear() {
318
+ const fe = this;
319
+ return !fe.column.required && !fe.column.readonly && (fe.multi || fe.value != null && fe.value !== '');
320
+ }
321
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
322
+ onClearClick(e) {
323
+ const fe = this;
324
+
325
+ e.value = e.text = '';
326
+ fe.value = fe.text = '';
327
+ e.fe = fe;
328
+ fe.onChange(e);
329
+ fe.refreshState();
330
+ }
331
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
315
332
  closeLookupField() {
316
333
  const fe = this;
317
334
  fe.lookupIsShowing = false;
package/src/Grid.jsx CHANGED
@@ -90,7 +90,7 @@ export class GridClass extends BaseComponent {
90
90
  grid.renderCell = props.renderCell;
91
91
  }
92
92
 
93
- grid.dateFormat = props.dateFormat || 'dd.MM.yyyy';//'DD.MM.YYYY';
93
+ grid.dateFormat = props.dateFormat || 'dd.MM.yyyy';
94
94
  grid.dateTimeFormat = props.dateTimeFormat || 'dd.MM.yyyy HH:mm:ss';
95
95
 
96
96
  grid.rows = [];
@@ -289,6 +289,7 @@ export class GridClass extends BaseComponent {
289
289
  gridTemplateRows: '1.5em auto',
290
290
  gridAutoFlow: 'row',
291
291
  width: 'calc(100% + 8px)',
292
+ justifyContent: 'space-between',
292
293
  }}
293
294
  >
294
295
  {grid.renderHeaderCell(col, context)}
@@ -498,7 +499,8 @@ export class GridClass extends BaseComponent {
498
499
  for (let col of grid.columns) {
499
500
  col.id = id++;
500
501
  col.title = col.title || col.name;
501
- col.w = col.initW = col.w || 100;
502
+ col.w = col.w || 100;
503
+ col.initW = col.initW || 100;
502
504
  col.minW = col.minW || 50;
503
505
  col.grid = grid;
504
506
  grid.colDict[col.id] = grid.colDict[col.name] = grid.colDict[col.name.toLowerCase()] = col;
package/src/GridDB.jsx CHANGED
@@ -151,7 +151,12 @@ export class GridDBClass extends GridPKClass {
151
151
  {grid.renderPager()}
152
152
  {super.render()}
153
153
  {grid.renderPager(true)}
154
- <Dropdown init={(dd) => { grid.menuDropdown = dd; }} getItems={(e) => { return grid.getGridSettings(e); }} onItemClick={(e) => { grid.onSettingsItemClick(e.itemId); }}></Dropdown>
154
+ <Dropdown
155
+ init={(dd) => { grid.menuDropdown = dd; }}
156
+ closeWhenMiss={true}
157
+ getItems={(e) => { return grid.getGridSettings(e); }}
158
+ onItemClick={(e) => { grid.onSettingsItemClick(e.itemId); }}>
159
+ </Dropdown>
155
160
  </>
156
161
  )
157
162
  }
@@ -607,7 +612,7 @@ export class GridDBClass extends GridPKClass {
607
612
  }
608
613
  // -------------------------------------------------------------------------------------------------------------------------------------------------------------
609
614
  getHeaderGridTemplateColumns(col) {
610
- return col.sortInd == null ? 'auto 8px' : 'auto 22px';
615
+ return col.sortInd == null ? 'auto 12px' : 'auto 22px';
611
616
  }
612
617
  // -------------------------------------------------------------------------------------------------------------------------------------------------------------
613
618
  renderHeaderCell(col, context) {
@@ -774,12 +779,20 @@ export class GridDBClass extends GridPKClass {
774
779
  resetColumnsSort() {
775
780
  const grid = this;
776
781
  grid._sortString = '';
782
+ let needRefresh = false;
777
783
  for (let col of grid.columns) {
784
+ needRefresh = needRefresh || col.asc != false || col.desc != false;
785
+
778
786
  delete col.asc;
779
787
  delete col.desc;
780
788
  delete col.sortInd;
781
789
  }
782
- grid.refresh();
790
+ if (needRefresh) {
791
+ grid.refresh();
792
+ }
793
+ else {
794
+ grid.refreshState();
795
+ }
783
796
  }
784
797
  // -------------------------------------------------------------------------------------------------------------------------------------------------------------
785
798
  changeColumnSortOrder(column, e) {
package/src/GridFE.jsx CHANGED
@@ -77,7 +77,6 @@ export class GridFEClass extends GridFLClass {
77
77
  grid.onSelectValue = props.onSelectValue || (() => { });
78
78
 
79
79
  const shift = (grid.level + 1) * 20;
80
-
81
80
  grid.popupPos = { x: 100 + shift, y: 100 + shift, w: 800, h: 600 };
82
81
 
83
82
  grid.addToolbarButtons();
@@ -130,17 +129,6 @@ export class GridFEClass extends GridFLClass {
130
129
  return <></>;
131
130
  }
132
131
  // -------------------------------------------------------------------------------------------------------------------------------------------------------------
133
- onClosePopup() {
134
- const grid = this;
135
-
136
- super.onClosePopup();
137
-
138
- if (grid.isNewRecord) {
139
- grid.isNewRecord = false;
140
- grid.refresh();
141
- }
142
- }
143
- // -------------------------------------------------------------------------------------------------------------------------------------------------------------
144
132
  renderCell(grid, col, row, selected) {
145
133
  if (!grid.allowEditGrid && !col.allowVerticalResize || !selected || grid.isDisabled()) return super.renderCell(grid, col, row);
146
134
 
@@ -495,17 +483,6 @@ export class GridFEClass extends GridFLClass {
495
483
  return selected ? '1' : grid.stateind;
496
484
  }
497
485
  // -------------------------------------------------------------------------------------------------------------------------------------------------------------
498
- selectedText(delim) {
499
- const grid = this;
500
- let res = super.selectedText(delim);
501
-
502
- if (res != null && res !== '') return res;
503
-
504
- if (grid.status === NodeStatus.filter && grid.value != null && grid.value !== '' && grid._selectedText != null && grid._selectedText !== '') return grid._selectedText;
505
-
506
- return res;
507
- }
508
- // -------------------------------------------------------------------------------------------------------------------------------------------------------------
509
486
  isRowChanged(row) {
510
487
  const grid = this;
511
488
  if (!grid.changedRow) return false;
@@ -529,4 +506,78 @@ export class GridFEClass extends GridFLClass {
529
506
  });
530
507
  }
531
508
  // -------------------------------------------------------------------------------------------------------------------------------------------------------------
509
+ getGridSettingsList() {
510
+ const res = super.getGridSettingsList();
511
+
512
+ const grid = this;
513
+ if (!grid.exportDisabled) {
514
+ res.push({ id: 4, text: grid.translate('Export to CSV', 'grid-menu') });
515
+ }
516
+
517
+ return res;
518
+ }
519
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
520
+ onSettingsItemClick(itemId) {
521
+ super.onSettingsItemClick(itemId);
522
+ const grid = this;
523
+
524
+ switch (String(itemId)) {
525
+ case '4':
526
+ grid.exportToCSV();
527
+
528
+ grid.refreshState();
529
+ break;
530
+ default:
531
+ }
532
+ }
533
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
534
+ exportToCSV(filename, delimeter) {
535
+ const grid = this;
536
+
537
+ if (filename == null || filename == '') {
538
+ const date = new Date();
539
+ filename = `exportCSV_${date.getDate()}_${date.getMonth()}_${date.getFullYear()}_${date.getTime()}_`;
540
+ };
541
+
542
+ delimeter = delimeter || ';';
543
+
544
+ let titles = [];
545
+ for (let col of grid.columns) {
546
+ if (col.visible == false) continue;
547
+ titles.push(col.title || col.name);
548
+ }
549
+
550
+ // 1. Преобразование данных в CSV строку
551
+ const csvContent = "\uFEFF" + // Добавляем BOM для корректного отображения кириллицы в Excel
552
+ [
553
+ titles.join(delimeter), // Заголовки
554
+ ...grid.rows.map(item => {
555
+
556
+ let values = [];
557
+ for (let col of grid.columns) {
558
+ if (col.visible == false) continue;
559
+ values.push(item[col.name]);
560
+ }
561
+ return values.join(delimeter);
562
+
563
+ //return Object.values(item).join(delimeter);
564
+ }) // Строки данных
565
+ ].join("\n");
566
+
567
+ // 2. Создание Blob
568
+ const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
569
+
570
+ // 3. Создание ссылки и скачивание
571
+ const link = document.createElement("a");
572
+ if (link.download !== undefined) {
573
+ const url = URL.createObjectURL(blob);
574
+ link.setAttribute("href", url);
575
+ link.setAttribute("download", filename);
576
+ link.style.visibility = 'hidden';
577
+ document.body.appendChild(link);
578
+ link.click();
579
+ document.body.removeChild(link);
580
+ }
581
+ }
582
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
532
583
  }
package/src/GridFL.jsx CHANGED
@@ -79,6 +79,7 @@ export class GridFLClass extends GridDBClass {
79
79
  <Dropdown
80
80
  getItems={(e) => { return grid.getAutocomleteItems(e); }}
81
81
  onItemClick={(e) => { grid.onAutocomleteItemClick(e); }}
82
+ closeWhenMiss={true}
82
83
  init={(dd) => {
83
84
  if (grid._autocompleteDropdown) {
84
85
  dd.visible = grid._autocompleteDropdown.visible;
@@ -411,7 +412,7 @@ export class GridFLClass extends GridDBClass {
411
412
  }
412
413
  // -------------------------------------------------------------------------------------------------------------------------------------------------------------
413
414
  getHeaderGridTemplateColumns(col) {
414
- return col.sortInd == null /*&& (col.filter == null || col.filter === '')*/ ? 'auto 18px' : 'auto 22px';
415
+ return col.sortInd == null ? 'auto 12px' : 'auto 22px';
415
416
  }
416
417
  // -------------------------------------------------------------------------------------------------------------------------------------------------------------
417
418
  getGridSettingsList() {
package/src/Modal.jsx CHANGED
@@ -54,7 +54,8 @@ export class ModalClass extends BaseComponent {
54
54
 
55
55
  wnd.opt.closeWhenClick = props.closeWhenClick;
56
56
  wnd.opt.closeWhenEscape = props.closeWhenEscape;
57
- wnd.opt.closeWhenMiss = (props.closeWhenMiss || !props.closeWhenMouseLeave) && wnd.opt.isModal;
57
+ wnd.opt.closeWhenMiss = props.closeWhenMiss && wnd.opt.isModal;
58
+ //wnd.opt.closeWhenMiss = (props.closeWhenMiss || props.closeWhenMouseLeave == false) && wnd.opt.isModal;
58
59
  wnd.opt.closeWhenMouseLeave = props.closeWhenMouseLeave;
59
60
 
60
61
  wnd.opt.onMouseEnter = props.onMouseEnter;
@@ -306,12 +307,14 @@ export class ModalClass extends BaseComponent {
306
307
  // -------------------------------------------------------------------------------------------------------------------------------------------------------------
307
308
  close() {
308
309
  const wnd = this;
309
- wnd.visible = false;
310
310
 
311
311
  if (wnd.onClose) {
312
- wnd.onClose();
312
+ const ev = {};
313
+ wnd.onClose(ev);
314
+ if (ev.cancel) return;
313
315
  }
314
316
 
317
+ wnd.visible = false;
315
318
  wnd.refreshState();
316
319
  }
317
320
  // -------------------------------------------------------------------------------------------------------------------------------------------------------------
@@ -10,7 +10,7 @@ export default class TestData {
10
10
 
11
11
  const family = [
12
12
  { Id: 1, ParentId: [3, 4], Name: 'Mikle', SecondName: 'Razumtsev', Date: '26/01/1979', Comment: 'Good boy', Hometown: 'Voronezh', HometownId: 1 },
13
- { Id: 2, ParentId: [0], Name: 'Nataly', SecondName: 'Sche..', Date: '15/01/1999', Comment: 'Good girl', Hometown: 'Hanty-Mansiysk', HometownId: 12 },
13
+ { Id: 2, ParentId: [0], Name: 'Nataly', SecondName: 'Sche..', Date: '14/01/1999', Comment: 'Good girl', Hometown: 'Hanty-Mansiysk', HometownId: 12 },
14
14
  { Id: 3, ParentId: [11, 23], Name: 'Lyuda', SecondName: 'Razumtseva', Date: '03/07/1953', Comment: 'Mommy', Hometown: 'Novosibirsk', HometownId: 8 },
15
15
  { Id: 4, ParentId: [5, 22], Name: 'Borya', SecondName: 'Razumtsev', Date: '14/06/1953', Comment: 'Papa', Hometown: 'Grafskaya', HometownId: 2 },
16
16
  { Id: 5, ParentId: [0], Name: 'Nina', SecondName: 'Razumtseva', Date: '17/06/1917', Comment: 'Babushka', Hometown: 'Ustyuzhna', HometownId: 9 },
@@ -30,8 +30,8 @@ export default class TestData {
30
30
  { Id: 19, ParentId: [11, 23], Name: 'Nadya', SecondName: 'Shaula', Date: '11/11/196?', Comment: 'Tetya', Hometown: 'Novosibirsk', HometownId: 8 },
31
31
  { Id: 20, ParentId: [11, 23], Name: 'Vitia', SecondName: 'Dolginov', Date: '11/11/196?', Comment: 'Dadya', Hometown: 'Novosibirsk', HometownId: 8 },
32
32
  { Id: 21, ParentId: [11, 23], Name: 'Tanya', SecondName: 'Dolginova', Date: '07/01/1963', Comment: 'Tetya', Hometown: 'Elista', HometownId: 5 },
33
- { Id: 22, ParentId: [0], Name: 'Misha', SecondName: 'Razumtsev', Date: '??/??/19??', Comment: 'Ded', Hometown: 'Grafskaya', HometownId: 2 },
34
- { Id: 23, ParentId: [0], Name: 'Zambo', SecondName: 'Dolginov', Date: '??/??/19??', Comment: 'Ded 2', Hometown: 'Elista', HometownId: 5 },
33
+ { Id: 22, ParentId: [0], Name: 'Misha', SecondName: 'Razumtsev', Date: '05/11/1918', Comment: 'Ded', Hometown: 'Grafskaya', HometownId: 2 },
34
+ { Id: 23, ParentId: [0], Name: 'Zambo', SecondName: 'Dolginov', Date: '24/04/1926', Comment: 'Ded 2', Hometown: 'Elista', HometownId: 5 },
35
35
 
36
36
  { Id: 24, ParentId: [18, 34], Name: 'Alina', SecondName: 'Ushakova', Date: '??/??/????', Comment: 'Dv. Sister', Hometown: 'Elista', HometownId: 5 },
37
37
  { Id: 25, ParentId: [19, 33], Name: 'Igor', SecondName: 'Shaula', Date: '??/??/????', Comment: 'Dv. Brother', Hometown: 'Energodar', HometownId: 14 },
@@ -40,7 +40,7 @@ export default class TestData {
40
40
  { Id: 28, ParentId: [20, 35], Name: 'Venia', SecondName: 'Dolginov', Date: '??/??/????', Comment: 'Dv. Brother', Hometown: 'Elista', HometownId: 5 },
41
41
  { Id: 29, ParentId: [20, 36], Name: 'Oleg', SecondName: 'Dolginov', Date: '??/??/????', Comment: 'Dv. Brother', Hometown: 'Elista', HometownId: 5 },
42
42
 
43
- { Id: 30, ParentId: [0], Name: 'Yura', SecondName: 'Pelushskiy', Date: '??/??/????', Comment: 'Dv. Ded', Hometown: 'Ustyuzhna', HometownId: 9 },
43
+ { Id: 30, ParentId: [0], Name: 'Yura', SecondName: 'Pelushskiy', Date: '??/??/1921', Comment: 'Dv. Ded', Hometown: 'Ustyuzhna', HometownId: 9 },
44
44
  { Id: 31, ParentId: [0], Name: 'Sanal', SecondName: 'Batyrev', Date: '11/06/????', Comment: 'Muzh Sestry 3', Hometown: 'Elista', HometownId: 5 },
45
45
  { Id: 32, ParentId: [0], Name: 'Dima', SecondName: 'Markelov', Date: '??/??/????', Comment: 'Muzh Sestry 2', Hometown: 'Elista', HometownId: 5 },
46
46
  { Id: 33, ParentId: [0], Name: 'Slava', SecondName: 'Shaula', Date: '??/??/????', Comment: 'Muzh Teti', Hometown: 'Energodar', HometownId: 14 },