aio-table 6.2.0 → 6.3.0

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.
Files changed (3) hide show
  1. package/index.css +26 -58
  2. package/index.js +361 -302
  3. package/package.json +1 -1
package/index.css CHANGED
@@ -45,11 +45,23 @@
45
45
  box-sizing:border-box;
46
46
  position: -webkit-sticky;
47
47
  background: #fff;
48
- z-index:100;
48
+ height:36px;
49
49
  border-bottom:1px solid #ddd;
50
- border-left:1px solid #ddd;
50
+ z-index:100;
51
51
  box-shadow: 1px 4px 6px -2px rgba(0,0,0,0.1);
52
52
  }
53
+ .aio-table-title:after{
54
+ content:'';
55
+ width:1px;
56
+ height:100%;
57
+ top:0;
58
+ background:#ddd;
59
+ left:calc(100% - 1px);
60
+ position:absolute;
61
+ }
62
+ .aio-table-title.is-last:after{
63
+ display:none;
64
+ }
53
65
  .aio-table.rtl .aio-table-title{
54
66
  box-shadow: -1px 4px 6px -2px rgba(0,0,0,0.1);
55
67
  }
@@ -67,17 +79,6 @@
67
79
  opacity:1;
68
80
  cursor:col-resize;
69
81
  }
70
- .aio-table.rtl .aio-table-title{
71
- border-left:none;
72
- border-right:1px solid #ddd;
73
- }
74
- .aio-table-title:first-child{
75
- border-left:none;
76
- border-right:none;
77
- }
78
- .aio-table-indent{
79
- flex-shrink:0;
80
- }
81
82
  .aio-table-cell{
82
83
  display:flex;
83
84
  align-items: center;
@@ -88,6 +89,10 @@
88
89
  white-space:nowrap;
89
90
  text-overflow:ellipsis;
90
91
  background:#fff;
92
+ height:36px;
93
+ }
94
+ .aio-table-cell.last-child{
95
+ border:none;
91
96
  }
92
97
  .aio-table-cell-selectable{
93
98
  user-select: text;
@@ -96,8 +101,10 @@
96
101
  .aio-table-cell-hidden{
97
102
  display:none;
98
103
  }
99
- .aio-table-content{
104
+ .aio-table-cell-content{
100
105
  width:100%;
106
+ height:100%;
107
+ align-items: center;
101
108
  overflow:hidden;
102
109
  display: flex;
103
110
  }
@@ -202,7 +209,7 @@ select.aio-table-paging-button{
202
209
  flex-shrink:0;
203
210
  cursor:pointer;
204
211
  }
205
- .aio-table-gap{
212
+ .aio-table-cell-gap{
206
213
  width:6px;
207
214
  flex-shrink:0;
208
215
  }
@@ -329,7 +336,7 @@ select.aio-table-paging-button{
329
336
  .aio-table-group{
330
337
  display:flex;
331
338
  padding:0 12px;
332
- height:24px;
339
+ height:36px;
333
340
  align-items: center;
334
341
  white-space:nowrap;
335
342
  background:#fff;
@@ -358,9 +365,10 @@ select.aio-table-paging-button{
358
365
  }
359
366
  }
360
367
  .aio-table-toolbar-button{
361
- background:dodgerblue;
362
- color:#fff;
368
+ background:#fff;
369
+ color:inherit;
363
370
  height:30px;
371
+ border-radius:36px;
364
372
  width:30px;
365
373
  margin:0 3px;
366
374
  }
@@ -456,46 +464,6 @@ select.aio-table-paging-button{
456
464
  user-select: text;
457
465
  -webkit-user-select: text;
458
466
  }
459
-
460
- .r-layout-item{
461
- overflow:auto;
462
- display:flex;
463
- position: relative;
464
- flex-grow:0;
465
- flex-shrink: 0;
466
- }
467
- .r-layout-parent{
468
- position:relative;
469
- display:flex;
470
- flex-grow:0;
471
- flex-shrink: 0;
472
- overflow:auto;
473
- }
474
- .r-layout-html{
475
- position: absolute;
476
- width:100%;
477
- height:100%;
478
- left:0;
479
- top:0;
480
- overflow:hidden;
481
- }
482
- .r-layout-gap{
483
- flex-shrink:0;
484
- }
485
- .r-layout-gap:last-child{
486
- display:none;
487
- }
488
-
489
- @media screen and (max-width: 768px) {
490
- .r-layout-hide-in-small {
491
- display: none !important;
492
- }
493
- }
494
- @media screen and (min-width: 768px) {
495
- .r-layout-hide-in-large {
496
- display: none !important;
497
- }
498
- }
499
467
  /* custom scrollbar */
500
468
  .aio-table-unit::-webkit-scrollbar {
501
469
  width: 10px !important;
package/index.js CHANGED
@@ -57,9 +57,20 @@ class AIOTable extends _react.Component {
57
57
  filterDictionary: {},
58
58
  groupsOpen: {},
59
59
  searchText: '',
60
+ addedSorts: [],
60
61
  freezeSize,
61
62
  groupDictionary,
62
- sorts,
63
+ startIndex: 0,
64
+ //بخاطر شرایط خاص سورتس باید کاملا از پروپس ورودی ایموتیبل شود//
65
+ sorts: sorts.map(o => {
66
+ let res = {};
67
+
68
+ for (let prop in o) {
69
+ res[prop] = o[prop];
70
+ }
71
+
72
+ return res;
73
+ }),
63
74
  //make imutable to prevent change of props.paging because that will compaire with next input props.paging
64
75
  paging: paging ? { ...paging
65
76
  } : false,
@@ -67,8 +78,34 @@ class AIOTable extends _react.Component {
67
78
  columns: copiedColumns,
68
79
  prevColumns: JSON.stringify(copiedColumns),
69
80
  focused: false,
70
- toggleAllState: true
81
+ toggleAllState: true,
82
+ getCellValue: (row, getValue, field) => {
83
+ try {
84
+ if (typeof getValue === 'function') {
85
+ return getValue(row);
86
+ }
87
+
88
+ if (field) {
89
+ let result;
90
+ eval('result = row.' + field);
91
+ return result;
92
+ }
93
+
94
+ return;
95
+ } catch {
96
+ return;
97
+ }
98
+ },
99
+ setCellValue: (row, field, value) => {
100
+ //row is used in eval
101
+ let {
102
+ model
103
+ } = this.props;
104
+ eval('row.' + field + ' = ' + value);
105
+ return model;
106
+ }
71
107
  };
108
+ console.log('in table', this.state.sorts);
72
109
  }
73
110
 
74
111
  copyJson(j) {
@@ -93,15 +130,6 @@ class AIOTable extends _react.Component {
93
130
  return a(j);
94
131
  }
95
132
 
96
- getGap() {
97
- return /*#__PURE__*/_react.default.createElement("div", {
98
- className: "aio-table-gap",
99
- style: {
100
- width: this.props.cellGap
101
- }
102
- });
103
- }
104
-
105
133
  resizeDown(e) {
106
134
  var {
107
135
  touch
@@ -335,7 +363,7 @@ class AIOTable extends _react.Component {
335
363
  setTimeout(() => this.setState({
336
364
  paging: { ...paging
337
365
  },
338
- prevPaging: JSON.stringify(paging)
366
+ prevPaging: p
339
367
  }), 0);
340
368
  }
341
369
  }
@@ -368,7 +396,7 @@ class AIOTable extends _react.Component {
368
396
  this.rg = rowGap;
369
397
  this.cg = columnGap;
370
398
  this.updateColumns();
371
- var Toolbar = this.toolbar.show ? /*#__PURE__*/_react.default.createElement(RTableToolbar, this.toolbar) : null;
399
+ var Toolbar = this.toolbar.show ? /*#__PURE__*/_react.default.createElement(AIOTableToolbar, this.toolbar) : null;
372
400
  var table = columns ? this.getTable(Toolbar) : '';
373
401
  var context = { ...this.props,
374
402
  ...this.state,
@@ -398,7 +426,6 @@ class AIOTable extends _react.Component {
398
426
  },
399
427
  onChangeFilter: onChangeFilter ? this.onChangeFilter.bind(this) : undefined,
400
428
  SetState: obj => this.setState(obj),
401
- getGap: this.getGap.bind(this),
402
429
  onScroll: index => this.fn.onScroll(this.dom, index),
403
430
  groups: this.groups,
404
431
  fn: this.fn,
@@ -426,7 +453,7 @@ class AIOTable extends _react.Component {
426
453
  paging.onChange(obj);
427
454
  }
428
455
  }
429
- })));
456
+ }), this.fn.getLoading(true)));
430
457
  }
