react-graph-grid 0.0.0 → 0.0.1

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/src/GridFE.jsx ADDED
@@ -0,0 +1,532 @@
1
+ /* eslint-disable no-mixed-operators */
2
+ import { useState, useEffect } from 'react';
3
+ import { GridFLClass } from './GridFL';
4
+ import { FieldEdit } from './FieldEdit';
5
+ import { Images } from './Themes/Images';
6
+ import { Modal } from './Modal';
7
+ // ==================================================================================================================================================================
8
+ export function GridFE(props) {
9
+ let grid = null;
10
+
11
+ const [gridState, setState] = useState({ grid: grid, ind: 0 });
12
+
13
+ grid = gridState.grid;
14
+ let needGetRows = false;
15
+ if (!grid || grid.uid !== props.uid && props.uid != null) {
16
+ grid = null;
17
+ if (props.findGrid) {
18
+ grid = props.findGrid(props);
19
+ }
20
+ grid = grid || new GridFEClass(props);
21
+ needGetRows = !props.noAutoRefresh && !grid.hasVisibleParentGrids();
22
+ }
23
+
24
+ if (props.init) {
25
+ props.init(grid);
26
+ }
27
+
28
+ grid.refreshState = function () {
29
+ setState({ grid: grid, ind: grid.stateind++ });
30
+ }
31
+
32
+ useEffect(() => {
33
+ grid.setupEvents();
34
+
35
+ if (needGetRows && (grid.rows.length <= 0 || grid.columns.length <= 0) || grid._forceRefresh) {
36
+
37
+ grid._forceRefresh = false;
38
+
39
+ grid._waitingRows = true;
40
+ grid.getRows({ filters: grid.collectFilters(), grid: grid }).then(
41
+ rows => {
42
+ grid.rows = rows;
43
+ grid.afterGetRows();
44
+ grid.refreshState();
45
+ }
46
+ ).finally(() => {
47
+ grid._waitingRows = false;
48
+ grid.refreshState();
49
+ });
50
+ }
51
+ else if (grid.columns.length <= 0 && grid.getColumns) {
52
+ grid.prepareColumns().then(() => grid.refreshState());;
53
+ }
54
+
55
+ return () => {
56
+ grid.clearEvents();
57
+ }
58
+ }, [grid, needGetRows])
59
+
60
+ return (grid.render());
61
+ }
62
+
63
+ // ==================================================================================================================================================================
64
+ export class GridFEClass extends GridFLClass {
65
+
66
+ constructor(props) {
67
+ super(props);
68
+
69
+ const grid = this;
70
+
71
+ grid.allowEditGrid = props.allowEditGrid;
72
+
73
+ //grid.changedRow = {};
74
+
75
+ grid.closeSelfWnd = grid.closeSelfWnd || (() => { });
76
+
77
+ grid.onSelectValue = props.onSelectValue || (() => { });
78
+
79
+ const shift = (grid.level + 1) * 20;
80
+
81
+ grid.popupPos = { x: 100 + shift, y: 100 + shift, w: 800, h: 600 };
82
+
83
+ grid.addToolbarButtons();
84
+ }
85
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
86
+ render() {
87
+ const grid = this;
88
+ return (
89
+ <>
90
+ {super.render()}
91
+ {grid.renderPopup()}
92
+ </>
93
+ )
94
+ }
95
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
96
+ isVisible() {
97
+ return this.visible;
98
+ }
99
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
100
+ renderPopup() {
101
+ const grid = this;
102
+ return (
103
+ grid.popupIsShowing ?
104
+ <Modal
105
+ title={grid.popupTitle}
106
+ level={grid.level + 1}
107
+ renderContent={(wnd) => { return grid.renderPopupContent(wnd) }}
108
+ dimensionsByContent={grid.popupDimensionsByContent}
109
+ pos={grid.popupPos}
110
+ closeWhenEscape={grid.popupCloseWhenEscape}
111
+ onClose={(e) => {
112
+ grid.onClosePopup(e);
113
+ grid.refreshState();
114
+ }}
115
+ >
116
+ </Modal>
117
+ :
118
+ <></>
119
+ );
120
+ }
121
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
122
+ onClosePopup() {
123
+ const grid = this;
124
+ grid.popupIsShowing = false;
125
+ grid.popupCloseWhenEscape = false;
126
+ grid.popupTitle = '';
127
+ }
128
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
129
+ renderPopupContent() {
130
+ return <></>;
131
+ }
132
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
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
+ renderCell(grid, col, row, selected) {
145
+ if (!grid.allowEditGrid && !col.allowVerticalResize || !selected || grid.isDisabled()) return super.renderCell(grid, col, row);
146
+
147
+ row = !grid.isEditing() || !grid.changedRow ? row : grid.changedRow;
148
+
149
+ return <FieldEdit
150
+ keyPref={grid.id + '_' + row[grid.keyField]}
151
+ column={col}
152
+ value={col.type === 'lookup' ? row[col.keyField] : row[col.name]}
153
+ text={row[col.name]}
154
+ findFieldEdit={() => { return col._fieldEditObj; }}
155
+ selectH={'1.4em'}
156
+ level={grid.level}
157
+ init={
158
+ (fe) => {
159
+ if (grid.isEditing() && !grid.changedRow) {
160
+ grid.changedRow = {};
161
+ Object.assign(grid.changedRow, grid.selectedRow());
162
+ }
163
+
164
+ fe.ownerGrid = grid;
165
+
166
+ const lrow = !grid.isEditing() ? grid.selectedRow() : grid.changedRow;
167
+
168
+ col._fieldEditObj = fe;
169
+ fe.value = col.type === 'lookup' ? lrow[col.keyField] : lrow[col.name];
170
+ fe.text = lrow[col.name];
171
+ }
172
+ }
173
+ onChange={(e) => {
174
+ if (!grid.changedRow) {
175
+ grid.changedRow = {};
176
+ Object.assign(grid.changedRow, grid.selectedRow());
177
+ }
178
+
179
+ if (col.type === 'lookup') {
180
+ grid.changedRow[col.keyField] = e.value;
181
+ grid.changedRow[col.name] = e.text;
182
+ if (!grid.isEditing()) {
183
+ grid.setEditing(true);
184
+ grid.refreshState();
185
+ }
186
+ e.fe.refreshState();
187
+ }
188
+ else {
189
+ grid.changedRow[col.name] = e.value;
190
+ if (!grid.isEditing()) {
191
+ grid.setEditing(true);
192
+ grid.refreshState();
193
+ }
194
+ else {
195
+ e.fe.refreshState();
196
+ }
197
+ }
198
+ }}
199
+ >
200
+ </FieldEdit>
201
+ }
202
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
203
+ addToolbarButtons() {
204
+ const grid = this;
205
+
206
+ //node.buttons.push({
207
+ // id: node.buttons.length,
208
+ // name: 'edit',
209
+ // title: node.translate('Start edit'),
210
+ // label: node.images.edit ? '' : node.translate('Start edit'),
211
+ // click: (e) => node.startEdit(e),
212
+ // img: node.images.edit
213
+ //});
214
+
215
+ grid.buttons.push({
216
+ id: grid.buttons.length,
217
+ name: 'commit',
218
+ title: grid.translate('Commit changes'),
219
+ label: grid.translate('Commit'),
220
+ img: Images.images.commit,
221
+ click: (e) => grid.commitChanges(e),
222
+ getDisabled: (e) => grid.commitChangesDisabled(e),
223
+ });
224
+
225
+ grid.buttons.push({
226
+ id: grid.buttons.length,
227
+ name: 'rollback',
228
+ title: grid.translate('Rollback changes'),
229
+ label: grid.translate('Rollback'),
230
+ img: Images.images.rollback,
231
+ click: (e) => grid.rollbackChanges(e),
232
+ getDisabled: (e) => grid.rollbackChangesDisabled(e),
233
+ });
234
+
235
+ grid.buttons.push({
236
+ id: grid.buttons.length,
237
+ name: 'add',
238
+ title: grid.translate('Add new record'),
239
+ label: grid.translate('Add'),
240
+ img: Images.images.addRecord,
241
+ click: (e) => grid.addRecord(e),
242
+ getDisabled: (e) => grid.addRecordDisabled(e),
243
+ });
244
+
245
+ grid.buttons.push({
246
+ id: grid.buttons.length,
247
+ name: 'copy',
248
+ title: grid.translate('Copy record'),
249
+ label: grid.translate('Copy'),
250
+ img: Images.images.copyRecord,
251
+ click: (e) => grid.copyRecord(e),
252
+ getDisabled: (e) => grid.copyRecordDisabled(e),
253
+ });
254
+
255
+ grid.buttons.push({
256
+ id: grid.buttons.length,
257
+ name: 'delete',
258
+ title: grid.translate('Delete record'),
259
+ label: grid.translate('Delete'),
260
+ img: Images.images.deleteRecord,
261
+ click: (e) => grid.deleteRecord(e),
262
+ getDisabled: (e) => grid.deleteRecordDisabled(e),
263
+ });
264
+
265
+ grid.buttons.push({
266
+ id: grid.buttons.length,
267
+ name: 'view',
268
+ title: grid.translate('View record'),
269
+ label: grid.translate('View'),
270
+ img: Images.images.viewRecord,
271
+ click: (e) => grid.viewRecord(e),
272
+ getDisabled: (e) => grid.viewRecordDisabled(e),
273
+ });
274
+
275
+ grid.buttons.push({
276
+ id: grid.buttons.length,
277
+ name: 'selectValue',
278
+ title: grid.translate('Select value'),
279
+ label: grid.translate('Select'),
280
+ click: (e) => grid.selectRecord(e),
281
+ img: Images.images.selectFilterValue,
282
+ getDisabled: (e) => grid.selectRecordDisabled(e),
283
+ getVisible: () => { return grid.isSelecting },
284
+ });
285
+
286
+ grid.buttons.push({
287
+ id: grid.buttons.length,
288
+ name: 'exit',
289
+ title: grid.translate('Exit'),
290
+ label: grid.translate('Exit'),
291
+ click: (e) => grid.closeSelfWnd(e),
292
+ img: Images.images.exit,
293
+ getDisabled: (e) => grid.exitDisabled(e),
294
+ getVisible: () => { return grid.isSelecting },
295
+ });
296
+
297
+ grid._buttonsDict = {};
298
+ for (let btn of grid.buttons) {
299
+ grid._buttonsDict[btn.name] = btn;
300
+ }
301
+ }
302
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
303
+ selectRecord(e) {
304
+ const grid = this;
305
+ const row = grid.selectedRow();
306
+ delete grid._selectedRows;
307
+
308
+ if (!grid.multi || !grid.pocketOpened) {
309
+ e.value = row[grid.keyField];
310
+ e.text = row[grid.nameField];
311
+ e.values = [{ value: e.value, label: e.text }];
312
+ }
313
+ else {
314
+ e.multi = true;
315
+ if (Object.keys(grid._selectedRowsDict).length === 0) {
316
+ grid._selectedRowsDict[row[grid.keyField]] = row;
317
+ }
318
+
319
+ const texts = [];
320
+ e.value = grid.selectedValue();
321
+ e.values = grid.selectedValues(texts);
322
+ e.text = texts.join(', ');
323
+ }
324
+
325
+ grid.onSelectValue(e);
326
+ }
327
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
328
+ onRowDblClick(e, row) {
329
+ const grid = this;
330
+ super.onRowDblClick(e, row);
331
+
332
+ if (grid.isSelecting && !grid.multi && grid.onSelectValue) {
333
+ const row = grid.selectedRow();
334
+ e.value = row[grid.keyField];
335
+ e.text = row[grid.nameField];
336
+ grid.onSelectValue(e);
337
+ }
338
+ }
339
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
340
+ commitChanges(e) {
341
+ const grid = this;
342
+
343
+ const row = grid.selectedRow();
344
+
345
+ grid.saveRow({ row: row, changedRow: grid.changedRow }).then(
346
+ () => {
347
+ grid.setEditing(false);
348
+ Object.assign(row, grid.changedRow);
349
+ delete grid.changedRow;
350
+ grid.refreshState();
351
+ }
352
+ ).catch((message) => {
353
+ Object.assign(grid.changedRow, row);
354
+ grid.refreshState();
355
+ alert(message || 'Error!');
356
+ });
357
+ }
358
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
359
+ commitChangesDisabled(e) {
360
+ const grid = this;
361
+ return grid._waitingRows || !grid.isEditing() || grid.isDisabled();
362
+ }
363
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
364
+ rollbackChanges(e) {
365
+ const grid = this;
366
+
367
+ delete grid.changedRow;
368
+ grid.setEditing(false);
369
+ grid.refreshState();
370
+ }
371
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
372
+ rollbackChangesDisabled(e) {
373
+ const grid = this;
374
+ return grid._waitingRows || !grid.isEditing() || grid.isDisabled();
375
+ }
376
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
377
+ addRecord(e) {
378
+ const grid = this;
379
+
380
+ grid.getNewRow().then((newRow) => {
381
+ grid.refreshState();
382
+ });
383
+ }
384
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
385
+ addRecordDisabled(e) {
386
+ const grid = this;
387
+ return grid._waitingRows || !grid.allowAdd || grid.isEditing() || grid.isDisabled();
388
+ }
389
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
390
+ copyRecord(e) {
391
+ const grid = this;
392
+
393
+ let newRow;
394
+ Object.assign(newRow, grid.selectedRow());
395
+
396
+ grid.refreshState();
397
+ }
398
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
399
+ copyRecordDisabled(e) {
400
+ const grid = this;
401
+ return grid._waitingRows || !grid.allowCopy || grid.isEditing() || grid.isDisabled() || grid.selectedRowIndex == null || grid.selectedRowIndex < 0 || !grid.rows || grid.rows.length <= 0;
402
+ }
403
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
404
+ deleteRecord(e) {
405
+ const grid = this;
406
+
407
+ if (window.confirm(grid.translate('Delete record') + '?')) {
408
+ grid.deleteRow(e).then(() => grid.refresh());
409
+ }
410
+ }
411
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
412
+ deleteRecordDisabled(e) {
413
+ const grid = this;
414
+ return grid._waitingRows || !grid.allowDelete || grid.isEditing() || grid.isDisabled() || grid.selectedRowIndex == null || grid.selectedRowIndex < 0 || !grid.rows || grid.rows.length <= 0;
415
+ }
416
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
417
+ viewRecord(e) {
418
+ const grid = this;
419
+
420
+ let cardRow = grid.selectedRow();
421
+
422
+ grid.refreshState();
423
+ }
424
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
425
+ viewRecordDisabled(e) {
426
+ const grid = this;
427
+ return grid._waitingRows || !grid.allowView || grid.isEditing() || grid.isDisabled() || grid.selectedRowIndex == null || grid.selectedRowIndex < 0 || !grid.rows || grid.rows.length <= 0;
428
+ }
429
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
430
+ selectRecordDisabled(e) {
431
+ const grid = this;
432
+ return grid._waitingRows || !grid.isSelecting || grid.isEditing() || grid.isDisabled() || grid.selectedRowIndex == null || grid.selectedRowIndex < 0 || !grid.rows || grid.rows.length <= 0;
433
+ }
434
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
435
+ exitDisabled(e) {
436
+ const grid = this;
437
+ return grid._waitingRows || !grid.isSelecting || grid.isEditing() || grid.isDisabled();
438
+ }
439
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
440
+ onSelectedRowChanged(e) {
441
+ const grid = this;
442
+ super.onSelectedRowChanged(e);
443
+
444
+ if (grid.allowEditGrid && grid.refreshState) {
445
+ grid.refreshState();
446
+ }
447
+ }
448
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
449
+ getSelectedRowIndex() {
450
+ const grid = this;
451
+ if (grid.value == null || grid.value === '') return;
452
+
453
+ let i = 0;
454
+ for (let row of grid.rows) {
455
+ if (row[grid.keyField] === grid.value) {
456
+ grid.selectedRowIndex = i;
457
+ break;
458
+ }
459
+ i++;
460
+ }
461
+ }
462
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
463
+ getGridMaxHeight() {
464
+ const grid = this;
465
+ return grid.frozenHeader ? grid.children && grid.children.length > 0 || grid.parents && grid.parents.length > 0 ? '40vh' : '80vh' : '';
466
+ }
467
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
468
+ async canLeaveRow(rowIndex) {
469
+ const grid = this;
470
+ let res;
471
+
472
+ return (!grid.allowEditGrid || !grid.isEditing()) && !grid.isDisabled();
473
+
474
+ const row = grid.rows[rowIndex];
475
+ await grid.saveRow({ row: row, changedRow: grid.changedRow }).then(
476
+ () => {
477
+ grid.setEditing(false);
478
+ Object.assign(row, grid.changedRow);
479
+ delete grid.changedRow;
480
+ grid.refreshState();
481
+ res = true;
482
+ }
483
+ ).catch((message) => {
484
+ Object.assign(grid.changedRow, row);
485
+ grid.refreshState();
486
+ res = false;
487
+ alert(message || 'Error!');
488
+ });
489
+
490
+ return res;
491
+ }
492
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
493
+ keyCellAdd(selected) {
494
+ const grid = this;
495
+ return selected ? '1' : grid.stateind;
496
+ }
497
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
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
+ isRowChanged(row) {
510
+ const grid = this;
511
+ if (!grid.changedRow) return false;
512
+
513
+ let res = false;
514
+ for (let col in grid.changedRow) {
515
+ if (grid.changedRow[col] !== row[col]) return true;
516
+ }
517
+
518
+ return res;
519
+ }
520
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
521
+ saveRow(e) {
522
+ const grid = this;
523
+
524
+ if (!grid.isRowChanged(e.row)) return new Promise(function (resolve) { resolve(true); });
525
+
526
+ return new Promise(function (resolve, reject) {
527
+ e.row = e.changedRow;
528
+ resolve(true);
529
+ });
530
+ }
531
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
532
+ }
package/src/GridFL.jsx CHANGED
@@ -17,7 +17,7 @@ export function GridFL(props) {
17
17
  grid = props.findGrid(props);
18
18
  }
