react-graph-grid 0.0.2 → 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 +130 -1
- package/package.json +1 -1
- package/src/Grid.jsx +4 -2
- package/src/GridDB.jsx +16 -3
- package/src/GridFE.jsx +74 -0
- package/src/GridFL.jsx +2 -1
- package/src/Modal.jsx +6 -3
- package/src/Tests/TestData.jsx +4 -4
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.
|
|
6
|
+
"version": "0.0.4",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"scripts": {
|
|
9
9
|
"dev": "vite --port 4000",
|
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'
|
|
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.
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
@@ -506,4 +506,78 @@ export class GridFEClass extends GridFLClass {
|
|
|
506
506
|
});
|
|
507
507
|
}
|
|
508
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
|
+
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
509
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
|
|
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 =
|
|
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
|
-
|
|
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
|
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
package/src/Tests/TestData.jsx
CHANGED
|
@@ -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: '
|
|
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: '
|
|
34
|
-
{ Id: 23, ParentId: [0], Name: 'Zambo', SecondName: 'Dolginov', Date: '
|
|
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: '
|
|
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 },
|