react-bootstrap-table-ng-example 4.19.0 → 4.19.2
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/.storybook/main.ts +24 -5
- package/.storybook/preview.ts +1 -1
- package/README.md +1 -1
- package/package.json +14 -14
- package/src/components/common/code-block.tsx +2 -4
- package/src/stories/BasicTable.stories.tsx +1 -1
- package/src/stories/Bootstrap4.stories.tsx +1 -1
- package/src/stories/CellEditing.stories.tsx +11 -11
- package/src/stories/ColumnFilter.stories.tsx +19 -23
- package/src/stories/ColumnToggle.stories.tsx +1 -1
- package/src/stories/Data.stories.tsx +1 -1
- package/src/stories/ExportCSV.stories.tsx +1 -1
- package/src/stories/Footer.stories.tsx +1 -1
- package/src/stories/Pagination.stories.tsx +1 -1
- package/src/stories/Remote.stories.tsx +9 -1
- package/src/stories/Remote.tsx +519 -48
- package/src/stories/RowExpand.stories.tsx +1 -1
- package/src/stories/RowSelection.stories.tsx +1 -1
- package/src/stories/SortTable.stories.tsx +1 -1
- package/src/stories/TableOverlay.stories.tsx +1 -1
- package/src/stories/TableOverlay.tsx +28 -26
- package/src/stories/TableSearch.stories.tsx +1 -1
- package/src/stories/Welcome.stories.ts +1 -1
- package/src/stories/WorkOnColumns.stories.tsx +1 -1
- package/src/stories/WorkOnHeaderColumns.stories.tsx +1 -1
- package/src/stories/WorkOnRows.stories.tsx +1 -1
- package/src/stories/bootstrap-style.tsx +2 -5
- package/tsconfig.json +1 -1
- package/sb_output.txt +0 -382
package/src/stories/Remote.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* eslint-disable import/no-anonymous-default-export */
|
|
2
|
-
|
|
2
|
+
|
|
3
3
|
import React from "react";
|
|
4
4
|
|
|
5
5
|
import BootstrapTable from "../../../react-bootstrap-table-ng";
|
|
@@ -8,9 +8,13 @@ import filterFactory, {
|
|
|
8
8
|
LIKE,
|
|
9
9
|
textFilter,
|
|
10
10
|
} from "../../../react-bootstrap-table-ng-filter";
|
|
11
|
-
import
|
|
11
|
+
import overlayFactory from "../../../react-bootstrap-table-ng-overlay";
|
|
12
|
+
import paginationFactory, {
|
|
13
|
+
PaginationProvider, PaginationListStandalone,
|
|
14
|
+
PaginationTotalStandalone, SizePerPageDropdownStandalone
|
|
15
|
+
} from "../../../react-bootstrap-table-ng-paginator";
|
|
12
16
|
import ToolkitProvider, {
|
|
13
|
-
Search,
|
|
17
|
+
Search, CSVExport
|
|
14
18
|
} from "../../../react-bootstrap-table-ng-toolkit";
|
|
15
19
|
import Code from "../components/common/code-block";
|
|
16
20
|
import { productsGenerator } from "../utils/common";
|
|
@@ -117,7 +121,12 @@ class Container extends React.Component {
|
|
|
117
121
|
}
|
|
118
122
|
`;
|
|
119
123
|
|
|
120
|
-
|
|
124
|
+
interface RemoteSortProps {
|
|
125
|
+
data: any[];
|
|
126
|
+
onTableChange: (type: any, context: any) => void;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const RemoteSort = (props: RemoteSortProps) => (
|
|
121
130
|
<div>
|
|
122
131
|
<BootstrapTable
|
|
123
132
|
remote={{ sort: true }}
|
|
@@ -130,10 +139,6 @@ const RemoteSort = (props: any) => (
|
|
|
130
139
|
</div>
|
|
131
140
|
);
|
|
132
141
|
|
|
133
|
-
RemoteSort.propTypes = {
|
|
134
|
-
data: PropTypes.array.isRequired,
|
|
135
|
-
onTableChange: PropTypes.func.isRequired,
|
|
136
|
-
};
|
|
137
142
|
|
|
138
143
|
interface RemoteSortState {
|
|
139
144
|
data: any;
|
|
@@ -278,7 +283,12 @@ class Container extends React.Component {
|
|
|
278
283
|
}
|
|
279
284
|
`;
|
|
280
285
|
|
|
281
|
-
|
|
286
|
+
interface RemoteFilterProps {
|
|
287
|
+
data: any[];
|
|
288
|
+
onTableChange: (type: any, context: any) => void;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
const RemoteFilter = (props: RemoteFilterProps) => (
|
|
282
292
|
<div>
|
|
283
293
|
<BootstrapTable
|
|
284
294
|
remote={{ filter: true }}
|
|
@@ -292,10 +302,6 @@ const RemoteFilter = (props: any) => (
|
|
|
292
302
|
</div>
|
|
293
303
|
);
|
|
294
304
|
|
|
295
|
-
RemoteFilter.propTypes = {
|
|
296
|
-
data: PropTypes.array.isRequired,
|
|
297
|
-
onTableChange: PropTypes.func.isRequired,
|
|
298
|
-
};
|
|
299
305
|
|
|
300
306
|
interface RemoteFilterState {
|
|
301
307
|
data: any;
|
|
@@ -399,13 +405,21 @@ class Container extends React.Component {
|
|
|
399
405
|
}
|
|
400
406
|
`;
|
|
401
407
|
|
|
408
|
+
interface RemotePaginationProps {
|
|
409
|
+
data: any[];
|
|
410
|
+
page: number;
|
|
411
|
+
totalSize: number;
|
|
412
|
+
sizePerPage: number;
|
|
413
|
+
onTableChange: (type: any, context: any) => void;
|
|
414
|
+
}
|
|
415
|
+
|
|
402
416
|
const RemotePagination = ({
|
|
403
417
|
data,
|
|
404
418
|
page,
|
|
405
419
|
sizePerPage,
|
|
406
420
|
onTableChange,
|
|
407
421
|
totalSize,
|
|
408
|
-
}:
|
|
422
|
+
}: RemotePaginationProps) => (
|
|
409
423
|
<div>
|
|
410
424
|
<BootstrapTable
|
|
411
425
|
remote
|
|
@@ -432,13 +446,6 @@ const RemotePagination = ({
|
|
|
432
446
|
</div>
|
|
433
447
|
);
|
|
434
448
|
|
|
435
|
-
RemotePagination.propTypes = {
|
|
436
|
-
data: PropTypes.array.isRequired,
|
|
437
|
-
page: PropTypes.number.isRequired,
|
|
438
|
-
totalSize: PropTypes.number.isRequired,
|
|
439
|
-
sizePerPage: PropTypes.number.isRequired,
|
|
440
|
-
onTableChange: PropTypes.func.isRequired,
|
|
441
|
-
};
|
|
442
449
|
|
|
443
450
|
interface RemotePaginationState {
|
|
444
451
|
data: any;
|
|
@@ -585,7 +592,12 @@ class Container extends React.Component {
|
|
|
585
592
|
}
|
|
586
593
|
`;
|
|
587
594
|
|
|
588
|
-
|
|
595
|
+
interface RemoteSearchProps {
|
|
596
|
+
data: any[];
|
|
597
|
+
onTableChange: (type: any, context: any) => void;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
const RemoteSearch = (props: RemoteSearchProps) => (
|
|
589
601
|
<div>
|
|
590
602
|
<ToolkitProvider
|
|
591
603
|
keyField="id"
|
|
@@ -608,10 +620,6 @@ const RemoteSearch = (props: any) => (
|
|
|
608
620
|
</div>
|
|
609
621
|
);
|
|
610
622
|
|
|
611
|
-
RemoteSearch.propTypes = {
|
|
612
|
-
data: PropTypes.array.isRequired,
|
|
613
|
-
onTableChange: PropTypes.func.isRequired,
|
|
614
|
-
};
|
|
615
623
|
|
|
616
624
|
interface RemoteSearchState {
|
|
617
625
|
data: any;
|
|
@@ -729,7 +737,13 @@ class Container extends React.Component {
|
|
|
729
737
|
}
|
|
730
738
|
`;
|
|
731
739
|
|
|
732
|
-
|
|
740
|
+
interface RemoteCellEditProps {
|
|
741
|
+
data: any[];
|
|
742
|
+
onTableChange: (type: any, context: any) => void;
|
|
743
|
+
errorMessage: string;
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
const RemoteCellEdit = (props: RemoteCellEditProps) => {
|
|
733
747
|
const cellEdit = {
|
|
734
748
|
mode: "click",
|
|
735
749
|
errorMessage: props.errorMessage,
|
|
@@ -763,11 +777,6 @@ const RemoteCellEdit = (props: any) => {
|
|
|
763
777
|
);
|
|
764
778
|
};
|
|
765
779
|
|
|
766
|
-
RemoteCellEdit.propTypes = {
|
|
767
|
-
data: PropTypes.array.isRequired,
|
|
768
|
-
onTableChange: PropTypes.func.isRequired,
|
|
769
|
-
errorMessage: PropTypes.string.isRequired,
|
|
770
|
-
};
|
|
771
780
|
|
|
772
781
|
interface RemoteCellEditState {
|
|
773
782
|
data: any;
|
|
@@ -872,13 +881,6 @@ const RemoteAll = ({ data, page, sizePerPage, onTableChange, totalSize }) => (
|
|
|
872
881
|
</div>
|
|
873
882
|
);
|
|
874
883
|
|
|
875
|
-
RemoteAll.propTypes = {
|
|
876
|
-
data: PropTypes.array.isRequired,
|
|
877
|
-
page: PropTypes.number.isRequired,
|
|
878
|
-
totalSize: PropTypes.number.isRequired,
|
|
879
|
-
sizePerPage: PropTypes.number.isRequired,
|
|
880
|
-
onTableChange: PropTypes.func.isRequired
|
|
881
|
-
};
|
|
882
884
|
|
|
883
885
|
class Container extends React.Component {
|
|
884
886
|
constructor(props) {
|
|
@@ -970,13 +972,21 @@ class Container extends React.Component {
|
|
|
970
972
|
}
|
|
971
973
|
`;
|
|
972
974
|
|
|
975
|
+
interface RemoteAllProps {
|
|
976
|
+
data: any[];
|
|
977
|
+
page: number;
|
|
978
|
+
totalSize: number;
|
|
979
|
+
sizePerPage: number;
|
|
980
|
+
onTableChange: (type: any, context: any) => void;
|
|
981
|
+
}
|
|
982
|
+
|
|
973
983
|
const RemoteAll = ({
|
|
974
984
|
data,
|
|
975
985
|
page,
|
|
976
986
|
sizePerPage,
|
|
977
987
|
onTableChange,
|
|
978
988
|
totalSize,
|
|
979
|
-
}:
|
|
989
|
+
}: RemoteAllProps) => (
|
|
980
990
|
<div>
|
|
981
991
|
<h3>
|
|
982
992
|
When <code>remote.pagination</code> is enabled, the filtering, sorting and
|
|
@@ -1024,14 +1034,6 @@ const RemoteAll = ({
|
|
|
1024
1034
|
</div>
|
|
1025
1035
|
);
|
|
1026
1036
|
|
|
1027
|
-
RemoteAll.propTypes = {
|
|
1028
|
-
data: PropTypes.array.isRequired,
|
|
1029
|
-
page: PropTypes.number.isRequired,
|
|
1030
|
-
totalSize: PropTypes.number.isRequired,
|
|
1031
|
-
sizePerPage: PropTypes.number.isRequired,
|
|
1032
|
-
onTableChange: PropTypes.func.isRequired,
|
|
1033
|
-
};
|
|
1034
|
-
|
|
1035
1037
|
let products = productsGenerator(87);
|
|
1036
1038
|
|
|
1037
1039
|
interface RemoteAllState {
|
|
@@ -1132,6 +1134,473 @@ class RemoteAllComponent extends React.Component<{}, RemoteAllState> {
|
|
|
1132
1134
|
}
|
|
1133
1135
|
}
|
|
1134
1136
|
|
|
1137
|
+
|
|
1138
|
+
const remoteAllExportSourceCode = `\
|
|
1139
|
+
import BootstrapTable from 'react-bootstrap-table-ng';
|
|
1140
|
+
import cellEditFactory from 'react-bootstrap-table-ng-editor';
|
|
1141
|
+
import filterFactory, {
|
|
1142
|
+
LIKE,
|
|
1143
|
+
textFilter,
|
|
1144
|
+
} from 'react-bootstrap-table-ng-filter';
|
|
1145
|
+
import paginationFactory, {
|
|
1146
|
+
PaginationProvider, PaginationListStandalone, PaginationTotalStandalone, SizePerPageDropdownStandalone
|
|
1147
|
+
} from 'react-bootstrap-table-ng-paginator';
|
|
1148
|
+
import ToolkitProvider, {
|
|
1149
|
+
Search, CSVExport
|
|
1150
|
+
} from 'react-bootstrap-table-ng-toolkit';
|
|
1151
|
+
// import ...
|
|
1152
|
+
|
|
1153
|
+
const productColumns = [
|
|
1154
|
+
{
|
|
1155
|
+
dataField: "id",
|
|
1156
|
+
text: "Product ID",
|
|
1157
|
+
sort: true,
|
|
1158
|
+
},
|
|
1159
|
+
{
|
|
1160
|
+
dataField: "name",
|
|
1161
|
+
text: "Product Name",
|
|
1162
|
+
filter: textFilter(),
|
|
1163
|
+
sort: true,
|
|
1164
|
+
},
|
|
1165
|
+
{
|
|
1166
|
+
dataField: "price",
|
|
1167
|
+
text: "Product Price",
|
|
1168
|
+
filter: textFilter(),
|
|
1169
|
+
sort: true,
|
|
1170
|
+
hidden: true,
|
|
1171
|
+
},
|
|
1172
|
+
];
|
|
1173
|
+
|
|
1174
|
+
const { ExportCSVButton } = CSVExport;
|
|
1175
|
+
|
|
1176
|
+
//leslint-disable-next-line react/proprtypes
|
|
1177
|
+
const CustomToggleList = ({ columns, onColumnToggle, toggles }) => (
|
|
1178
|
+
<div className="btn-group btn-group-toggle" data-toggle="buttons" style={{ marginBottom: '10px' }}>
|
|
1179
|
+
{columns
|
|
1180
|
+
.filter(column => !(column.toggleHidden === true))
|
|
1181
|
+
.map(column => ({
|
|
1182
|
+
...column,
|
|
1183
|
+
toggle: toggles[column.dataField]
|
|
1184
|
+
}))
|
|
1185
|
+
.map(column => (
|
|
1186
|
+
<button
|
|
1187
|
+
type="button"
|
|
1188
|
+
key={column.dataField}
|
|
1189
|
+
className={\`btn \${column.toggle ? 'btn-primary' : 'btn-default'}\`}
|
|
1190
|
+
data-toggle="button"
|
|
1191
|
+
aria-pressed={column.toggle ? 'true' : 'false'}
|
|
1192
|
+
onClick={() => onColumnToggle(column.dataField)}
|
|
1193
|
+
>
|
|
1194
|
+
{column.text}
|
|
1195
|
+
</button>
|
|
1196
|
+
))}
|
|
1197
|
+
</div>
|
|
1198
|
+
);
|
|
1199
|
+
|
|
1200
|
+
const customPaginationTotal = (from: number, to: number, totalSize: number) => (
|
|
1201
|
+
<span className="react-bootstrap-table-pagination-total">
|
|
1202
|
+
{from} to {to} of {totalSize} rows
|
|
1203
|
+
</span>
|
|
1204
|
+
);
|
|
1205
|
+
|
|
1206
|
+
|
|
1207
|
+
const allExportProducts = productsGenerator(487);
|
|
1208
|
+
|
|
1209
|
+
class RemoteAllExportComponent extends React.Component {
|
|
1210
|
+
constructor(props: any) {
|
|
1211
|
+
super(props);
|
|
1212
|
+
this.state = {
|
|
1213
|
+
page: 1,
|
|
1214
|
+
data: allExportProducts.slice(0, 10),
|
|
1215
|
+
totalSize: allExportProducts.length,
|
|
1216
|
+
sizePerPage: 10,
|
|
1217
|
+
allData: allExportProducts,
|
|
1218
|
+
};
|
|
1219
|
+
this.handleTableChange = this.handleTableChange.bind(this);
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
handleTableChange = (
|
|
1223
|
+
type: any,
|
|
1224
|
+
{ page, sizePerPage, filters, sortField, sortOrder, cellEdit }: any
|
|
1225
|
+
) => {
|
|
1226
|
+
setTimeout(() => {
|
|
1227
|
+
// Handle cell editing
|
|
1228
|
+
if (type === "cellEdit") {
|
|
1229
|
+
const { rowId, dataField, newValue } = cellEdit;
|
|
1230
|
+
products = products.map((row: any) => {
|
|
1231
|
+
if (row.id === rowId) {
|
|
1232
|
+
const newRow = { ...row };
|
|
1233
|
+
newRow[dataField] = newValue;
|
|
1234
|
+
return newRow;
|
|
1235
|
+
}
|
|
1236
|
+
return row;
|
|
1237
|
+
});
|
|
1238
|
+
}
|
|
1239
|
+
let result = allExportProducts;
|
|
1240
|
+
// Handle column filters
|
|
1241
|
+
result = result.filter((row: any) => {
|
|
1242
|
+
let valid = true;
|
|
1243
|
+
for (const dataField in filters) {
|
|
1244
|
+
const { filterVal, filterType, comparator } = filters[dataField];
|
|
1245
|
+
|
|
1246
|
+
if (filterType === "TEXT") {
|
|
1247
|
+
if (comparator === LIKE) {
|
|
1248
|
+
valid = row[dataField].toString().indexOf(filterVal) > -1;
|
|
1249
|
+
} else {
|
|
1250
|
+
valid = row[dataField] === filterVal;
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
if (!valid) break;
|
|
1254
|
+
}
|
|
1255
|
+
return valid;
|
|
1256
|
+
});
|
|
1257
|
+
// Handle column sort
|
|
1258
|
+
if (sortOrder === "asc") {
|
|
1259
|
+
result = result.sort((a: any, b: any) => {
|
|
1260
|
+
if (a[sortField] > b[sortField]) {
|
|
1261
|
+
return 1;
|
|
1262
|
+
} else if (b[sortField] > a[sortField]) {
|
|
1263
|
+
return -1;
|
|
1264
|
+
}
|
|
1265
|
+
return 0;
|
|
1266
|
+
});
|
|
1267
|
+
} else {
|
|
1268
|
+
result = result.sort((a: any, b: any) => {
|
|
1269
|
+
if (a[sortField] > b[sortField]) {
|
|
1270
|
+
return -1;
|
|
1271
|
+
} else if (b[sortField] > a[sortField]) {
|
|
1272
|
+
return 1;
|
|
1273
|
+
}
|
|
1274
|
+
return 0;
|
|
1275
|
+
});
|
|
1276
|
+
}
|
|
1277
|
+
this.setState(() => ({
|
|
1278
|
+
page: page,
|
|
1279
|
+
data: result.slice((page - 1) * sizePerPage, page * sizePerPage),
|
|
1280
|
+
totalSize: result.length,
|
|
1281
|
+
sizePerPage: sizePerPage,
|
|
1282
|
+
allData: result,
|
|
1283
|
+
}));
|
|
1284
|
+
}, 2000);
|
|
1285
|
+
};
|
|
1286
|
+
|
|
1287
|
+
handleExport = (onExport: any) => (e: any) => {
|
|
1288
|
+
onExport((this.state as any).allData);
|
|
1289
|
+
};
|
|
1290
|
+
|
|
1291
|
+
render() {
|
|
1292
|
+
return (
|
|
1293
|
+
<ToolkitProvider
|
|
1294
|
+
keyField="id"
|
|
1295
|
+
data={this.state.data}
|
|
1296
|
+
columns={productColumns}
|
|
1297
|
+
search
|
|
1298
|
+
columnToggle
|
|
1299
|
+
exportCSV={{
|
|
1300
|
+
fileName: 'products-export.csv',
|
|
1301
|
+
noAutoBOM: false,
|
|
1302
|
+
blobType: 'text/csv;charset=ansi',
|
|
1303
|
+
data: this.state.allData
|
|
1304
|
+
}}
|
|
1305
|
+
>
|
|
1306
|
+
{props => (
|
|
1307
|
+
<PaginationProvider
|
|
1308
|
+
pagination={paginationFactory({
|
|
1309
|
+
custom: true,
|
|
1310
|
+
page: this.state.page,
|
|
1311
|
+
sizePerPage: this.state.sizePerPage,
|
|
1312
|
+
totalSize: this.state.totalSize,
|
|
1313
|
+
sizePerPageList: [10, 25, 50, 100],
|
|
1314
|
+
showSizePerPage: true,
|
|
1315
|
+
showTotal: true,
|
|
1316
|
+
paginationTotalRenderer: customPaginationTotal,
|
|
1317
|
+
})}
|
|
1318
|
+
>
|
|
1319
|
+
{({ paginationProps, paginationTableProps }) => (
|
|
1320
|
+
<div>
|
|
1321
|
+
<CustomToggleList {...props.columnToggleProps} />
|
|
1322
|
+
<div>
|
|
1323
|
+
<SizePerPageDropdownStandalone {...paginationProps} />
|
|
1324
|
+
<PaginationTotalStandalone {...paginationProps} />
|
|
1325
|
+
<ExportCSVButton {...props.csvProps}
|
|
1326
|
+
className="btn-warning"
|
|
1327
|
+
style={{ marginLeft: '20px' }}
|
|
1328
|
+
onClick={this.handleExport(props.csvProps.onExport)}
|
|
1329
|
+
>Export CSV</ExportCSVButton>
|
|
1330
|
+
<PaginationListStandalone {...paginationProps} />
|
|
1331
|
+
</div>
|
|
1332
|
+
<BootstrapTable
|
|
1333
|
+
remote
|
|
1334
|
+
striped
|
|
1335
|
+
hover
|
|
1336
|
+
condensed
|
|
1337
|
+
defaultSorted={[
|
|
1338
|
+
{
|
|
1339
|
+
dataField: "name",
|
|
1340
|
+
order: "desc",
|
|
1341
|
+
},
|
|
1342
|
+
]}
|
|
1343
|
+
{...props.baseProps}
|
|
1344
|
+
filter={filterFactory()}
|
|
1345
|
+
overlay={overlayFactory({ spinner: true })}
|
|
1346
|
+
onTableChange={this.handleTableChange}
|
|
1347
|
+
cellEdit={cellEditFactory({
|
|
1348
|
+
mode: "click",
|
|
1349
|
+
})}
|
|
1350
|
+
{...paginationTableProps}
|
|
1351
|
+
/>
|
|
1352
|
+
<div style={{ marginBottom: '20px' }}>
|
|
1353
|
+
<SizePerPageDropdownStandalone {...paginationProps} />
|
|
1354
|
+
<PaginationTotalStandalone {...paginationProps} />
|
|
1355
|
+
<ExportCSVButton {...props.csvProps}
|
|
1356
|
+
className="btn-warning"
|
|
1357
|
+
style={{ marginLeft: '20px' }}
|
|
1358
|
+
onClick={this.handleExport(props.csvProps.onExport)}
|
|
1359
|
+
>Export CSV</ExportCSVButton>
|
|
1360
|
+
<PaginationListStandalone {...paginationProps} />
|
|
1361
|
+
</div>
|
|
1362
|
+
<Code>{remoteAllExportSourceCode}</Code>
|
|
1363
|
+
</div>
|
|
1364
|
+
)}
|
|
1365
|
+
</PaginationProvider>
|
|
1366
|
+
)}
|
|
1367
|
+
</ToolkitProvider>
|
|
1368
|
+
);
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
`;
|
|
1372
|
+
|
|
1373
|
+
const productColumns = [
|
|
1374
|
+
{
|
|
1375
|
+
dataField: "id",
|
|
1376
|
+
text: "Product ID",
|
|
1377
|
+
filter: textFilter(),
|
|
1378
|
+
sort: true,
|
|
1379
|
+
},
|
|
1380
|
+
{
|
|
1381
|
+
dataField: "name",
|
|
1382
|
+
text: "Product Name",
|
|
1383
|
+
filter: textFilter(),
|
|
1384
|
+
sort: true,
|
|
1385
|
+
},
|
|
1386
|
+
{
|
|
1387
|
+
dataField: "price",
|
|
1388
|
+
text: "Product Price",
|
|
1389
|
+
filter: textFilter(),
|
|
1390
|
+
sort: true,
|
|
1391
|
+
hidden: true,
|
|
1392
|
+
},
|
|
1393
|
+
];
|
|
1394
|
+
|
|
1395
|
+
const { ExportCSVButton } = CSVExport;
|
|
1396
|
+
|
|
1397
|
+
//leslint-disable-next-line react/proprtypes
|
|
1398
|
+
interface CustomToggleListProps {
|
|
1399
|
+
columns: any[];
|
|
1400
|
+
onColumnToggle: (dataField: string) => void;
|
|
1401
|
+
toggles: any;
|
|
1402
|
+
}
|
|
1403
|
+
|
|
1404
|
+
const CustomToggleList = ({
|
|
1405
|
+
columns,
|
|
1406
|
+
onColumnToggle,
|
|
1407
|
+
toggles,
|
|
1408
|
+
}: CustomToggleListProps) => (
|
|
1409
|
+
|
|
1410
|
+
<div className="btn-group btn-group-toggle" data-toggle="buttons" style={{ marginBottom: '10px' }}>
|
|
1411
|
+
{columns
|
|
1412
|
+
.filter(column => !(column.toggleHidden === true))
|
|
1413
|
+
.map(column => ({
|
|
1414
|
+
...column,
|
|
1415
|
+
toggle: toggles[column.dataField]
|
|
1416
|
+
}))
|
|
1417
|
+
.map(column => (
|
|
1418
|
+
<button
|
|
1419
|
+
type="button"
|
|
1420
|
+
key={column.dataField}
|
|
1421
|
+
className={`btn ${column.toggle ? 'btn-primary' : 'btn-default'}`}
|
|
1422
|
+
data-toggle="button"
|
|
1423
|
+
aria-pressed={column.toggle ? 'true' : 'false'}
|
|
1424
|
+
onClick={() => onColumnToggle(column.dataField)}
|
|
1425
|
+
>
|
|
1426
|
+
{column.text}
|
|
1427
|
+
</button>
|
|
1428
|
+
))}
|
|
1429
|
+
</div>
|
|
1430
|
+
);
|
|
1431
|
+
|
|
1432
|
+
const customPaginationTotal = (from: number, to: number, totalSize: number) => (
|
|
1433
|
+
<span className="react-bootstrap-table-pagination-total" style={{ marginLeft: '10px' }}>
|
|
1434
|
+
{from} to {to} of {totalSize} rows
|
|
1435
|
+
</span>
|
|
1436
|
+
);
|
|
1437
|
+
|
|
1438
|
+
|
|
1439
|
+
const allExportProducts = productsGenerator(487);
|
|
1440
|
+
|
|
1441
|
+
class RemoteAllCustomComponent extends React.Component {
|
|
1442
|
+
constructor(props: any) {
|
|
1443
|
+
super(props);
|
|
1444
|
+
this.state = {
|
|
1445
|
+
page: 1,
|
|
1446
|
+
data: allExportProducts.slice(0, 10),
|
|
1447
|
+
totalSize: allExportProducts.length,
|
|
1448
|
+
sizePerPage: 10,
|
|
1449
|
+
allData: allExportProducts,
|
|
1450
|
+
};
|
|
1451
|
+
this.handleTableChange = this.handleTableChange.bind(this);
|
|
1452
|
+
}
|
|
1453
|
+
|
|
1454
|
+
handleTableChange = (
|
|
1455
|
+
type: any,
|
|
1456
|
+
{ page, sizePerPage, filters, sortField, sortOrder, cellEdit }: any
|
|
1457
|
+
) => {
|
|
1458
|
+
setTimeout(() => {
|
|
1459
|
+
// Handle cell editing
|
|
1460
|
+
if (type === "cellEdit") {
|
|
1461
|
+
const { rowId, dataField, newValue } = cellEdit;
|
|
1462
|
+
products = products.map((row: any) => {
|
|
1463
|
+
if (row.id === rowId) {
|
|
1464
|
+
const newRow = { ...row };
|
|
1465
|
+
newRow[dataField] = newValue;
|
|
1466
|
+
return newRow;
|
|
1467
|
+
}
|
|
1468
|
+
return row;
|
|
1469
|
+
});
|
|
1470
|
+
}
|
|
1471
|
+
let result = allExportProducts;
|
|
1472
|
+
// Handle column filters
|
|
1473
|
+
result = result.filter((row: any) => {
|
|
1474
|
+
let valid = true;
|
|
1475
|
+
for (const dataField in filters) {
|
|
1476
|
+
const { filterVal, filterType, comparator } = filters[dataField];
|
|
1477
|
+
|
|
1478
|
+
if (filterType === "TEXT") {
|
|
1479
|
+
if (comparator === LIKE) {
|
|
1480
|
+
valid = row[dataField].toString().indexOf(filterVal) > -1;
|
|
1481
|
+
} else {
|
|
1482
|
+
valid = row[dataField] === filterVal;
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
if (!valid) break;
|
|
1486
|
+
}
|
|
1487
|
+
return valid;
|
|
1488
|
+
});
|
|
1489
|
+
// Handle column sort
|
|
1490
|
+
if (sortOrder === "asc") {
|
|
1491
|
+
result = result.sort((a: any, b: any) => {
|
|
1492
|
+
if (a[sortField] > b[sortField]) {
|
|
1493
|
+
return 1;
|
|
1494
|
+
} else if (b[sortField] > a[sortField]) {
|
|
1495
|
+
return -1;
|
|
1496
|
+
}
|
|
1497
|
+
return 0;
|
|
1498
|
+
});
|
|
1499
|
+
} else {
|
|
1500
|
+
result = result.sort((a: any, b: any) => {
|
|
1501
|
+
if (a[sortField] > b[sortField]) {
|
|
1502
|
+
return -1;
|
|
1503
|
+
} else if (b[sortField] > a[sortField]) {
|
|
1504
|
+
return 1;
|
|
1505
|
+
}
|
|
1506
|
+
return 0;
|
|
1507
|
+
});
|
|
1508
|
+
}
|
|
1509
|
+
this.setState(() => ({
|
|
1510
|
+
page: page * sizePerPage < result.length ? page : Math.ceil(result.length / sizePerPage),
|
|
1511
|
+
data: result.slice((page - 1) * sizePerPage, page * sizePerPage),
|
|
1512
|
+
totalSize: result.length,
|
|
1513
|
+
sizePerPage: sizePerPage,
|
|
1514
|
+
allData: result,
|
|
1515
|
+
}));
|
|
1516
|
+
}, 2000);
|
|
1517
|
+
};
|
|
1518
|
+
|
|
1519
|
+
handleExport = onExport => e => {
|
|
1520
|
+
onExport(this.state.allData);
|
|
1521
|
+
};
|
|
1522
|
+
|
|
1523
|
+
render() {
|
|
1524
|
+
return (
|
|
1525
|
+
<ToolkitProvider
|
|
1526
|
+
keyField="id"
|
|
1527
|
+
data={this.state.data}
|
|
1528
|
+
columns={productColumns}
|
|
1529
|
+
search
|
|
1530
|
+
columnToggle
|
|
1531
|
+
exportCSV={{
|
|
1532
|
+
fileName: 'products-export.csv',
|
|
1533
|
+
noAutoBOM: false,
|
|
1534
|
+
blobType: 'text/csv;charset=ansi',
|
|
1535
|
+
data: this.state.allData
|
|
1536
|
+
}}
|
|
1537
|
+
>
|
|
1538
|
+
{props => (
|
|
1539
|
+
<PaginationProvider
|
|
1540
|
+
pagination={paginationFactory({
|
|
1541
|
+
custom: true,
|
|
1542
|
+
page: this.state.page,
|
|
1543
|
+
sizePerPage: this.state.sizePerPage,
|
|
1544
|
+
totalSize: this.state.totalSize,
|
|
1545
|
+
sizePerPageList: [10, 25, 50, 100],
|
|
1546
|
+
showSizePerPage: true,
|
|
1547
|
+
showTotal: true,
|
|
1548
|
+
paginationTotalRenderer: customPaginationTotal,
|
|
1549
|
+
})}
|
|
1550
|
+
>
|
|
1551
|
+
{({ paginationProps, paginationTableProps }) => (
|
|
1552
|
+
<div>
|
|
1553
|
+
<CustomToggleList {...props.columnToggleProps} />
|
|
1554
|
+
<div>
|
|
1555
|
+
<SizePerPageDropdownStandalone {...paginationProps} />
|
|
1556
|
+
<PaginationTotalStandalone {...paginationProps} />
|
|
1557
|
+
<ExportCSVButton {...props.csvProps}
|
|
1558
|
+
className="btn-warning"
|
|
1559
|
+
style={{ marginLeft: '20px' }}
|
|
1560
|
+
onClick={this.handleExport(props.csvProps.onExport)}
|
|
1561
|
+
>Export CSV</ExportCSVButton>
|
|
1562
|
+
<PaginationListStandalone {...paginationProps} />
|
|
1563
|
+
</div>
|
|
1564
|
+
<BootstrapTable
|
|
1565
|
+
remote
|
|
1566
|
+
striped
|
|
1567
|
+
hover
|
|
1568
|
+
condensed
|
|
1569
|
+
defaultSorted={[
|
|
1570
|
+
{
|
|
1571
|
+
dataField: "name",
|
|
1572
|
+
order: "desc",
|
|
1573
|
+
},
|
|
1574
|
+
]}
|
|
1575
|
+
{...props.baseProps}
|
|
1576
|
+
filter={filterFactory()}
|
|
1577
|
+
overlay={overlayFactory({ spinner: true })}
|
|
1578
|
+
onTableChange={this.handleTableChange}
|
|
1579
|
+
cellEdit={cellEditFactory({
|
|
1580
|
+
mode: "click",
|
|
1581
|
+
})}
|
|
1582
|
+
{...paginationTableProps}
|
|
1583
|
+
/>
|
|
1584
|
+
<div style={{ marginBottom: '20px' }}>
|
|
1585
|
+
<SizePerPageDropdownStandalone {...paginationProps} />
|
|
1586
|
+
<PaginationTotalStandalone {...paginationProps} />
|
|
1587
|
+
<ExportCSVButton {...props.csvProps}
|
|
1588
|
+
className="btn-warning"
|
|
1589
|
+
style={{ marginLeft: '20px' }}
|
|
1590
|
+
onClick={this.handleExport(props.csvProps.onExport)}
|
|
1591
|
+
>Export CSV</ExportCSVButton>
|
|
1592
|
+
<PaginationListStandalone {...paginationProps} />
|
|
1593
|
+
</div>
|
|
1594
|
+
<Code>{remoteAllExportSourceCode}</Code>
|
|
1595
|
+
</div>
|
|
1596
|
+
)}
|
|
1597
|
+
</PaginationProvider>
|
|
1598
|
+
)}
|
|
1599
|
+
</ToolkitProvider>
|
|
1600
|
+
);
|
|
1601
|
+
}
|
|
1602
|
+
}
|
|
1603
|
+
|
|
1135
1604
|
interface RemoteMainProps {
|
|
1136
1605
|
mode?: any;
|
|
1137
1606
|
}
|
|
@@ -1150,5 +1619,7 @@ export default ({ mode }: RemoteMainProps) => {
|
|
|
1150
1619
|
return <RemoteCellEditComponent />;
|
|
1151
1620
|
case "all":
|
|
1152
1621
|
return <RemoteAllComponent />;
|
|
1622
|
+
case "all-custom":
|
|
1623
|
+
return <RemoteAllCustomComponent />;
|
|
1153
1624
|
}
|
|
1154
1625
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import type { Meta, StoryObj } from '@storybook/react-webpack5';
|
|
3
3
|
|
|
4
4
|
// import bootstrap style by given version
|
|
5
5
|
import cellEditFactory from '../../../react-bootstrap-table-ng-editor';
|