feat: add grid all columns search

This commit is contained in:
Vladimir Iliev 2020-04-27 17:47:12 +03:00
Родитель 2203cc4a82
Коммит 9d99df0457
3 изменённых файлов: 122 добавлений и 12 удалений

Просмотреть файл

@ -19,6 +19,8 @@
"@progress/kendo-react-inputs": "^3.13.0-dev.202004240541",
"@progress/kendo-react-intl": "^3.13.0-dev.202004240541",
"@progress/kendo-react-layout": "^3.13.0-dev.202004240541",
"@progress/kendo-react-pdf": "^3.13.0-dev.202004240541",
"@progress/kendo-react-excel-export": "^3.13.0-dev.202004240541",
"@progress/kendo-react-scheduler": "^3.12.0",
"@progress/kendo-react-upload": "^3.13.0-dev.202004240541",
"@progress/kendo-theme-default": "^4.17.0",

Просмотреть файл

@ -2,8 +2,12 @@
import React from 'react';
import * as PropTypes from 'prop-types';
import { Grid as KendoGrid, GridColumn, GridColumnMenuSort, GridColumnMenuFilter } from '@progress/kendo-react-grid';
import { Grid as KendoGrid, GridColumn, GridColumnMenuSort, GridColumnMenuFilter, GridToolbar } from '@progress/kendo-react-grid';
import { Button } from '@progress/kendo-react-buttons'
import { GridPDFExport } from '@progress/kendo-react-pdf';
import { ExcelExport } from '@progress/kendo-react-excel-export';
import { process } from '@progress/kendo-data-query';
import { Input } from '@progress/kendo-react-inputs';
export const Column = GridColumn;
@ -19,29 +23,107 @@ export const ColumnMenu = (props) => {
export const Grid = (props) => {
const { data, onDataChange, ...others } = props;
const excelExportRef = React.useRef(null);
const pdfExportRef = React.useRef(null);
const [isPdfExporting, setIsPdfExporting] = React.useState(false);
const [take, setTake] = React.useState(10);
const [skip, setSkip] = React.useState(0);
const [sort, setSort] = React.useState([]);
const [group, setGroup] = React.useState([]);
const [filter, setFilter] = React.useState(null);
const lastSelectedIndexRef = React.useRef(0);
const [allColumnFilter, setAllColumnFilter] = React.useState('');
const dataState = {
take,
skip,
sort,
group
group,
filter
};
const textColumns = props.children.map(col => {
if (col.props.children) {
return col.props.children.map(child => {
if (!child.props.filter || child.props.filter === "text") {
return child.props.field;
}
});
} else if (col.props.field) {
if (!col.props.filter || col.props.filter === "text") {
return col.props.field;
}
}
})
.flat()
.filter(field => field);
const allColumnsFilters = textColumns.map(column => ({
field: column,
operator: 'contains',
value: allColumnFilter
}));
const allColumnFilteredData = allColumnFilter ?
process(data, {filter: { logic: "or", filters: allColumnsFilters }}).data :
data;
const processedData = process(allColumnFilteredData, dataState);
React.useEffect(
() => {
if (!processedData.data.length) {
setSkip(0);
}
},
[processedData]
)
const onDataStateChange = React.useCallback(
(event) => {
setTake(event.data.take);
setSkip(event.data.skip);
setSort(event.data.sort);
setGroup(event.data.group)
setGroup(event.data.group);
setFilter(event.data.filter);
},
[setTake, setSkip, setSort, setGroup]
);
const onExcelExport = React.useCallback(
() => {
if (excelExportRef.current) {
excelExportRef.current.save();
}
},
[]
);
const onPdfExportDone = React.useCallback(
() => {
setIsPdfExporting(false);
},
[]
);
const onAllColumnFilterChange = React.useCallback(
(event) => {
setAllColumnFilter(event.value);
},
[setAllColumnFilter]
);
const onPdfExport = React.useCallback(
() => {
if (pdfExportRef.current) {
setIsPdfExporting(true);
pdfExportRef.current.save(processedData.data, onPdfExportDone);
}
},
[processedData, onPdfExportDone]
);
const onSelectionChange = React.useCallback(
(event) => {
let last = lastSelectedIndexRef.current;
@ -82,7 +164,7 @@ export const Grid = (props) => {
[data, onDataChange]
);
return (
const GridElement = (
<KendoGrid
{...dataState}
{...others}
@ -92,12 +174,26 @@ export const Grid = (props) => {
groupable
selectedField={'selected'}
data={process(data, dataState)}
data={processedData}
onDataStateChange={onDataStateChange}
onSelectionChange={onSelectionChange}
onHeaderSelectionChange={onHeaderSelectionChange}
>
<GridToolbar>
<Input value={allColumnFilter} onChange={onAllColumnFilterChange} placeholder={'Search in all columns...'} />
<Button
onClick={onExcelExport}
>
Export to Excel
</Button>
<Button
onClick={onPdfExport}
disabled={isPdfExporting}
>
Export PDF
</Button>
</GridToolbar>
<Column
field={'selected'}
width={50}
@ -109,6 +205,18 @@ export const Grid = (props) => {
{props.children}
</KendoGrid>
);
return (
<>
<ExcelExport data={processedData.data} ref={excelExportRef}>
{ GridElement }
</ExcelExport>
<GridPDFExport ref={pdfExportRef}>
{ GridElement }
</GridPDFExport>
</>
);
};
Grid.displayName = 'Grid';

Просмотреть файл

@ -107,18 +107,18 @@ const Dashboard = () => {
<span></span>
<div className="card-component">
<Grid data={filterBy(data, gridFilterExpression)} style={{ height: 480, maxWidth: window.innerWidth - 20 }} onDataChange={data => setData(data)}>
<Column title={localizationService.toLanguageString('custom.employee')}>
<Column title={localizationService.toLanguageString('custom.employee')} groupable={false}>
<Column field={'fullName'} title={localizationService.toLanguageString('custom.contactName')} columnMenu={ColumnMenu} width={230} cell={FullNameCell} />
<Column field={'jobTitle'} title={localizationService.toLanguageString('custom.jobTitle')} columnMenu={ColumnMenu} width={230} />
<Column field={'country'} title={localizationService.toLanguageString('custom.country')} columnMenu={ColumnMenu} width={100} cell={FlagCell} />
<Column field={'isOnline'} title={localizationService.toLanguageString('custom.status')} columnMenu={ColumnMenu} width={100} cell={OnlineCell} />
<Column field={'isOnline'} title={localizationService.toLanguageString('custom.status')} columnMenu={ColumnMenu} width={100} cell={OnlineCell} filter={'boolean'} />
</Column>
<Column title={localizationService.toLanguageString('custom.performance')}>
<Column field={'rating'} title={localizationService.toLanguageString('custom.rating')} columnMenu={ColumnMenu} width={110} cell={RatingCell} />
<Column field={'target'} title={localizationService.toLanguageString('custom.engagement')} columnMenu={ColumnMenu} width={200} cell={EngagementCell} />
<Column field={'budget'} title={localizationService.toLanguageString('custom.budget')} columnMenu={ColumnMenu} width={100} cell={CurrencyCell} />
<Column title={localizationService.toLanguageString('custom.performance')} groupable={false}>
<Column field={'rating'} title={localizationService.toLanguageString('custom.rating')} columnMenu={ColumnMenu} width={110} cell={RatingCell} filter={'numeric'} />
<Column field={'target'} title={localizationService.toLanguageString('custom.engagement')} columnMenu={ColumnMenu} width={200} cell={EngagementCell} filter={'numeric'} />
<Column field={'budget'} title={localizationService.toLanguageString('custom.budget')} columnMenu={ColumnMenu} width={100} cell={CurrencyCell} filter={'numeric'} />
</Column>
<Column title={localizationService.toLanguageString('custom.contacts')}>
<Column title={localizationService.toLanguageString('custom.contacts')} groupable={false}>
<Column field={'phone'} title={localizationService.toLanguageString('custom.phone')} columnMenu={ColumnMenu} width={130} />
<Column field={'address'} title={localizationService.toLanguageString('custom.address')} columnMenu={ColumnMenu} width={200} />
</Column>