@arcblock/ux 2.1.4 → 2.1.7
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/lib/Blocklet/blocklet.js +1 -1
- package/lib/Datatable/CustomToolbar.js +330 -0
- package/lib/Datatable/TableSearch.js +100 -0
- package/lib/Datatable/index.js +185 -0
- package/lib/Datatable/utils.js +154 -0
- package/lib/index.js +8 -0
- package/package.json +5 -4
- package/src/Blocklet/blocklet.js +6 -7
- package/src/Datatable/CustomToolbar.js +371 -0
- package/src/Datatable/TableSearch.js +127 -0
- package/src/Datatable/index.js +145 -0
- package/src/Datatable/utils.js +165 -0
- package/src/index.js +2 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
exports.handleCSVDownload = handleCSVDownload;
|
|
8
|
+
|
|
9
|
+
var _find = _interopRequireDefault(require("lodash/find"));
|
|
10
|
+
|
|
11
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
12
|
+
|
|
13
|
+
function escapeDangerousCSVCharacters(data) {
|
|
14
|
+
if (typeof data === 'string') {
|
|
15
|
+
// Places single quote before the appearance of dangerous characters if they
|
|
16
|
+
// are the first in the data string.
|
|
17
|
+
// eslint-disable-next-line no-useless-escape
|
|
18
|
+
return data.replace(/^\+|^\-|^\=|^\@/g, "'$&");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return data;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function buildCSV(columns, data, options) {
|
|
25
|
+
const replaceDoubleQuoteInString = columnData => typeof columnData === 'string' ? columnData.replace(/"/g, '""') : columnData; // eslint-disable-next-line no-shadow
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
const buildHead = columns => {
|
|
29
|
+
return "".concat(columns.reduce((soFar, column) => column.download ? "".concat(soFar, "\"").concat(escapeDangerousCSVCharacters(replaceDoubleQuoteInString(column.label || column.name)), "\"").concat(options.downloadOptions.separator) : soFar, '').slice(0, -1), "\r\n");
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const CSVHead = buildHead(columns); // eslint-disable-next-line no-shadow
|
|
33
|
+
|
|
34
|
+
const buildBody = data => {
|
|
35
|
+
if (!data.length) return '';
|
|
36
|
+
return data.reduce((soFar, row) => "".concat(soFar, "\"").concat(row.data.filter((_, index) => columns[index].download).map(columnData => escapeDangerousCSVCharacters(replaceDoubleQuoteInString(columnData))).join("\"".concat(options.downloadOptions.separator, "\"")), "\"\r\n"), '').trim();
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const CSVBody = buildBody(data);
|
|
40
|
+
const csv = options.onDownload ? options.onDownload(buildHead, buildBody, columns, data) : "".concat(CSVHead).concat(CSVBody).trim();
|
|
41
|
+
return csv;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function downloadCSV(csv, filename) {
|
|
45
|
+
const blob = new Blob([csv], {
|
|
46
|
+
type: 'text/csv'
|
|
47
|
+
});
|
|
48
|
+
/* taken from react-csv */
|
|
49
|
+
|
|
50
|
+
if (navigator && navigator.msSaveOrOpenBlob) {
|
|
51
|
+
navigator.msSaveOrOpenBlob(blob, filename);
|
|
52
|
+
} else {
|
|
53
|
+
const dataURI = "data:text/csv;charset=utf-8,".concat(csv);
|
|
54
|
+
const URL = window.URL || window.webkitURL;
|
|
55
|
+
const downloadURI = typeof URL.createObjectURL === 'undefined' ? dataURI : URL.createObjectURL(blob);
|
|
56
|
+
const link = document.createElement('a');
|
|
57
|
+
link.setAttribute('href', downloadURI);
|
|
58
|
+
link.setAttribute('download', filename);
|
|
59
|
+
document.body.appendChild(link);
|
|
60
|
+
link.click();
|
|
61
|
+
document.body.removeChild(link);
|
|
62
|
+
}
|
|
63
|
+
} // eslint-disable-next-line no-shadow
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
function createCSVDownload(columns, data, options, downloadCSV) {
|
|
67
|
+
const csv = buildCSV(columns, data, options);
|
|
68
|
+
|
|
69
|
+
if (options.onDownload && csv === false) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
downloadCSV(csv, options.downloadOptions.filename);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function handleCSVDownload(props) {
|
|
77
|
+
const {
|
|
78
|
+
data,
|
|
79
|
+
displayData,
|
|
80
|
+
columns,
|
|
81
|
+
options,
|
|
82
|
+
columnOrder
|
|
83
|
+
} = props;
|
|
84
|
+
let dataToDownload = [];
|
|
85
|
+
let columnsToDownload = [];
|
|
86
|
+
let columnOrderCopy = Array.isArray(columnOrder) ? columnOrder.slice(0) : [];
|
|
87
|
+
|
|
88
|
+
if (columnOrderCopy.length === 0) {
|
|
89
|
+
columnOrderCopy = columns.map((item, idx) => idx);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
data.forEach(row => {
|
|
93
|
+
const newRow = {
|
|
94
|
+
index: row.index,
|
|
95
|
+
data: []
|
|
96
|
+
};
|
|
97
|
+
columnOrderCopy.forEach(idx => {
|
|
98
|
+
newRow.data.push(row.data[idx]);
|
|
99
|
+
});
|
|
100
|
+
dataToDownload.push(newRow);
|
|
101
|
+
});
|
|
102
|
+
columnOrderCopy.forEach(idx => {
|
|
103
|
+
columnsToDownload.push(columns[idx]);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
if (options.downloadOptions && options.downloadOptions.filterOptions) {
|
|
107
|
+
// check rows first:
|
|
108
|
+
if (options.downloadOptions.filterOptions.useDisplayedRowsOnly) {
|
|
109
|
+
const filteredDataToDownload = displayData.map((row, index) => {
|
|
110
|
+
let i = -1; // Help to preserve sort order in custom render columns
|
|
111
|
+
|
|
112
|
+
row.index = index;
|
|
113
|
+
return {
|
|
114
|
+
data: row.data.map(column => {
|
|
115
|
+
i += 1; // if we have a custom render, which will appear as a react element, we must grab the actual value from data
|
|
116
|
+
// that matches the dataIndex and column
|
|
117
|
+
// TODO: Create a utility function for checking whether or not something is a react object
|
|
118
|
+
|
|
119
|
+
let val = typeof column === 'object' && column !== null && !Array.isArray(column) ? (0, _find.default)(data, d => d.index === row.dataIndex).data[i] : column;
|
|
120
|
+
val = typeof val === 'function' ? (0, _find.default)(data, d => d.index === row.dataIndex).data[i] : val;
|
|
121
|
+
return val;
|
|
122
|
+
})
|
|
123
|
+
};
|
|
124
|
+
});
|
|
125
|
+
dataToDownload = [];
|
|
126
|
+
filteredDataToDownload.forEach(row => {
|
|
127
|
+
const newRow = {
|
|
128
|
+
index: row.index,
|
|
129
|
+
data: []
|
|
130
|
+
};
|
|
131
|
+
columnOrderCopy.forEach(idx => {
|
|
132
|
+
newRow.data.push(row.data[idx]);
|
|
133
|
+
});
|
|
134
|
+
dataToDownload.push(newRow);
|
|
135
|
+
});
|
|
136
|
+
} // now, check columns:
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
if (options.downloadOptions.filterOptions.useDisplayedColumnsOnly) {
|
|
140
|
+
columnsToDownload = columnsToDownload.filter(_ => _.display === 'true');
|
|
141
|
+
dataToDownload = dataToDownload.map(row => {
|
|
142
|
+
row.data = row.data.filter((_, index) => columns[columnOrderCopy[index]].display === 'true');
|
|
143
|
+
return row;
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
createCSVDownload(columnsToDownload, dataToDownload, options, downloadCSV);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
var _default = {
|
|
152
|
+
handleCSVDownload
|
|
153
|
+
};
|
|
154
|
+
exports.default = _default;
|
package/lib/index.js
CHANGED
|
@@ -69,6 +69,12 @@ Object.defineProperty(exports, "CountDown", {
|
|
|
69
69
|
return _CountDown.default;
|
|
70
70
|
}
|
|
71
71
|
});
|
|
72
|
+
Object.defineProperty(exports, "Datatable", {
|
|
73
|
+
enumerable: true,
|
|
74
|
+
get: function get() {
|
|
75
|
+
return _Datatable.default;
|
|
76
|
+
}
|
|
77
|
+
});
|
|
72
78
|
Object.defineProperty(exports, "Earth", {
|
|
73
79
|
enumerable: true,
|
|
74
80
|
get: function get() {
|
|
@@ -230,6 +236,8 @@ var _Logo = _interopRequireDefault(require("./Logo"));
|
|
|
230
236
|
|
|
231
237
|
var _RelativeTime = _interopRequireDefault(require("./RelativeTime"));
|
|
232
238
|
|
|
239
|
+
var _Datatable = _interopRequireDefault(require("./Datatable"));
|
|
240
|
+
|
|
233
241
|
var _Tabs = _interopRequireDefault(require("./Tabs"));
|
|
234
242
|
|
|
235
243
|
var _Tag = _interopRequireDefault(require("./Tag"));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arcblock/ux",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.7",
|
|
4
4
|
"description": "Common used react components for arcblock products",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -52,10 +52,10 @@
|
|
|
52
52
|
"react": ">=18.1.0",
|
|
53
53
|
"react-ga": "^2.7.0"
|
|
54
54
|
},
|
|
55
|
-
"gitHead": "
|
|
55
|
+
"gitHead": "a54ef3a9335aae1bc7404b5f4a8c9c508b6ff81f",
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@arcblock/icons": "^2.1.
|
|
58
|
-
"@arcblock/react-hooks": "^2.1.
|
|
57
|
+
"@arcblock/icons": "^2.1.7",
|
|
58
|
+
"@arcblock/react-hooks": "^2.1.7",
|
|
59
59
|
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
|
60
60
|
"@emotion/react": "^11.9.0",
|
|
61
61
|
"@emotion/styled": "^11.8.1",
|
|
@@ -75,6 +75,7 @@
|
|
|
75
75
|
"js-cookie": "^2.2.0",
|
|
76
76
|
"lodash": "^4.17.21",
|
|
77
77
|
"mdi-material-ui": "^7.2.0",
|
|
78
|
+
"mui-datatables": "^4.2.2",
|
|
78
79
|
"notistack": "^2.0.5",
|
|
79
80
|
"react-cookie-consent": "^6.4.1",
|
|
80
81
|
"react-helmet": "^6.1.0",
|
package/src/Blocklet/blocklet.js
CHANGED
|
@@ -12,7 +12,8 @@ import Img from '../Img';
|
|
|
12
12
|
|
|
13
13
|
const Div = styled.div`
|
|
14
14
|
&.arcblock-blocklet {
|
|
15
|
-
padding:
|
|
15
|
+
padding: ${props => props.theme.spacing(2)} ${props => props.theme.spacing(2)} 0
|
|
16
|
+
${props => props.theme.spacing(2)};
|
|
16
17
|
}
|
|
17
18
|
.arcblock-blocklet__content {
|
|
18
19
|
cursor: pointer;
|
|
@@ -24,7 +25,7 @@ const Div = styled.div`
|
|
|
24
25
|
.arcblock-blocklet__cover {
|
|
25
26
|
width: 64px;
|
|
26
27
|
height: 64px;
|
|
27
|
-
margin-right:
|
|
28
|
+
margin-right: ${props => props.theme.spacing(2)};
|
|
28
29
|
overflow: hidden;
|
|
29
30
|
border-radius: 12px;
|
|
30
31
|
/* see: https://stackoverflow.com/questions/49066011/overflow-hidden-with-border-radius-not-working-on-safari */
|
|
@@ -83,7 +84,7 @@ const Div = styled.div`
|
|
|
83
84
|
flex: 1;
|
|
84
85
|
overflow: hidden;
|
|
85
86
|
border-bottom: 1px solid ${props => props.theme.palette.divider};
|
|
86
|
-
padding-bottom:
|
|
87
|
+
padding-bottom: ${props => props.theme.spacing(2)};
|
|
87
88
|
}
|
|
88
89
|
.arcblock-blocklet__text {
|
|
89
90
|
height: 57px;
|
|
@@ -94,14 +95,12 @@ const Div = styled.div`
|
|
|
94
95
|
margin: 0;
|
|
95
96
|
font-size: 16px;
|
|
96
97
|
font-weight: 500;
|
|
97
|
-
line-height: 19px;
|
|
98
|
-
max-height: 19px;
|
|
99
98
|
overflow: hidden;
|
|
100
99
|
text-overflow: ellipsis;
|
|
101
100
|
white-space: nowrap;
|
|
102
101
|
}
|
|
103
102
|
.arcblock-blocklet__describe {
|
|
104
|
-
margin-top:
|
|
103
|
+
margin-top: ${props => props.theme.spacing(0.5)};
|
|
105
104
|
color: ${props => props.theme.palette.grey[600]};
|
|
106
105
|
font-size: 14px;
|
|
107
106
|
font-weight: 500;
|
|
@@ -112,7 +111,7 @@ const Div = styled.div`
|
|
|
112
111
|
display: -webkit-box;
|
|
113
112
|
-webkit-line-clamp: 2;
|
|
114
113
|
-webkit-box-orient: vertical;
|
|
115
|
-
word-break: break-
|
|
114
|
+
word-break: break-word;
|
|
116
115
|
}
|
|
117
116
|
.arcblock-blocklet__version {
|
|
118
117
|
color: ${props => props.theme.palette.grey[600]};
|
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
import React, { useState, useRef, isValidElement } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { TableFilter, TableViewCol } from 'mui-datatables';
|
|
4
|
+
import styled from 'styled-components';
|
|
5
|
+
import ReactToPrint, { PrintContextConsumer } from 'react-to-print';
|
|
6
|
+
import IconButton from '@mui/material/IconButton';
|
|
7
|
+
import Tooltip from '@mui/material/Tooltip';
|
|
8
|
+
import DownloadIcon from '@mui/icons-material/CloudDownload';
|
|
9
|
+
import PrintIcon from '@mui/icons-material/Print';
|
|
10
|
+
import ViewColumnIcon from '@mui/icons-material/ViewColumn';
|
|
11
|
+
import FilterIcon from '@mui/icons-material/FilterList';
|
|
12
|
+
import Popover from '@mui/material/Popover';
|
|
13
|
+
import MoreVertIcon from '@mui/icons-material/MoreVert';
|
|
14
|
+
import Menu from '@mui/material/Menu';
|
|
15
|
+
import MenuItem from '@mui/material/MenuItem';
|
|
16
|
+
import ListItemIcon from '@mui/material/ListItemIcon';
|
|
17
|
+
import ListItemText from '@mui/material/ListItemText';
|
|
18
|
+
import useMediaQuery from '@mui/material/useMediaQuery';
|
|
19
|
+
import { useTheme } from '@mui/material/styles';
|
|
20
|
+
import { handleCSVDownload } from './utils';
|
|
21
|
+
import TableSearch from './TableSearch';
|
|
22
|
+
|
|
23
|
+
function useMobile() {
|
|
24
|
+
const theme = useTheme();
|
|
25
|
+
return useMediaQuery(theme.breakpoints.down('sm'));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export default function CustomToolbar(props) {
|
|
29
|
+
const [menuIconEl, setMenuIconEl] = useState(null);
|
|
30
|
+
const moreBtn = useRef(null);
|
|
31
|
+
const isMobile = useMobile();
|
|
32
|
+
const toolbarId = useRef(Math.random().toString(32).slice(2));
|
|
33
|
+
|
|
34
|
+
const {
|
|
35
|
+
data,
|
|
36
|
+
options,
|
|
37
|
+
components,
|
|
38
|
+
columns,
|
|
39
|
+
filterList,
|
|
40
|
+
filterData,
|
|
41
|
+
filterUpdate,
|
|
42
|
+
resetFilters,
|
|
43
|
+
updateFilterByType,
|
|
44
|
+
toggleViewColumn,
|
|
45
|
+
updateColumns,
|
|
46
|
+
title,
|
|
47
|
+
searchText,
|
|
48
|
+
searchTextUpdate,
|
|
49
|
+
searchClose,
|
|
50
|
+
customButtons,
|
|
51
|
+
} = props;
|
|
52
|
+
|
|
53
|
+
const { search, downloadCsv, print, viewColumns, filterTable } = options.textLabels.toolbar;
|
|
54
|
+
|
|
55
|
+
const hideSearch = options.search === false || options.search === 'false';
|
|
56
|
+
const hidePrint = options.print === false || options.print === 'false';
|
|
57
|
+
|
|
58
|
+
const TableFilterComponent = components.TableFilter || TableFilter;
|
|
59
|
+
const TableViewColComponent = components.TableViewCol || TableViewCol;
|
|
60
|
+
|
|
61
|
+
const printArea = func => {
|
|
62
|
+
return (
|
|
63
|
+
<ReactToPrint content={() => props.tableRef()}>
|
|
64
|
+
<PrintContextConsumer>{func}</PrintContextConsumer>
|
|
65
|
+
</ReactToPrint>
|
|
66
|
+
);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const getPopId = key => `toolbar-pop-${toolbarId.current}-${key}`;
|
|
70
|
+
|
|
71
|
+
const defaultButtons = [];
|
|
72
|
+
|
|
73
|
+
if (!(options.download === false || options.download === 'false')) {
|
|
74
|
+
defaultButtons.push({
|
|
75
|
+
Icon: DownloadIcon,
|
|
76
|
+
title: downloadCsv,
|
|
77
|
+
onClick: () => {
|
|
78
|
+
handleCSVDownload(props);
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (!(options.viewColumns === false || options.viewColumns === 'false')) {
|
|
84
|
+
defaultButtons.push({
|
|
85
|
+
Icon: ViewColumnIcon,
|
|
86
|
+
title: viewColumns,
|
|
87
|
+
popRender() {
|
|
88
|
+
return (
|
|
89
|
+
<TableViewColComponent
|
|
90
|
+
data={data}
|
|
91
|
+
columns={columns}
|
|
92
|
+
options={options}
|
|
93
|
+
onColumnUpdate={toggleViewColumn}
|
|
94
|
+
updateColumns={updateColumns}
|
|
95
|
+
components={components}
|
|
96
|
+
/>
|
|
97
|
+
);
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (!(options.filter === false || options.filter === 'false')) {
|
|
103
|
+
defaultButtons.push({
|
|
104
|
+
Icon: FilterIcon,
|
|
105
|
+
title: filterTable,
|
|
106
|
+
popRender() {
|
|
107
|
+
return (
|
|
108
|
+
<TableFilterComponent
|
|
109
|
+
customFooter={options.customFilterDialogFooter}
|
|
110
|
+
columns={columns}
|
|
111
|
+
options={options}
|
|
112
|
+
filterList={filterList}
|
|
113
|
+
filterData={filterData}
|
|
114
|
+
onFilterUpdate={filterUpdate}
|
|
115
|
+
onFilterReset={resetFilters}
|
|
116
|
+
updateFilterByType={updateFilterByType}
|
|
117
|
+
components={components}
|
|
118
|
+
/>
|
|
119
|
+
);
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const showMore =
|
|
125
|
+
[!hidePrint, ...defaultButtons, ...customButtons].filter(e => !!e).length > 1 && isMobile;
|
|
126
|
+
|
|
127
|
+
const allPops = [];
|
|
128
|
+
const [allPopsEl, setAllPopsEl] = useState({});
|
|
129
|
+
|
|
130
|
+
const toolbarButtons = [...defaultButtons, ...customButtons].map((e, index) => {
|
|
131
|
+
if (isValidElement(e)) {
|
|
132
|
+
return e;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const popId = getPopId(index);
|
|
136
|
+
|
|
137
|
+
if (e.Icon) {
|
|
138
|
+
const { Icon, popRender } = e;
|
|
139
|
+
if (popRender) {
|
|
140
|
+
allPops.push(
|
|
141
|
+
<Popover
|
|
142
|
+
open={!!allPopsEl[popId]}
|
|
143
|
+
anchorEl={() => allPopsEl[popId]}
|
|
144
|
+
onClose={() => {
|
|
145
|
+
setAllPopsEl({});
|
|
146
|
+
}}
|
|
147
|
+
key={popId}
|
|
148
|
+
anchorOrigin={{
|
|
149
|
+
vertical: 'bottom',
|
|
150
|
+
horizontal: 'right',
|
|
151
|
+
}}>
|
|
152
|
+
<div>{popRender()}</div>
|
|
153
|
+
</Popover>
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return (
|
|
158
|
+
<Tooltip title={e.title} key={popId}>
|
|
159
|
+
<IconButton
|
|
160
|
+
data-testid={`${e.title}-iconButton`}
|
|
161
|
+
id={`btn-${popId}`}
|
|
162
|
+
aria-label={e.title}
|
|
163
|
+
onClick={() => {
|
|
164
|
+
if (e.onClick) {
|
|
165
|
+
e.onClick();
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (popRender) {
|
|
169
|
+
setAllPopsEl({
|
|
170
|
+
[popId]: document.getElementById(`btn-${popId}`),
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}}>
|
|
174
|
+
<Icon />
|
|
175
|
+
</IconButton>
|
|
176
|
+
</Tooltip>
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return e;
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
const menuItems = [...defaultButtons, ...customButtons].map((e, index) => {
|
|
184
|
+
const popId = getPopId(index);
|
|
185
|
+
|
|
186
|
+
let content;
|
|
187
|
+
|
|
188
|
+
if (isValidElement(e)) {
|
|
189
|
+
content = e;
|
|
190
|
+
} else if (e.Icon) {
|
|
191
|
+
const { Icon } = e;
|
|
192
|
+
|
|
193
|
+
content = (
|
|
194
|
+
<>
|
|
195
|
+
<ListItemIcon>
|
|
196
|
+
<Icon fontSize="small" />
|
|
197
|
+
</ListItemIcon>
|
|
198
|
+
<ListItemText>{e.title}</ListItemText>
|
|
199
|
+
</>
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return (
|
|
204
|
+
<MenuItem
|
|
205
|
+
key={popId}
|
|
206
|
+
onClick={() => {
|
|
207
|
+
setMenuIconEl(null);
|
|
208
|
+
if (e.onClick) {
|
|
209
|
+
e.onClick();
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (e.popRender) {
|
|
213
|
+
setAllPopsEl({
|
|
214
|
+
[popId]: moreBtn.current,
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
}}>
|
|
218
|
+
{content}
|
|
219
|
+
</MenuItem>
|
|
220
|
+
);
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
return (
|
|
224
|
+
<div>
|
|
225
|
+
<Container>
|
|
226
|
+
<div className="custom-toobar-title">
|
|
227
|
+
<div className="custom-toobar-title-inner">
|
|
228
|
+
<span>{title}</span>
|
|
229
|
+
</div>
|
|
230
|
+
</div>
|
|
231
|
+
<div className="custom-toobar-right">
|
|
232
|
+
<div className="custom-toobar-btns">
|
|
233
|
+
{!hideSearch && (
|
|
234
|
+
<TableSearch
|
|
235
|
+
search={search}
|
|
236
|
+
options={options}
|
|
237
|
+
searchText={searchText}
|
|
238
|
+
searchTextUpdate={searchTextUpdate}
|
|
239
|
+
searchClose={searchClose}
|
|
240
|
+
isMobile={isMobile}
|
|
241
|
+
/>
|
|
242
|
+
)}
|
|
243
|
+
{!showMore && (
|
|
244
|
+
<>
|
|
245
|
+
{!hidePrint &&
|
|
246
|
+
printArea(({ handlePrint }) => (
|
|
247
|
+
<span>
|
|
248
|
+
<Tooltip title={print}>
|
|
249
|
+
<IconButton
|
|
250
|
+
data-testid={`${print}-iconButton`}
|
|
251
|
+
aria-label={print}
|
|
252
|
+
disabled={options.print === 'disabled'}
|
|
253
|
+
onClick={handlePrint}>
|
|
254
|
+
<PrintIcon />
|
|
255
|
+
</IconButton>
|
|
256
|
+
</Tooltip>
|
|
257
|
+
</span>
|
|
258
|
+
))}
|
|
259
|
+
|
|
260
|
+
{toolbarButtons}
|
|
261
|
+
</>
|
|
262
|
+
)}
|
|
263
|
+
{showMore && (
|
|
264
|
+
<IconButton
|
|
265
|
+
ref={moreBtn}
|
|
266
|
+
aria-haspopup="true"
|
|
267
|
+
aria-expanded={menuIconEl ? 'true' : undefined}
|
|
268
|
+
onClick={event => setMenuIconEl(event.currentTarget)}>
|
|
269
|
+
<MoreVertIcon />
|
|
270
|
+
</IconButton>
|
|
271
|
+
)}
|
|
272
|
+
</div>
|
|
273
|
+
</div>
|
|
274
|
+
</Container>
|
|
275
|
+
|
|
276
|
+
<Menu
|
|
277
|
+
anchorEl={menuIconEl}
|
|
278
|
+
open={!!menuIconEl}
|
|
279
|
+
onClose={() => setMenuIconEl(null)}
|
|
280
|
+
MenuListProps={{
|
|
281
|
+
'aria-labelledby': 'more-button',
|
|
282
|
+
}}>
|
|
283
|
+
{!hidePrint &&
|
|
284
|
+
printArea(({ handlePrint }) => (
|
|
285
|
+
<MenuItem
|
|
286
|
+
onClick={() => {
|
|
287
|
+
setMenuIconEl(null);
|
|
288
|
+
handlePrint();
|
|
289
|
+
}}>
|
|
290
|
+
<ListItemIcon>
|
|
291
|
+
<PrintIcon fontSize="small" />
|
|
292
|
+
</ListItemIcon>
|
|
293
|
+
<ListItemText>{print}</ListItemText>
|
|
294
|
+
</MenuItem>
|
|
295
|
+
))}
|
|
296
|
+
{menuItems}
|
|
297
|
+
</Menu>
|
|
298
|
+
{allPops.map((e, index) => (
|
|
299
|
+
<div key={getPopId(index)}>{e}</div>
|
|
300
|
+
))}
|
|
301
|
+
</div>
|
|
302
|
+
);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
CustomToolbar.propTypes = {
|
|
306
|
+
data: PropTypes.array,
|
|
307
|
+
options: PropTypes.object.isRequired,
|
|
308
|
+
components: PropTypes.object,
|
|
309
|
+
columns: PropTypes.array.isRequired,
|
|
310
|
+
filterList: PropTypes.array,
|
|
311
|
+
filterData: PropTypes.array,
|
|
312
|
+
filterUpdate: PropTypes.func.isRequired,
|
|
313
|
+
resetFilters: PropTypes.func.isRequired,
|
|
314
|
+
updateFilterByType: PropTypes.func.isRequired,
|
|
315
|
+
toggleViewColumn: PropTypes.func.isRequired,
|
|
316
|
+
updateColumns: PropTypes.func.isRequired,
|
|
317
|
+
title: PropTypes.string,
|
|
318
|
+
searchText: PropTypes.any,
|
|
319
|
+
searchTextUpdate: PropTypes.func.isRequired,
|
|
320
|
+
searchClose: PropTypes.func.isRequired,
|
|
321
|
+
tableRef: PropTypes.func.isRequired,
|
|
322
|
+
customButtons: PropTypes.array.isRequired,
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
CustomToolbar.defaultProps = {
|
|
326
|
+
data: [],
|
|
327
|
+
components: {},
|
|
328
|
+
filterList: [],
|
|
329
|
+
filterData: [],
|
|
330
|
+
title: '',
|
|
331
|
+
searchText: null,
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
const Container = styled.div`
|
|
335
|
+
display: flex;
|
|
336
|
+
align-items: center;
|
|
337
|
+
height: 56px;
|
|
338
|
+
.custom-toobar {
|
|
339
|
+
&-title {
|
|
340
|
+
position: relative;
|
|
341
|
+
flex: 1;
|
|
342
|
+
font-size: 18px;
|
|
343
|
+
font-weight: 800;
|
|
344
|
+
height: 56px;
|
|
345
|
+
&-inner {
|
|
346
|
+
line-height: 56px;
|
|
347
|
+
width: 100%;
|
|
348
|
+
height: 56px;
|
|
349
|
+
position: absolute;
|
|
350
|
+
left: 0;
|
|
351
|
+
top: 0;
|
|
352
|
+
span {
|
|
353
|
+
display: inline-block;
|
|
354
|
+
max-width: 100%;
|
|
355
|
+
white-space: nowrap;
|
|
356
|
+
text-overflow: ellipsis;
|
|
357
|
+
overflow: hidden;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
&-right {
|
|
362
|
+
display: flex;
|
|
363
|
+
margin-left: auto;
|
|
364
|
+
}
|
|
365
|
+
&-btns {
|
|
366
|
+
display: flex;
|
|
367
|
+
justify-content: center;
|
|
368
|
+
align-items: center;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
`;
|