Skip to content

Commit 086d211

Browse files
author
flexicious
committed
Added Lazy load hierarchical example
Added Sql builder example Bumped latest grid versions.
1 parent 3faa14e commit 086d211

44 files changed

Lines changed: 1400 additions & 251 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/graphql-apollo-react/components/RestaurantsDataGrid.tsx

Lines changed: 40 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,90 +1,81 @@
11
import { createColumn, FilterOperation, FilterPageSortArguments, FilterPageSortChangeReason, FilterPageSortLoadMode, ServerInfo } from "@euxdt/grid-core";
22
import { createMultiSelectFilterOptions, createNumericRangeFilterOptions, createTextInputFilterOptions } from "@euxdt/grid-react";
3-
import { useEffect, useMemo, useReducer, useState } from "react";
3+
import { useEffect, useMemo, useState } from "react";
44
import { client } from "../graphql/client/apollo-client";
55
import { BusinessQuery } from "../graphql/client/queries/business";
66
import { DataGrid } from "./DataGrid";
77

88

99
export const RestaurantsDataGrid = () => {
1010
const [loading, setLoading] = useState<boolean>(true);
11-
const [filterPageSortArgs, setFilterPageSortArgs] = useState<FilterPageSortArguments>();
12-
const [serverInfo, dispatch] = useReducer( (state: ServerInfo, action: { type: "SET_SERVER_INFO";
13-
payload: Partial<ServerInfo>;
14-
}): ServerInfo => {
15-
switch (action.type) {
16-
case "SET_SERVER_INFO":
17-
return { ...state, ...action.payload };
18-
default:
19-
return state;
20-
}
21-
}, {});
11+
const [request, setRequest] = useState<FilterPageSortArguments>();
12+
const [response, setResponse] = useState<ServerInfo>({});
2213

2314
const uniqueIdentifierOptions = useMemo(() => ({
2415
useField: "business_id",
2516
}), []);
26-
const filterValueColumns = useMemo(() => ["name", "city"], []);
27-
const footerValueColumns = useMemo(() => ["inspection_count", "violation_count"], []);
17+
const initialLoadDistinctValueColumns = useMemo(() => ["name", "city","TaxCode"], []);
2818
useEffect(() => {
29-
setFilterPageSortArgs({
30-
distinctValueColumns: filterValueColumns,
31-
footerValueColumns,
19+
//Initial load
20+
setRequest({
21+
distinctValueColumns: initialLoadDistinctValueColumns,
3222
filter: { children: [] },
3323
pagination: { pageSize: 100, currentPage: 1 },
24+
reason: FilterPageSortChangeReason.InitialLoad,
3425
});
35-
}, [filterValueColumns, footerValueColumns]);
26+
}, [initialLoadDistinctValueColumns]);
3627
useEffect(() => {
37-
if (!filterPageSortArgs) return;
28+
if (!request) return;
3829
const getServerData = async (filterPageSortArgs: FilterPageSortArguments) => {
39-
const { pagination } = filterPageSortArgs;
4030
setLoading(true);
4131
const response = await client.query({
4232
query: BusinessQuery,
4333
variables: {
4434
args: filterPageSortArgs,
4535
},
36+
})
37+
const result = response.data.businesses;
38+
const newResponse = {...result};
39+
setResponse(s=>{
40+
//Merge the new response with the old response.
41+
if (Object.keys(result.filterDistinctValues || {}).length > 0) {
42+
newResponse.filterDistinctValues = { ...s.filterDistinctValues, ...result.filterDistinctValues };
43+
} else {
44+
delete newResponse.filterDistinctValues;
45+
}
46+
return {
47+
...s,
48+
...newResponse,
49+
pagination: {
50+
...s.pagination,
51+
...newResponse.pagination,
52+
},
53+
};
4654
});
47-
const newServerInfo: ServerInfo = {
48-
currentPageData: response.data.businesses.rows,
49-
pagination: {
50-
currentPage: pagination?.currentPage || 1,
51-
pageSize: pagination?.pageSize || 100,
52-
totalRecords: response.data.businesses.count || 0,
53-
totalPages: Math.ceil(response.data.businesses.count / (pagination?.pageSize || 100)),
54-
},
55-
};
56-
if(Object.keys(response.data.businesses.filterDistinctValues || {}).length > 0) {
57-
newServerInfo.filterDistinctValues = response.data.businesses.filterDistinctValues;
58-
}
59-
if(Object.keys(response.data.businesses.footerValues || {}).length > 0) {
60-
newServerInfo.footerValues = response.data.businesses.footerValues;
61-
}
62-
dispatch({ type: "SET_SERVER_INFO", payload: newServerInfo });
63-
6455
setLoading(false);
6556
};
66-
getServerData(filterPageSortArgs);
67-
}, [filterPageSortArgs]);
57+
getServerData(request);
58+
}, [request]);
6859