19
19
  grid = grid || new GridFLClass(props);
20
- needGetRows = !props.noAutoRefresh && !props.parentGrids;
20
+ needGetRows = !props.noAutoRefresh && !grid.hasVisibleParentGrids();
21
21
  }
22
22
 
23
23
  if (props.init) {
@@ -139,6 +139,7 @@ export class GridFLClass extends GridDBClass {
139
139
  disabled={isDisabled ? 'disabled' : ''}
140
140
  onBlur={(e) => { grid.onColumnFocusLost(col, col.filter, e); }}
141
141
  autoComplete="off"
142
+ autocomplete="off"
142
143
  >
143
144
  </input>
144
145
  {
@@ -240,6 +241,8 @@ export class GridFLClass extends GridDBClass {
240
241
  showAutocomplete(e) {
241
242
  const grid = this;
242
243
 
244
+ if (grid._waitingRows) return;
245
+
243
246
  if (grid._autocompleteRect) {
244
247
  grid._autocompleteDropdown.opt.parentRect = grid._autocompleteRect;
245
248
  }
@@ -312,6 +315,8 @@ export class GridFLClass extends GridDBClass {
312
315
  // -------------------------------------------------------------------------------------------------------------------------------------------------------------
313
316
  onColumnFocusLost(column, filter, e) {
314
317
  const grid = this;
318
+ grid._waitingRows = true;
319
+
315
320
  if (grid._inputingColumn !== column) {
316
321
  //console.log('onColumnFocusLost: grid._inputingColumn !== column');
317
322
  delete grid._inputingColumn;
@@ -328,12 +333,17 @@ export class GridFLClass extends GridDBClass {
328
333
  grid.selectedRowIndex = 0;
329
334
  grid.refresh();
330
335
  }
336
+ else {
337
+ grid._waitingRows = false;
338
+ }
331
339
  }, 150);
332
340
  }
333
341
  // -------------------------------------------------------------------------------------------------------------------------------------------------------------
334
342
  onColumnFilterClick(col, e) {
335
343
  const grid = this;
336
344
 
345
+ if (grid._waitingRows) return;
346
+
337
347
  grid._inputingColumn = col;
338
348
  e.target.focus();
339
349
  setTimeout(() => {
package/src/GridGR.jsx CHANGED
@@ -1,6 +1,7 @@
1
1
  import { useState, useEffect } from 'react';
2
2
  import { GridClass } from './Grid';
3
3
  import { GraphClass } from './Graph';
4
+ import { NodeStatus } from './Base';
4
5
  // ==================================================================================================================================================================
5
6
  export function GridGR(props) {
6
7
  let grid = null;
@@ -307,4 +308,16 @@ export class GridGRClass extends GridClass {
307
308
  });
308
309
  }
309
310
  // -------------------------------------------------------------------------------------------------------------------------------------------------------------
311
+ hasVisibleParentGrids() {
312
+ const grid = this;
313
+ if (!grid.graph) return false;
314
+
315
+ for (let puid of grid.parents) {
316
+ let pnode = grid.graph.nodesDict[puid];
317
+ if (pnode.visible !== false && pnode.status === NodeStatus.grid) return true;
318
+ }
319
+
320
+ return false;
321
+ }
322
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
310
323
  }
package/src/Overlay.jsx CHANGED
@@ -6,9 +6,11 @@ export function Overlay(props) {
6
6
 
7
7
  const [ovlState, setState] = useState({ ovl: ovl, ind: 0 });
8
8
 
9
- if (ovlState.ovl && ovlState.ovl.closing) {
9
+ if (ovlState.ovl) {
10
10
  ovl = ovlState.ovl;
11
- ovl.closing = false;
11
+ if (ovlState.ovl.closing) {
12
+ ovl.closing = false;
13
+ }
12
14
  }
13
15
  else {
14
16
  ovl = new OverlayClass(props);