mirror of
https://github.com/rowyio/rowy.git
synced 2025-12-28 16:06:41 +01:00
useTable hook, connecting to firestore collections
This commit is contained in:
@@ -6,9 +6,11 @@
|
||||
"@material-ui/core": "^4.4.0",
|
||||
"@types/jest": "24.0.18",
|
||||
"@types/node": "12.7.4",
|
||||
"@types/ramda": "^0.26.21",
|
||||
"@types/react": "16.9.2",
|
||||
"@types/react-dom": "16.9.0",
|
||||
"firebase": "^6.6.0",
|
||||
"ramda": "^0.26.1",
|
||||
"react": "^16.9.0",
|
||||
"react-dom": "^16.9.0",
|
||||
"react-scripts": "3.1.1",
|
||||
|
||||
123
src/hooks/useTable.ts
Normal file
123
src/hooks/useTable.ts
Normal file
@@ -0,0 +1,123 @@
|
||||
import { db } from "../firebase";
|
||||
import { useEffect, useReducer } from "react";
|
||||
import equals from "ramda/es/equals";
|
||||
const CAP = 500;
|
||||
|
||||
const tableReducer = (prevState: any, newProps: any) => {
|
||||
if (newProps.type) {
|
||||
switch (newProps.type) {
|
||||
case "more":
|
||||
if (prevState.limit < prevState.cap)
|
||||
// rows count hardcap
|
||||
return { ...prevState, limit: prevState.limit + 10 };
|
||||
else return { ...prevState };
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
return { ...prevState, ...newProps };
|
||||
}
|
||||
};
|
||||
const tableIntialState = {
|
||||
rows: [],
|
||||
prevFilters: null,
|
||||
prevPath: null,
|
||||
path: null,
|
||||
filters: [],
|
||||
prevLimit: 0,
|
||||
limit: 20,
|
||||
loading: true,
|
||||
cap: CAP
|
||||
};
|
||||
|
||||
const useTable = (intialOverrides: any) => {
|
||||
const [tableState, tableDispatch] = useReducer(tableReducer, {
|
||||
...tableIntialState,
|
||||
...intialOverrides
|
||||
});
|
||||
const getRows = (
|
||||
filters: {
|
||||
field: string;
|
||||
operator: "==" | "<" | ">" | ">=" | "<=";
|
||||
value: string;
|
||||
}[],
|
||||
limit: number,
|
||||
sort:
|
||||
| { field: string; direction: "asc" | "desc" }[]
|
||||
| { field: string; direction: "asc" | "desc" }
|
||||
) => {
|
||||
//unsubscribe from old path
|
||||
if (tableState.prevPath && tableState.path !== tableState.prevPath) {
|
||||
tableState.unsubscribe();
|
||||
}
|
||||
//updates prev values
|
||||
tableDispatch({
|
||||
prevFilters: filters,
|
||||
prevLimit: limit,
|
||||
prevPath: tableState.path,
|
||||
loading: true
|
||||
});
|
||||
let query:
|
||||
| firebase.firestore.CollectionReference
|
||||
| firebase.firestore.Query = db.collection(tableState.path);
|
||||
|
||||
filters.forEach(filter => {
|
||||
query = query.where(filter.field, filter.operator, filter.value);
|
||||
});
|
||||
if (sort) {
|
||||
if (Array.isArray(sort)) {
|
||||
sort.forEach(order => {
|
||||
query = query.orderBy(order.field, order.direction);
|
||||
});
|
||||
} else {
|
||||
query = query.orderBy(sort.field, sort.direction);
|
||||
}
|
||||
}
|
||||
const unsubscribe = query.limit(limit).onSnapshot(snapshot => {
|
||||
if (snapshot.docs.length > 0) {
|
||||
const rows = snapshot.docs.map(doc => {
|
||||
const data = doc.data();
|
||||
const id = doc.id;
|
||||
return { ...data, id };
|
||||
});
|
||||
tableDispatch({
|
||||
rows,
|
||||
loading: false
|
||||
});
|
||||
} else {
|
||||
tableDispatch({
|
||||
rows: [],
|
||||
loading: false
|
||||
});
|
||||
}
|
||||
});
|
||||
tableDispatch({ unsubscribe });
|
||||
};
|
||||
useEffect(() => {
|
||||
const {
|
||||
prevFilters,
|
||||
filters,
|
||||
prevLimit,
|
||||
limit,
|
||||
prevPath,
|
||||
path,
|
||||
sort,
|
||||
unsubscribe
|
||||
} = tableState;
|
||||
if (
|
||||
!equals(prevFilters, filters) ||
|
||||
prevLimit !== limit ||
|
||||
prevPath !== path
|
||||
) {
|
||||
if (path) getRows(filters, limit, sort);
|
||||
}
|
||||
return () => {
|
||||
if (unsubscribe) {
|
||||
tableState.unsubscribe();
|
||||
}
|
||||
};
|
||||
}, [tableState.filters, tableState.limit, tableState.path]);
|
||||
return [tableState, tableDispatch];
|
||||
};
|
||||
|
||||
export default useTable;
|
||||
17
yarn.lock
17
yarn.lock
@@ -1610,6 +1610,13 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.1.tgz#48fd98c1561fe718b61733daed46ff115b496e18"
|
||||
integrity sha512-eqz8c/0kwNi/OEHQfvIuJVLTst3in0e7uTKeuY+WL/zfKn0xVujOTp42bS/vUUokhK5P2BppLd9JXMOMHcgbjA==
|
||||
|
||||
"@types/ramda@^0.26.21":
|
||||
version "0.26.21"
|
||||
resolved "https://registry.yarnpkg.com/@types/ramda/-/ramda-0.26.21.tgz#cfd552c679453d153a9e2fd89ffc5dd5aa93d2c9"
|
||||
integrity sha512-zMYtIZMceA6BvH+or6LmewLBgojbXg5+FGCwjO8K+Z+d/ZWxILmhhASXkehW0PqJL+V0QbyDeeAHix0dvEKXfQ==
|
||||
dependencies:
|
||||
ts-toolbelt "^3.8.4"
|
||||
|
||||
"@types/react-dom@16.9.0":
|
||||
version "16.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.9.0.tgz#ba6ddb00bf5de700b0eb91daa452081ffccbfdea"
|
||||
@@ -8873,6 +8880,11 @@ raf@3.4.1:
|
||||
dependencies:
|
||||
performance-now "^2.1.0"
|
||||
|
||||
ramda@^0.26.1:
|
||||
version "0.26.1"
|
||||
resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.26.1.tgz#8d41351eb8111c55353617fc3bbffad8e4d35d06"
|
||||
integrity sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ==
|
||||
|
||||
randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80"
|
||||
@@ -10427,6 +10439,11 @@ ts-pnp@^1.1.2:
|
||||
resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.1.4.tgz#ae27126960ebaefb874c6d7fa4729729ab200d90"
|
||||
integrity sha512-1J/vefLC+BWSo+qe8OnJQfWTYRS6ingxjwqmHMqaMxXMj7kFtKLgAaYW3JeX3mktjgUL+etlU8/B4VUAUI9QGw==
|
||||
|
||||
ts-toolbelt@^3.8.4:
|
||||
version "3.8.72"
|
||||
resolved "https://registry.yarnpkg.com/ts-toolbelt/-/ts-toolbelt-3.8.72.tgz#647ba67a3bd55f1e5a8057c1a7621c38b2e418a5"
|
||||
integrity sha512-rVwnPRczAamCTIs/9iUgWW12YMscmDG79M0xiUmcmWgTk8lkjxrrwzUys72wsIxNohtiNQaOhbkgQPIxqIdwmA==
|
||||
|
||||
tslib@1.10.0, tslib@^1.8.1:
|
||||
version "1.10.0"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a"
|
||||
|
||||
Reference in New Issue
Block a user