6960

7061
return (
7162
<DataGrid style={{height:"100%", }}
7263
gridOptions={{
73-
dataProvider: serverInfo?.currentPageData,
64+
dataProvider: response?.currentPageData,
7465
filterPageSortMode: FilterPageSortLoadMode.Server,
7566
enablePaging: true,
76-
serverInfo,
67+
serverInfo: response,
7768
toolbarOptions: {
7869
enableGlobalSearch: false,
7970
enableExcel:true,
8071
enablePdf:true,
8172
},
8273
eventBus: {
8374
onFilterPageSortChanged: (args: FilterPageSortArguments, reason: FilterPageSortChangeReason) => {
84-
setFilterPageSortArgs({
75+
setRequest({
8576
...args,
86-
distinctValueColumns: [],//don't need distinct values on subsequent calls, footers only need to be updated on filter change
87-
footerValueColumns: reason === FilterPageSortChangeReason.FilterChanged ? footerValueColumns : [],
77+
reason,
78+
distinctValueColumns: [],//don't need distinct values on subsequent calls
8879
});
8980
},
9081
onExportPageRequested: async(args) => {
@@ -94,7 +85,7 @@ export const RestaurantsDataGrid = () => {
9485
args,
9586
},
9687
});
97-
return response.data.businesses.rows;
88+
return response.data.businesses.currentPageData;
9889
},
9990
},
10091
isLoading: loading,
@@ -111,6 +102,10 @@ export const RestaurantsDataGrid = () => {
111102
...createColumn("name", "string", "Name"),
112103
filterOptions: createMultiSelectFilterOptions()
113104
},
105+
{
106+
...createColumn("TaxCode", "string", "Tax Code"),
107+
filterOptions: createMultiSelectFilterOptions()
108+
},
114109
{
115110
...createColumn("inspection_count", "number", "Inspection Count"),
116111
width: 100,
@@ -145,10 +140,6 @@ export const RestaurantsDataGrid = () => {
145140
...createColumn("longitude", "number", "Longitude"),
146141
filterOptions: createNumericRangeFilterOptions(),
147142
},
148-
{
149-
...createColumn("TaxCode", "string", "Tax Code"),
150-
filterOptions: createTextInputFilterOptions(FilterOperation.Wildcard),
151-
},
152143
{
153144
...createColumn("business_certificate", "number", "Business_certificate"),
154145
filterOptions: createNumericRangeFilterOptions(),

apps/graphql-apollo-react/graphql/client/queries/business.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { gql } from 'apollo-server-micro';
22

33
export const BusinessQuery = gql`query Query($args: FilterPageSortArguments) {
44
businesses(args: $args) {
5-
rows {
5+
currentPageData {
66
business_id
77
name
88
address
@@ -23,10 +23,14 @@ export const BusinessQuery = gql`query Query($args: FilterPageSortArguments) {
2323
violation_count
2424
2525
}
26-
26+
pagination {
27+
totalRecords
28+
pageSize
29+
currentPage
30+
totalPages
31+
}
2732
footerValues
2833
filterDistinctValues
29-
count
3034
}
3135
}
3236
`;

apps/graphql-apollo-react/graphql/resolvers/business.ts

Lines changed: 48 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,65 @@
1-
import { FilterPageSortArguments,ServerResponse,NameValue } from '@euxdt/grid-core';
2-
import { buildWhereClause, getRowsFromSqlite } from 'apps/graphql-apollo-react/shared/sql-builder';
1+
import { buildSqlWhereClause, FilterPageSortArguments, FilterPageSortChangeReason, NameValue, ServerInfo } from '@euxdt/grid-core';
2+
import { getRowsFromSqlite } from '@euxdt/grid-shared';
33
import { Business } from 'apps/graphql-apollo-react/shared/types';
4+
const sqlite3 = require('sqlite3').verbose();
5+
const getDb = () => new sqlite3.Database('dbs/sf-restaurants.db');
46
export const BusinessResolver = {
57
Query: {
68
businesses: async (
79
_,
810
{ args }: { args: FilterPageSortArguments },
9-
) : Promise<ServerResponse<Business>> => {
10-
const { filter, distinctValueColumns, footerValueColumns } = args;
11+
): Promise<ServerInfo> => {
12+
const { filter, distinctValueColumns, pagination, reason } = args;
1113
const params = [];
1214
const noPagingParams = [];
13-
const noPagingWhereClause = buildWhereClause( {filter}, noPagingParams, false );
15+
const noPagingWhereClause = buildSqlWhereClause({ filter }, noPagingParams, false);
16+
const footerValueColumns = ["inspection_count", "violation_count"];
1417
const countSelect = `select count(*) as count from businesses ${noPagingWhereClause}`;
15-
const count = await getRowsFromSqlite(countSelect, params)
16-
const businessQuery = buildWhereClause(args,params);
17-
console.log(businessQuery);
18-
const businessSelect = `select businesses.*,
19-
(select count(*) from inspections where inspections.business_id = businesses.business_id) as inspection_count,
20-
(select count(*) from violations where violations.business_id = businesses.business_id) as violation_count
21-
from businesses ${businessQuery}`;
22-
const businesses = await getRowsFromSqlite<Business>(businessSelect,params);
18+
const response: ServerInfo = {};
19+
if (reason === FilterPageSortChangeReason.InitialLoad || reason === FilterPageSortChangeReason.FilterChanged) {
20+
const count = await getRowsFromSqlite(getDb(), countSelect, params)
21+
const totalRecords = (count[0] as any).count;
22+
response.pagination = {
23+
...pagination,
24+
totalRecords,
25+
totalPages: Math.ceil(totalRecords / pagination.pageSize || 100),
26+
}
27+
}
28+
if (reason === FilterPageSortChangeReason.InitialLoad || reason === FilterPageSortChangeReason.FilterChanged || reason === FilterPageSortChangeReason.SortChanged
29+
|| reason === FilterPageSortChangeReason.PageChanged || !reason) {
30+
const businessQuery = buildSqlWhereClause(args, params);
31+
console.log(businessQuery);
32+
const businessSelect = `select businesses.*,
33+
(select count(*) from inspections where inspections.business_id = businesses.business_id) as inspection_count,
34+
(select count(*) from violations where violations.business_id = businesses.business_id) as violation_count
35+
from businesses ${businessQuery}`;
36+
const businesses = await getRowsFromSqlite<Business>(getDb(), businessSelect, params);
37+
response.currentPageData = businesses;
38+
}
39+
if (reason === FilterPageSortChangeReason.InitialLoad || reason === FilterPageSortChangeReason.FilterChanged) {
2340

24-
const footerValues: Record<string, string> = {};
25-
for(const column of footerValueColumns || []) {
26-
const inspectionsQuery = `select count(*) as count from inspections left join businesses on inspections.business_id = businesses.business_id ${noPagingWhereClause}`;
27-
const violationsQuery = `select count(*) as count from violations left join businesses on violations.business_id = businesses.business_id ${noPagingWhereClause}`;
28-
const value = column === "inspection_count" ? await getRowsFromSqlite(inspectionsQuery,noPagingParams) :
29-
await getRowsFromSqlite(violationsQuery,noPagingParams);
30-
footerValues[column] = `Total: ${value[0]["count"]}`;
41+
const footerValues: Record<string, string> = {};
42+
for (const column of footerValueColumns || []) {
43+
const inspectionsQuery = `select count(*) as count from inspections left join businesses on inspections.business_id = businesses.business_id ${noPagingWhereClause}`;
44+
const violationsQuery = `select count(*) as count from violations left join businesses on violations.business_id = businesses.business_id ${noPagingWhereClause}`;
45+
const value = column === "inspection_count" ? await getRowsFromSqlite(getDb(), inspectionsQuery, noPagingParams) :
46+
await getRowsFromSqlite(getDb(), violationsQuery, noPagingParams);
47+
footerValues[column] = `Total: ${value[0]["count"]}`;
48+
}
49+
response.footerValues = footerValues;
3150
}
51+
if (reason === FilterPageSortChangeReason.InitialLoad) {
3252

33-
// const filterDistinctValues: Record<string, NameValue[]> =await distinctValueColumns?.reduce(async (obj, column) => {
34-
// const values = `select distinct ${column} from businesses ${noPagingWhereClause}`;
35-
// const dbValues = await getRowsFromSqlite(values);
36-
// obj[column] = dbValues.map((value: unknown) => ({name: (value as any)[column], value: (value as any)[column]}));
37-
// }, {}) || {};
38-
const filterDistinctValues: Record<string, NameValue[]> = {};
39-
for(const column of distinctValueColumns || []) {
40-
const values = `select distinct ${column} from businesses ${noPagingWhereClause}`;
41-
const dbValues = await getRowsFromSqlite(values,noPagingParams);
42-
filterDistinctValues[column] = dbValues.map((value: unknown) => ({name: (value as any)[column], value: (value as any)[column]}));
53+
const filterDistinctValues: Record<string, NameValue[]> = {};
54+
for (const column of distinctValueColumns || []) {
55+
const values = `select distinct ${column} from businesses ${noPagingWhereClause}`;
56+
const dbValues = await getRowsFromSqlite(getDb(), values, noPagingParams);
57+
filterDistinctValues[column] = dbValues.map((value: unknown) => ({ name: (value as any)[column], value: (value as any)[column] }));
58+
}
59+
response.filterDistinctValues = filterDistinctValues;
4360
}
4461
return {
45-
rows: businesses,
46-
count: (count[0] as any).count,
47-
footerValues,
48-
filterDistinctValues
62+
...response,
4963
};
5064
},
5165
},

apps/graphql-apollo-react/graphql/schemas/business.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,20 @@ type NameValue {
2727
name: String!
2828
value: String!
2929
}
30+
type Pagination{
31+
totalRecords: Int
32+
pageSize: Int
33+
currentPage: Int
34+
totalPages: Int
35+
}
3036
3137
3238
type Query {
33-
businesses(args: FilterPageSortArguments): ServerResponse!
39+
businesses(args: FilterPageSortArguments): ServerInfo!
3440
}
35-
type ServerResponse {
36-
rows: [Business!]!
37-
count: Int!
41+
type ServerInfo {
42+
currentPageData: [Business!]!
43+
pagination: Pagination
3844
filterDistinctValues: JSON
3945
footerValues: JSON
4046
}
@@ -92,11 +98,12 @@ input ExpansionInput {
9298
9399
input FilterPageSortArguments {
94100
distinctValueColumns: [String!]
95-
footerValueColumns: [String!]
101+
visibleColumns: [String!]
96102
filter: FilterInput
97103
pagination: PaginationRequestInput
98104
sorts: [SortInfoInput!]
99105
expansion: ExpansionInput
106+
reason: String
100107
}
101108
102109
type Query {

apps/graphql-apollo-react/shared/sql-builder.ts

Lines changed: 0 additions & 28 deletions
This file was deleted.

apps/graphql-apollo-react/tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"incremental": true,
1414
"types": ["jest", "node"]
1515
},
16-
"include": ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx", "next-env.d.ts"],
16+
"include": ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx", "next-env.d.ts", "../../libs/grid-shared/src/lib/shared/sql-builder.ts"],
1717
"exclude": [
1818
"node_modules",
1919
"jest.config.ts",

0 commit comments

Comments
 (0)