431
458
 
432
459
  }
@@ -446,7 +473,7 @@ AIOTable.defaultProps = {
446
473
  groups: []
447
474
  };
448
475
 
449
- class RTableToolbar extends _react.Component {
476
+ class AIOTableToolbar extends _react.Component {
450
477
  constructor(...args) {
451
478
  super(...args);
452
479
 
@@ -643,7 +670,7 @@ class RTableToolbar extends _react.Component {
643
670
 
644
671
  }
645
672
 
646
- _defineProperty(RTableToolbar, "contextType", AioTableContext);
673
+ _defineProperty(AIOTableToolbar, "contextType", AioTableContext);
647
674
 
648
675
  class AIOTablePaging extends _react.Component {
649
676
  getPageNumber(type) {
@@ -849,7 +876,8 @@ class AIOTableUnit extends _react.Component {
849
876
 
850
877
  keyDown(e) {
851
878
  var {
852
- SetState
879
+ SetState,
880
+ focused
853
881
  } = this.context;
854
882
 
855
883
  if (e.keyCode === 27) {
@@ -885,12 +913,11 @@ class AIOTableUnit extends _react.Component {
885
913
 
886
914
  if (inputCells.length) {
887
915
  let cell = inputCells.eq(0);
888
- let cellId = cell.attr('cellid');
889
916
  SetState({
890
- focused: cellId
917
+ focused: cell.attr('data-cell-id')
891
918
  });
892
919
  setTimeout(() => {
893
- (0, _jquery.default)('.aio-table-cell-input[cellid=' + cellId + '] .aio-table-input').focus().select();
920
+ cell.find('.aio-table-input').focus().select();
894
921
  }, 10);
895
922
  }
896
923
 
@@ -898,16 +925,17 @@ class AIOTableUnit extends _react.Component {
898
925
  }
899
926
 
900
927
  let [rowIndex, colIndex] = this.getCellIndex(focusedInput.parents('.aio-table-cell'));
928
+ console.log(rowIndex, colIndex);
901
929
 
902
930
  if (e.keyCode === 40 || e.keyCode === 38) {
903
931
  let sign = e.keyCode === 40 ? 1 : -1;
904
932
  e.preventDefault();
905
933
  rowIndex += sign;
906
- let next = inputs.filter(`[rowindex=${rowIndex}][colindex=${colIndex}]`);
934
+ let next = inputs.filter(`[data-row-index=${rowIndex}][data-col-index=${colIndex}]`);
907
935
 
908
936
  while (rowIndex < this.renderIndex && rowIndex > 0 && next.length === 0) {
909
937
  rowIndex += sign;
910
- next = inputs.filter(`[rowindex=${rowIndex}][colindex=${colIndex}]`);
938
+ next = inputs.filter(`[data-row-index=${rowIndex}][data-col-index=${colIndex}]`);
911
939
  }
912
940
 
913
941
  if (next.length) {
@@ -918,11 +946,11 @@ class AIOTableUnit extends _react.Component {
918
946
  e.preventDefault();
919
947
  let sign = (e.keyCode === 37 ? -1 : 1) * (rtl ? -1 : 1);
920
948
  colIndex += sign;
921
- let next = inputs.filter(`[rowindex=${rowIndex}][colindex=${colIndex}]`);
949
+ let next = inputs.filter(`[data-row-index=${rowIndex}][data-col-index=${colIndex}]`);
922
950
 
923
951
  while (colIndex > 0 && colIndex < columns.length && next.length === 0) {
924
952
  colIndex += sign;
925
- next = inputs.filter(`[rowindex=${rowIndex}][colindex=${colIndex}]`);
953
+ next = inputs.filter(`[data-row-index=${rowIndex}][data-col-index=${colIndex}]`);
926
954
  }
927
955
 
928
956
  if (next.length) {
@@ -933,7 +961,7 @@ class AIOTableUnit extends _react.Component {
933
961
  }
934
962
 
935
963
  getCellIndex(cell) {
936
- return [parseInt(cell.attr('rowindex')), parseInt(cell.attr('colindex'))];
964
+ return [parseInt(cell.attr('data-row-index')), parseInt(cell.attr('data-col-index'))];
937
965
  }
938
966
 
939
967
  card(props) {
@@ -988,10 +1016,20 @@ class AIOTableUnit extends _react.Component {
988
1016
  }), rows && rows.length === 0 && fn.getNoData(columns), !rows && fn.getLoading());
989
1017
  }
990
1018
 
1019
+ getPropValue(row, column, prop) {
1020
+ return typeof prop === 'function' ? prop(row, column) : prop;
1021
+ }
1022
+
991
1023
  render() {
992
1024
  var {
993
1025
  onScroll,
994
- fn
1026
+ onSwap,
1027
+ onDrop,
1028
+ onDrag,
1029
+ fn,
1030
+ focused,
1031
+ SetState,
1032
+ striped
995
1033
  } = this.context;
996
1034
  var {
997
1035
  rows,
@@ -1015,24 +1053,60 @@ class AIOTableUnit extends _react.Component {
1015
1053
  }
1016
1054
 
1017
1055
  this.renderIndex = -1;
1018
- return /*#__PURE__*/_react.default.createElement("div", props, this.getTitles(), rows && rows.length !== 0 && rows.map((row, i) => {
1019
- if (row._groupId) {
1056
+ return /*#__PURE__*/_react.default.createElement("div", props, this.getTitles(), rows && rows.length !== 0 && rows.map((o, i) => {
1057
+ if (o._groupId) {
1020
1058
  return /*#__PURE__*/_react.default.createElement(AIOTableGroup, {
1021
1059
  tableIndex,
1022
- row,
1060
+ row: o,
1023
1061
  columns,
1024
1062
  key: 'group' + i + '-' + tableIndex
1025
1063
  });
1026
1064
  }
1027
1065
 
1028
1066
  this.renderIndex++;
1029
- return row[type].map((r, j) => {
1030
- return /*#__PURE__*/_react.default.createElement(AIOTableCell, _extends({
1031
- cellId: i + '-' + j + '-' + tableIndex,
1032
- renderIndex: this.renderIndex
1033
- }, r, {
1034
- row: row.row
1035
- }));
1067
+ return o[type].map(({
1068
+ value,
1069
+ column
1070
+ }, j) => {
1071
+ let row = o.row;
1072
+ let cellId = i + '-' + j + '-' + tableIndex;
1073
+ let inlineEdit = this.getPropValue(row, column, column.inlineEdit);
1074
+ return /*#__PURE__*/_react.default.createElement(AIOTableCell, {
1075
+ key: cellId,
1076
+ attrs: {
1077
+ 'data-row-index': this.renderIndex,
1078
+ 'data-col-index': column._renderIndex,
1079
+ 'data-real-row-index': row._index,
1080
+ 'data-real-col-index': column._index,
1081
+ 'data-child-index': row._childIndex,
1082
+ 'data-childs-length': row._childsLength,
1083
+ 'data-lavel': row._level,
1084
+ 'data-cell-id': cellId,
1085
+ tabIndex: 0,
1086
+ draggable: typeof onSwap === 'function' && column.swap,
1087
+ onDrop: () => onDrop(row),
1088
+ onDragOver: e => e.preventDefault(),
1089
+ onDragStart: () => onDrag(row),
1090
+ onClick: () => {
1091
+ if (!inlineEdit || focused === cellId) {
1092
+ return;
1093
+ }
1094
+
1095
+ SetState({
1096
+ focused: cellId
1097
+ });
1098
+ setTimeout(() => (0, _jquery.default)('.aio-table-input:focus').select(), 10);
1099
+ }
1100
+ },
1101
+ striped: this.renderIndex % 2 === 0 && striped,
1102
+ value: value,
1103
+ column: column,
1104
+ row: row,
1105
+ inlineEdit: inlineEdit,
1106
+ before: this.getPropValue(row, column, column.before),
1107
+ after: this.getPropValue(row, column, column.after),
1108
+ justify: column.justify !== false && !column.treeMode
1109
+ });
1036
1110
  });
1037
1111
  }), rows && rows.length === 0 && fn.getNoData(columns), !rows && fn.getLoading());
1038
1112
  }
@@ -1285,8 +1359,7 @@ class AIOTableGroup extends _react.Component {
1285
1359
 
1286
1360
  render() {
1287
1361
  let {
1288
- indent,
1289
- getGap
1362
+ indent
1290
1363
  } = this.context;
1291
1364
  let {
1292
1365
  row,
@@ -1304,7 +1377,9 @@ class AIOTableGroup extends _react.Component {
1304
1377
  }), /*#__PURE__*/_react.default.createElement("div", {
1305
1378
  className: "aio-table-toggle",
1306
1379
  onClick: () => this.click(row)
1307
- }, this.getIcon(row)), getGap(), /*#__PURE__*/_react.default.createElement("div", {
1380
+ }, this.getIcon(row)), /*#__PURE__*/_react.default.createElement("div", {
1381
+ className: "aio-table-cell-gap"
1382
+ }), /*#__PURE__*/_react.default.createElement("div", {
1308
1383
  className: "aio-table-group-text"
1309
1384
  }, row._groupValue)));
1310
1385
  }
@@ -1327,32 +1402,6 @@ class AIOTableCell extends _react.Component {
1327
1402
  };
1328
1403
  }
1329
1404
 
1330
- getBefore(row, column) {
1331
- if (!column.before) {
1332
- return '';
1333
- }
1334
-
1335
- var before = typeof column.before === 'function' ? column.before(row, column) : column.before;
1336
- return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
1337
- className: "aio-table-icon"
1338
- }, before), this.context.getGap());
1339
- }
1340
-
1341
- getAfter(row, column) {
1342
- if (!column.after) {
1343
- return '';
1344
- }
1345
-
1346
- var after = typeof column.after === 'function' ? column.after(row, column) : column.after;
1347
- return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
1348
- style: {
1349
- flex: 1
1350
- }
1351
- }), /*#__PURE__*/_react.default.createElement("div", {
1352
- className: "aio-table-icon"
1353
- }, after));
1354
- }
1355
-
1356
1405
  getStyle(column, row) {
1357
1406
  var {
1358
1407
  padding = '36px',
@@ -1361,7 +1410,6 @@ class AIOTableCell extends _react.Component {
1361
1410
  } = column;
1362
1411
  var {
1363
1412
  rowHeight,
1364
- striped,
1365
1413
  getCellStyle = () => {
1366
1414
  return {};
1367
1415
  }
@@ -1372,17 +1420,6 @@ class AIOTableCell extends _react.Component {
1372
1420
  minWidth
1373
1421
  };
1374
1422
 
1375
- if (row._index % 2 === 0) {
1376
- if (typeof striped === 'string') {
1377
- style.background = striped;
1378
- }
1379
-
1380
- if (Array.isArray(striped)) {
1381
- style.background = striped[0];
1382
- style.color = striped[1];
1383
- }
1384
- }
1385
-
1386
1423
  if (column.template === 'gantt') {
1387
1424
  style.padding = `0 ${padding}`;
1388
1425
  }
@@ -1397,12 +1434,9 @@ class AIOTableCell extends _react.Component {
1397
1434
  var className = 'aio-table-cell';
1398
1435
  let {
1399
1436
  striped
1400
- } = this.context;
1401
- let {
1402
- renderIndex
1403
1437
  } = this.props;
1404
1438
 
1405
- if (renderIndex % 2 === 0 && striped === true) {
1439
+ if (striped) {
1406
1440
  className += ' striped';
1407
1441
  }
1408
1442
 
@@ -1410,11 +1444,7 @@ class AIOTableCell extends _react.Component {
1410
1444
  className += ' aio-table-cell-selectable';
1411
1445
  }
1412
1446
 
1413
- if (column.template) {
1414
- className += ' aio-table-cell-template';
1415
- }
1416
-
1417
- if (column.template === 'gantt') {
1447
+ if (column.template && column.template.type === 'gantt') {
1418
1448
  className += ' aio-table-cell-gantt';
1419
1449
  }
1420
1450
 
@@ -1434,6 +1464,14 @@ class AIOTableCell extends _react.Component {
1434
1464
  className += ' aio-table-cell-hidden';
1435
1465
  }
1436
1466
 
1467
+ if (row._isFirstChild) {
1468
+ className += ' first-child';
1469
+ }
1470
+
1471
+ if (row._isLastChild) {
1472
+ className += ' last-child';
1473
+ }
1474
+
1437
1475
  return className;
1438
1476
  }
1439
1477
 
@@ -1457,7 +1495,9 @@ class AIOTableCell extends _react.Component {
1457
1495
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
1458
1496
  className: "aio-table-toggle",
1459
1497
  onClick: () => fn.toggleRow(row)
1460
- }, icon), this.context.getGap());
1498
+ }, icon), /*#__PURE__*/_react.default.createElement("div", {
1499
+ className: "aio-table-cell-gap"
1500
+ }));
1461
1501
  }
1462
1502
 
1463
1503
  getContent(row, column, value) {
@@ -1465,6 +1505,9 @@ class AIOTableCell extends _react.Component {
1465
1505
  focused,
1466
1506
  fn
1467
1507
  } = this.context;
1508
+ let {
1509
+ inlineEdit
1510
+ } = this.props;
1468
1511
  var content = '';
1469
1512
  let template = typeof column.template === 'function' ? column.template(row, column) : column.template;
1470
1513
 
@@ -1472,19 +1515,15 @@ class AIOTableCell extends _react.Component {
1472
1515
  content = fn.getSliderCell(template);
1473
1516
  } else if (template && template.type === 'options') {
1474
1517
  content = fn.getOptionsCell(template);
1475
- } else if (template === 'gantt') {
1476
- content = fn.getGanttCell(row, column);
1477
- } else if (template && this.inlineEdit) {
1478
- if (!focused) {
1479
- content = template;
1480
- } else {
1481
- content = this.getInput(row, column);
1482
- }
1518
+ } else if (template && template.type === 'gantt') {
1519
+ content = fn.getGanttCell(row, template);
1520
+ } else if (template && inlineEdit) {
1521
+ content = focused ? this.getInput(row, column) : template;
1483
1522
  } else if (template) {
1484
1523
  content = template;
1485
- } else if (this.inlineEdit) {
1524
+ } else if (inlineEdit) {
1486
1525
  content = this.getInput(row, column);
1487
- } else if (column.getValue) {
1526
+ } else {
1488
1527
  content = value;
1489
1528
  }
1490
1529
 
@@ -1509,21 +1548,52 @@ class AIOTableCell extends _react.Component {
1509
1548
  return content;
1510
1549
  }
1511
1550
 
1551
+ async changeCell(value) {
1552
+ let {
1553
+ row,
1554
+ column,
1555
+ inlineEdit
1556
+ } = this.props;
1557
+ let {
1558
+ setCellValue
1559
+ } = this.context;
1560
+ let res;
1561
+ this.setState({
1562
+ loading: true
1563
+ });
1564
+
1565
+ if (inlineEdit.onChange) {
1566
+ res = await inlineEdit.onChange(row, value);
1567
+ } else {
1568
+ res = await this.context.onChange(setCellValue(row, column.field, value));
1569
+ }
1570
+
1571
+ this.setState({
1572
+ loading: false
1573
+ });
1574
+ return res;
1575
+ }
1576
+
1512
1577
  getInput(row, column) {
1513
1578
  let {
1514
- type,
1515
- getValue,
1516
- disabled = () => false
1517
- } = this.inlineEdit;
1579
+ getCellValue
1580
+ } = this.context;
1518
1581
  let {
1519
- renderIndex
1582
+ attrs,
1583
+ inlineEdit
1520
1584
  } = this.props;
1585
+ let {
1586
+ type,
1587
+ getValue,
1588
+ disabled = () => false,
1589
+ options
1590
+ } = inlineEdit;
1521
1591
  let {
1522
1592
  value
1523
1593
  } = this.state;
1524
1594
 
1525
1595
  if (getValue) {
1526
- value = getValue(row);
1596
+ value = getCellValue(row, getValue, column.field);
1527
1597
  }
1528
1598
 
1529
1599
  if (disabled(row)) {
@@ -1534,10 +1604,10 @@ class AIOTableCell extends _react.Component {
1534
1604
  return value;
1535
1605
  }
1536
1606
 
1537
- let props = { ...this.inlineEdit,
1607
+ let props = { ...inlineEdit,
1538
1608
  className: 'aio-table-input',
1539
- rowindex: renderIndex,
1540
- colindex: column._renderIndex,
1609
+ 'data-row-index': attrs['data-row-index'],
1610
+ 'data-col-index': attrs['data-col-index'],
1541
1611
  value: value === null || value === undefined ? '' : value
1542
1612
  };
1543
1613
 
@@ -1552,26 +1622,26 @@ class AIOTableCell extends _react.Component {
1552
1622
  value: e.target.value
1553
1623
  }),
1554
1624
  onBlur: async e => {
1625
+ let {
1626
+ value
1627
+ } = this.state;
1628
+
1555
1629
  if (value === this.props.value) {
1556
1630
  return;
1557
1631
  }
1558
1632
 
1559
- this.setState({
1560
- loading: true
1561
- });
1562
- let res = await this.inlineEdit.onChange(row, type === 'number' ? parseFloat(value) : value);
1563
- this.setState({
1564
- loading: false
1565
- });
1633
+ let newValue = type === 'number' ? parseFloat(value) : value;
1634
+
1635
+ if (isNaN(newValue)) {
1636
+ newValue = 0;
1637
+ }
1638
+
1639
+ let res = await this.changeCell(newValue);
1566
1640
 
1567
1641
  if (typeof res === 'string') {
1568
1642
  this.setState({
1569
1643
  error: res
1570
1644
  });
1571
- } else if (res === false) {
1572
- this.setState({
1573
- value: this.props.value
1574
- });
1575
1645
  } else {
1576
1646
  this.setState({
1577
1647
  value: this.props.value
@@ -1584,12 +1654,12 @@ class AIOTableCell extends _react.Component {
1584
1654
  }
1585
1655
 
1586
1656
  if (type === 'select') {
1587
- if (!this.inlineEdit.options) {
1657
+ if (!options) {
1588
1658
  console.error('aio table => missing options property of column inlineEdit with type="select"');
1589
1659
  return '';
1590
1660
  }
1591
1661
 
1592
- if (!Array.isArray(this.inlineEdit.options)) {
1662
+ if (!Array.isArray(options)) {
1593
1663
  console.error('aio table => options property of column inlineEdit with type="select" must be an array of objects . each object must have text and value property!!!');
1594
1664
  return '';
1595
1665
  }
@@ -1611,13 +1681,9 @@ class AIOTableCell extends _react.Component {
1611
1681
  }
1612
1682
 
1613
1683
  this.setState({
1614
- loading: true,
1615
1684
  value
1616
1685
  });
1617
- let res = await this.inlineEdit.onChange(row, value);
1618
- this.setState({
1619
- loading: false
1620
- });
1686
+ let res = await this.changeCell(value);
1621
1687
 
1622
1688
  if (typeof res === 'string') {
1623
1689
  this.setState({
@@ -1629,7 +1695,7 @@ class AIOTableCell extends _react.Component {
1629
1695
  });
1630
1696
  }
1631
1697
  }
1632
- }), this.inlineEdit.options.map((o, i) => /*#__PURE__*/_react.default.createElement("option", {
1698
+ }), options.map((o, i) => /*#__PURE__*/_react.default.createElement("option", {
1633
1699
  key: i,
1634
1700
  value: o.value
1635
1701
  }, o.text))), /*#__PURE__*/_react.default.createElement("div", {
@@ -1637,40 +1703,75 @@ class AIOTableCell extends _react.Component {
1637
1703
  }));
1638
1704
  }
1639
1705
 
1706
+ if (type === 'checkbox') {
1707
+ return /*#__PURE__*/_react.default.createElement("div", {
1708
+ className: 'aio-table-input-container',
1709
+ tabIndex: 0,
1710
+ onKeyDown: async e => {
1711
+ if (e.keyCode === 13) {
1712
+ value = value === true ? true : false;
1713
+ await this.changeCell(!value);
1714
+ }
1715
+ }
1716
+ }, /*#__PURE__*/_react.default.createElement("input", _extends({}, props, {
1717
+ onFocus: () => this.focus = true,
1718
+ onBlur: () => this.focus = false,
1719
+ checked: value === true ? true : false,
1720
+ onChange: async e => {
1721
+ let value = e.target.checked;
1722
+ this.setState({
1723
+ loading: true
1724
+ });
1725
+ await this.changeCell(value);
1726
+ this.setState({
1727
+ loading: false
1728
+ });
1729
+ }
1730
+ })), /*#__PURE__*/_react.default.createElement("div", {
1731
+ className: "aio-table-input-border"
1732
+ }));
1733
+ }
1734
+
1640
1735
  console.error('aio table => missing type property of column input');
1641
1736
  return '';
1642
1737
  }
1643
1738
 
1644
1739
  componentDidUpdate() {
1645
- if (this.inlineEdit && this.inlineEdit.type === 'select' && this.focus) {
1646
- (0, _jquery.default)(this.dom.current).find('.aio-table-input').focus();
1740
+ let {
1741
+ inlineEdit
1742
+ } = this.props;
1743
+
1744
+ if (inlineEdit && this.focus) {
1745
+ if (inlineEdit.type === 'select' || inlineEdit.type === 'checkbox') {
1746
+ (0, _jquery.default)(this.dom.current).find('.aio-table-input').focus();
1747
+ }
1647
1748
  }
1648
1749
  }
1649
1750
 
1751
+ getProps(row, column, content) {
1752
+ let title = column.getTooltip ? column.getTooltip(row) : typeof content === 'string' ? content : undefined;
1753
+ return {
1754
+ ref: this.dom,
1755
+ title,
1756
+ style: this.getStyle(column, row),
1757
+ className: this.getClassName(row, column)
1758
+ };
1759
+ }
1760
+
1650
1761
  render() {
1651
1762
  let {
1652
1763
  indent,
1653
- fn,
1654
- focused,
1655
- SetState,
1656
- onDrag,
1657
- onDrop,
1658
- onSwap
1764
+ fn
1659
1765
  } = this.context;
1660
1766
  let {
1661
1767
  row,
1662
1768
  column,
1663
1769
  value,
1664
- cellId,
1665
- renderIndex
1770
+ before,
1771
+ after,
1772
+ justify,
1773
+ attrs
1666
1774
  } = this.props;
1667
- this.inlineEdit = typeof column.inlineEdit === 'function' ? column.inlineEdit(row, column) : column.inlineEdit;
1668
-
1669
- if (column.title === 'تعداد' && row._index === 0) {
1670
- console.log('aio table cell render value', value);
1671
- console.log('aio table cell render state.value', this.state.value);
1672
- console.log('aio table cell render this.state.prevValue', this.state.prevValue);
1673
- }
1674
1775
 
1675
1776
  if (this.state.prevValue !== value) {
1676
1777
  setTimeout(() => this.setState({
@@ -1684,9 +1785,6 @@ class AIOTableCell extends _react.Component {
1684
1785
  loading
1685
1786
  } = this.state;
1686
1787
  let content = this.getContent(row, column, value);
1687
- let before = this.getBefore(row, column);
1688
- let after = this.getAfter(row, column);
1689
- let showToggleIcon = column.treeMode;
1690
1788
  let cell;
1691
1789
 
1692
1790
  if (loading) {
@@ -1704,51 +1802,30 @@ class AIOTableCell extends _react.Component {
1704
1802
  }
1705
1803
  }, error);
1706
1804
  } else {
1707
- let style = {
1708
- justifyContent: column.justify !== false && !column.treeMode ? 'center' : undefined
1709
- };
1710
1805
  cell = /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, column.treeMode && /*#__PURE__*/_react.default.createElement("div", {
1711
- className: "aio-table-indent",
1712
1806
  style: {
1713
- width: row._level * indent
1807
+ width: row._level * indent,
1808
+ flexShrink: 0
1809
+ }
1810
+ }), column.treeMode && this.getToggleIcon(row), before !== undefined && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
1811
+ className: "aio-table-icon"
1812
+ }, before), /*#__PURE__*/_react.default.createElement("div", {
1813
+ className: "aio-table-cell-gap"
1814
+ })), content !== undefined && /*#__PURE__*/_react.default.createElement("div", {
1815
+ className: "aio-table-cell-content",
1816
+ style: {
1817
+ justifyContent: justify ? 'center' : undefined
1714
1818
  }
1715
- }), showToggleIcon && this.getToggleIcon(row), before, /*#__PURE__*/_react.default.createElement("div", {
1716
- className: "aio-table-content",
1717
- style: style
1718
- }, content), after);
1819
+ }, content), after !== undefined && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
1820
+ style: {
1821
+ flex: 1
1822
+ }
1823
+ }), /*#__PURE__*/_react.default.createElement("div", {
1824
+ className: "aio-table-icon"
1825
+ }, after)));
1719
1826
  }
1720
1827
 
1721
- return /*#__PURE__*/_react.default.createElement("div", {
1722
- key: cellId,
1723
- tabIndex: 0,
1724
- ref: this.dom,
1725
- cellid: cellId,
1726
- title: typeof content === 'string' ? content : '',
1727
- "data-evenodd": row._index % 2 === 0 ? 'even' : 'odd',
1728
- rowindex: renderIndex,
1729
- colindex: column._renderIndex,
1730
- childindex: row._childIndex,
1731
- level: row._level,
1732
- isfirstchild: row._isFirstChild ? 1 : 0,
1733
- islastchild: row._isLastChild ? 1 : 0,
1734
- childslength: row._childsLength,
1735
- style: this.getStyle(column, row),
1736
- className: this.getClassName(row, column),
1737
- draggable: typeof onSwap === 'function' && column.swap,
1738
- onDragOver: e => e.preventDefault(),
1739
- onDragStart: () => onDrag(row),
1740
- onDrop: () => onDrop(row),
1741
- onClick: e => {
1742
- if (this.inlineEdit) {
1743
- if (focused !== cellId) {
1744
- SetState({
1745
- focused: cellId
1746
- });
1747
- setTimeout(() => (0, _jquery.default)('.aio-table-input:focus').select(), 10);
1748
- }
1749
- }
1750
- }
1751
- }, cell);
1828
+ return /*#__PURE__*/_react.default.createElement("div", _extends({}, attrs, this.getProps(row, column, content)), cell);
1752
1829
  }
1753
1830
 
1754
1831
  }
@@ -2045,7 +2122,7 @@ function ATFN({
2045
2122
  } = getProps();
2046
2123
  let name = window.prompt(translate('Inter Excel File Name')); // if (name === false || name === undefined || name === null) { return; }
2047
2124
 
2048
- if (!name.length) return;
2125
+ if (!name || name === null || !name.length) return;
2049
2126
  var data = $$.getJSON(columns, rows);
2050
2127
  var arrData = typeof data != "object" ? JSON.parse(data) : data;
2051
2128
  var CSV = ""; // CSV += 'title';
@@ -2182,7 +2259,7 @@ function ATFN({
2182
2259
  });
2183
2260
  },
2184
2261
 
2185
- getGanttCell(row, column) {
2262
+ getGanttCell(row, template) {
2186
2263
  let {
2187
2264
  rtl
2188
2265
  } = getProps();
@@ -2195,7 +2272,7 @@ function ATFN({
2195
2272
  getText = () => false,
2196
2273
  getStart,
2197
2274
  getEnd
2198
- } = column;
2275
+ } = template;
2199
2276
 
2200
2277
  if (typeof getStart !== 'function') {
2201
2278
  console.error('aio table => gantt column => column getStart property is not a function');
@@ -2328,7 +2405,56 @@ function ATFN({
2328
2405
  return result;
2329
2406
  },
2330
2407
 
2331
- onScroll(dom, index) {
2408
+ async onScroll(dom, index) {
2409
+ let {
2410
+ onScrollEnd
2411
+ } = getProps();
2412
+
2413
+ if (onScrollEnd) {
2414
+ if (index === undefined || index === 0) {
2415
+ let table = (0, _jquery.default)(dom.current).find('.aio-table-unit');
2416
+ let scrollTop = table.scrollTop();
2417
+ let scrollHeight = table[0].scrollHeight;
2418
+ let height = table.height();
2419
+
2420
+ if (scrollTop + height === scrollHeight) {
2421
+ let {
2422
+ startIndex
2423
+ } = getState();
2424
+ let {
2425
+ scrollLoadLength,
2426
+ scrollTotalLength
2427
+ } = getProps();
2428
+ let from = startIndex + scrollLoadLength;
2429
+
2430
+ if (from > scrollTotalLength) {
2431
+ return;
2432
+ }
2433
+
2434
+ let to = from + scrollLoadLength;
2435
+
2436
+ if (to > scrollTotalLength) {
2437
+ to = scrollTotalLength;
2438
+ }
2439
+
2440
+ let a = (0, _jquery.default)(dom.current).find('.aio-table-main-loading');
2441
+ a.css({
2442
+ display: 'flex'
2443
+ });
2444
+ let res = await onScrollEnd(from, to);
2445
+ a.css({
2446
+ display: 'none'
2447
+ });
2448
+
2449
+ if (res !== false) {
2450
+ setState({
2451
+ startIndex: from
2452
+ });
2453
+ }
2454
+ }
2455
+ }
2456
+ }
2457
+
2332
2458
  if (index === undefined) {
2333
2459
  return;
2334
2460
  }
@@ -2398,98 +2524,27 @@ function ATFN({
2398
2524
  return parseInt(list.map(o => o.length === 1 ? '0' + o : o).join(''));
2399
2525
  },
2400
2526
 
2401
- // getSorts(toolbar){
2402
- // let {onChangeSort} = getProps();
2403
- // let {sorts,columns = []} = getState();
2404
- // let Sorts = sorts.map((o)=>{
2405
- // return {
2406
- // ...o,
2407
- // onChangeDir:()=>{
2408
- // o.dir = o.dir === 'dec'?'inc':'dec';
2409
- // setState({sorts});
2410
- // if(onChangeSort){onChangeSort(Sorts.filter((o)=>o.active !== false))}
2411
- // },
2412
- // onChangeActive:()=>{
2413
- // o.active = o.active === undefined?true:o.active;
2414
- // o.active = !o.active;
2415
- // setState({sorts});
2416
- // if(onChangeSort){onChangeSort(Sorts.filter((o)=>o.active !== false))}
2417
- // }
2418
- // }
2419
- // })
2420
- // for(let i = 0; i < columns.length; i++){
2421
- // if(!columns[i].sort || columns[i]._addedTosorts){continue}
2422
- // let column = columns[i];
2423
- // let {sort,getValue} = columns[i];
2424
- // let title = sort.title || column.title || '';
2425
- // let {toggle = true,dir = 'inc',active = true,type} = sort;
2426
- // Sorts.push({
2427
- // title,dir,active,toggle,getValue,type,
2428
- // onChangeDir:()=>{
2429
- // sort.dir = sort.dir === 'dec'?'inc':'dec';
2430
- // setState({columns});
2431
- // if(onChangeSort){onChangeSort(Sorts.filter((o)=>o.active !== false))}
2432
- // },
2433
- // onChangeActive:()=>{
2434
- // sort.active = sort.active === undefined?true:sort.active;
2435
- // sort.active = !sort.active;
2436
- // setState({columns});
2437
- // if(onChangeSort){onChangeSort(Sorts.filter((o)=>o.active !== false))}
2438
- // }
2439
- // })
2440
- // }
2441
- // let result = [];
2442
- // for(let i = 0; i < Sorts.length; i++){
2443
- // let sort = Sorts[i];
2444
- // let {getValue,dir = 'inc',title,active = true,toggle = true,type,onChangeDir,onChangeActive} = sort;
2445
- // if(!title){console.error('aio table => missing sort title property'); continue;}
2446
- // if(typeof getValue !== 'function'){console.error('aio table => sort getValue property is not a function'); continue;}
2447
- // if(active === true){
2448
- // if(type === 'date'){
2449
- // let newGetValue = (row)=>{
2450
- // let value = getValue(row);
2451
- // if(typeof value !== 'string'){return 0}
2452
- // return $$.getDateNumber(value)
2453
- // }
2454
- // result.push({getValue:(row)=>newGetValue(row),dir});
2455
- // }
2456
- // else{
2457
- // result.push({getValue,dir});
2458
- // }
2459
- // }
2460
- // if(toggle){
2461
- // toolbar.show = true;
2462
- // toolbar.sort.push({
2463
- // text:title,checked:active === true,
2464
- // after:(
2465
- // <div style={{width:'30px',display:'flex',justifyContent:'flex-end'}}>
2466
- // <Icon
2467
- // size={0.8} path={dir === 'dec'?mdiArrowDown:mdiArrowUp}
2468
- // onClick={(e)=>{e.stopPropagation(); onChangeDir()}}
2469
- // />
2470
- // </div>
2471
- // ),
2472
- // onClick:()=>onChangeActive()
2473
- // })
2474
- // }
2475
- // }
2476
- // return result;
2477
- // },
2478
2527
  getSorts(toolbar) {
2479
2528
  let {
2480
2529
  onChangeSort
2481
2530
  } = getProps();
2482
2531
  let {
2483
2532
  sorts,
2484
- columns = []
2533
+ columns = [],
2534
+ getCellValue
2485
2535
  } = getState();
2536
+ let sortTitles = sorts.map(o => o.title);
2486
2537
 
2487
2538
  for (let i = 0; i < columns.length; i++) {
2488
- if (!columns[i].sort || columns[i]._addedTosorts) {
2539
+ if (!columns[i].sort) {
2540
+ continue;
2541
+ }
2542
+
2543
+ if (sortTitles.indexOf(columns[i].title) !== -1) {
2489
2544
  continue;
2490
2545
  }
2491
2546
 
2492
- columns[i]._addedTosorts = true;
2547
+ columns[i]._addedToSorts = true;
2493
2548
  let column = columns[i];
2494
2549
 
2495
2550
  if (column.sort === true) {
@@ -2499,8 +2554,10 @@ function ATFN({
2499
2554
  let {
2500
2555
  sort
2501
2556
  } = columns[i];
2502
- let title = sort.title || column.title || '';
2557
+ let a = sort.title || column.title || '';
2558
+ let title = typeof a === 'function' ? a() : a;
2503
2559
  let getValue = sort.getValue || column.getValue;
2560
+ let field = sort.field || column.field;
2504
2561
  let {
2505
2562
  toggle = true,
2506
2563
  dir = 'inc',
@@ -2513,7 +2570,8 @@ function ATFN({
2513
2570
  active,
2514
2571
  toggle,
2515
2572
  getValue,
2516
- type
2573
+ type,
2574
+ field
2517
2575
  });
2518
2576
  }
2519
2577
 
@@ -2554,7 +2612,8 @@ function ATFN({
2554
2612
  toggle = true,
2555
2613
  type,
2556
2614
  onChangeDir,
2557
- onChangeActive
2615
+ onChangeActive,
2616
+ field
2558
2617
  } = sort;
2559
2618
 
2560
2619
  if (!title) {
@@ -2562,15 +2621,10 @@ function ATFN({
2562
2621
  continue;
2563
2622
  }
2564
2623
 
2565
- if (typeof getValue !== 'function') {
2566
- console.error('aio table => sort getValue property is not a function');
2567
- continue;
2568
- }
2569
-
2570
2624
  if (active === true) {
2571
2625
  if (type === 'date') {
2572
2626
  let newGetValue = row => {
2573
- let value = getValue(row);
2627
+ let value = getCellValue(row, getValue, field);
2574
2628
 
2575
2629
  if (typeof value !== 'string') {
2576
2630
  return 0;
@@ -2631,8 +2685,7 @@ function ATFN({
2631
2685
  let {
2632
2686
  title,
2633
2687
  active = true,
2634
- toggle = true,
2635
- getValue
2688
+ toggle = true
2636
2689
  } = group;
2637
2690
 
2638
2691
  if (!title) {
@@ -2640,11 +2693,6 @@ function ATFN({
2640
2693
  continue;
2641
2694
  }
2642
2695
 
2643
- if (typeof getValue !== 'function') {
2644
- console.error('aio table => group getValue property is not a function');
2645
- continue;
2646
- }
2647
-
2648
2696
  groupDictionary[title] = groupDictionary[title] === undefined ? active : groupDictionary[title];
2649
2697
 
2650
2698
  if (groupDictionary[title]) {
@@ -2746,10 +2794,10 @@ function ATFN({
2746
2794
  } = getState();
2747
2795
  let column = columns[index];
2748
2796
  let {
2749
- title,
2750
2797
  show,
2751
2798
  storageKey
2752
2799
  } = column;
2800
+ let title = typeof column.title === 'function' ? column.title() : column.title;
2753
2801
  toolbar.show = true;
2754
2802
  toolbar.toggle.push({
2755
2803
  text: title,
@@ -3009,7 +3057,18 @@ function ATFN({
3009
3057
  }, items);
3010
3058
  },
3011
3059
 
3012
- getLoading() {
3060
+ getLoading(isMain) {
3061
+ if (isMain) {
3062
+ return /*#__PURE__*/_react.default.createElement("div", {
3063
+ className: "aio-table-loading aio-table-main-loading",
3064
+ style: {
3065
+ display: 'none'
3066
+ }
3067
+ }, $$.cubes2({
3068
+ thickness: [6, 40]
3069
+ }));
3070
+ }
3071
+
3013
3072
  return /*#__PURE__*/_react.default.createElement("div", {
3014
3073
  className: "aio-table-loading"
3015
3074
  }, $$.cubes2({
@@ -3076,7 +3135,8 @@ function ATFN({
3076
3135
  } = getProps();
3077
3136
  let {
3078
3137
  filterDictionary,
3079
- searchText
3138
+ searchText,
3139
+ getCellValue
3080
3140
  } = getState();
3081
3141
  row._values = {};
3082
3142
  let show = true,
@@ -3088,14 +3148,7 @@ function ATFN({
3088
3148
 
3089
3149
  for (let i = 0; i < columns.length; i++) {
3090
3150
  let column = columns[i],
3091
- value;
3092
-
3093
- try {
3094
- value = typeof column.getValue === 'function' ? column.getValue(row) : undefined;
3095
- } catch {
3096
- value = undefined;
3097
- }
3098
-
3151
+ value = getCellValue(row, column.getValue, column.field);
3099
3152
  row._values[column._index] = value;
3100
3153
  filterDictionary[column._index] = filterDictionary[column._index] || {
3101
3154
  items: [],
@@ -3350,6 +3403,10 @@ function ATFN({
3350
3403
  },
3351
3404
 
3352
3405
  getRowsBySort(rows, sorts) {
3406
+ let {
3407
+ getCellValue
3408
+ } = getState();
3409
+
3353
3410
  if (!sorts.length) {
3354
3411
  return rows;
3355
3412
  }
@@ -3362,10 +3419,11 @@ function ATFN({
3362
3419
  for (let i = 0; i < sorts.length; i++) {
3363
3420
  let {
3364
3421
  getValue,
3365
- dir
3422
+ dir,
3423
+ field
3366
3424
  } = sorts[i];
3367
- let aValue = getValue(a),
3368
- bValue = getValue(b);
3425
+ let aValue = getCellValue(a, getValue, field),
3426
+ bValue = getCellValue(b, getValue, field);
3369
3427
 
3370
3428
  if (aValue < bValue) {
3371
3429
  return -1 * (dir === 'dec' ? -1 : 1);
@@ -3452,7 +3510,8 @@ function ATFN({
3452
3510
  }
3453
3511
 
3454
3512
  var {
3455
- groupsOpen
3513
+ groupsOpen,
3514
+ getCellValue
3456
3515
  } = getState();
3457
3516
 
3458
3517
  function msf(obj, _level, parents) {
@@ -3484,7 +3543,7 @@ function ATFN({
3484
3543
  for (let i = 0; i < roots.length; i++) {
3485
3544
  let root = roots[i];
3486
3545
  var obj = newModel;
3487
- let values = groups.map(group => group.getValue(root[0].row));
3546
+ let values = groups.map(group => getCellValue(root[0].row, group.getValue, group.field));
3488
3547
 
3489
3548
  for (let j = 0; j < values.length; j++) {
3490
3549
  let value = values[j];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aio-table",
3
- "version": "6.2.0",
3
+ "version": "6.3.0",
4
4
  "description": "all in one table. tree mode , simple mode , tree mode, gantt mode , groupby mode, freeze mode.",
5
5
  "main": "index.js",
6
6
  "scripts": {