mirror of
https://github.com/Kingsrook/qqq-frontend-material-dashboard.git
synced 2025-07-18 05:10:45 +00:00
Update to not show results from previous queries or counts
This commit is contained in:
@ -22,6 +22,7 @@
|
|||||||
import {QFieldType} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFieldType";
|
import {QFieldType} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFieldType";
|
||||||
import {QProcessMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QProcessMetaData";
|
import {QProcessMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QProcessMetaData";
|
||||||
import {QTableMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableMetaData";
|
import {QTableMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableMetaData";
|
||||||
|
import {QRecord} from "@kingsrook/qqq-frontend-core/lib/model/QRecord";
|
||||||
import {QFilterCriteria} from "@kingsrook/qqq-frontend-core/lib/model/query/QFilterCriteria";
|
import {QFilterCriteria} from "@kingsrook/qqq-frontend-core/lib/model/query/QFilterCriteria";
|
||||||
import {QFilterOrderBy} from "@kingsrook/qqq-frontend-core/lib/model/query/QFilterOrderBy";
|
import {QFilterOrderBy} from "@kingsrook/qqq-frontend-core/lib/model/query/QFilterOrderBy";
|
||||||
import {QQueryFilter} from "@kingsrook/qqq-frontend-core/lib/model/query/QQueryFilter";
|
import {QQueryFilter} from "@kingsrook/qqq-frontend-core/lib/model/query/QQueryFilter";
|
||||||
@ -162,6 +163,15 @@ function EntityList({table}: Props): JSX.Element
|
|||||||
const [pinnedColumns, setPinnedColumns] = useState({left: ["__check__", "id"]});
|
const [pinnedColumns, setPinnedColumns] = useState({left: ["__check__", "id"]});
|
||||||
const instance = useRef({timer: null});
|
const instance = useRef({timer: null});
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// use all these states to avoid showing results from an "old" query, that finishes loading after a newer one //
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
const [latestQueryId, setLatestQueryId] = useState(0);
|
||||||
|
const [countResults, setCountResults] = useState({} as any);
|
||||||
|
const [receivedCountTimestamp, setReceivedCountTimestamp] = useState(new Date());
|
||||||
|
const [queryResults, setQueryResults] = useState({} as any);
|
||||||
|
const [receivedQueryTimestamp, setReceivedQueryTimestamp] = useState(new Date());
|
||||||
|
|
||||||
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
||||||
|
|
||||||
const openActionsMenu = (event: any) => setActionsMenu(event.currentTarget);
|
const openActionsMenu = (event: any) => setActionsMenu(event.currentTarget);
|
||||||
@ -200,7 +210,6 @@ function EntityList({table}: Props): JSX.Element
|
|||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// we need the table meta data to look up the default filter (if it comes from query string), //
|
// we need the table meta data to look up the default filter (if it comes from query string), //
|
||||||
// because we need to know field types to translate qqq filter to material filter //
|
// because we need to know field types to translate qqq filter to material filter //
|
||||||
// because we need to know field types to translate qqq filter to material filter //
|
|
||||||
// return here ane wait for the next 'turn' to allow doing the actual query //
|
// return here ane wait for the next 'turn' to allow doing the actual query //
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
if (!defaultFilterLoaded)
|
if (!defaultFilterLoaded)
|
||||||
@ -210,6 +219,7 @@ function EntityList({table}: Props): JSX.Element
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setTableMetaData(tableMetaData);
|
setTableMetaData(tableMetaData);
|
||||||
|
setTableLabel(tableMetaData.label);
|
||||||
if (columnSortModel.length === 0)
|
if (columnSortModel.length === 0)
|
||||||
{
|
{
|
||||||
columnSortModel.push({
|
columnSortModel.push({
|
||||||
@ -222,34 +232,88 @@ function EntityList({table}: Props): JSX.Element
|
|||||||
|
|
||||||
const qFilter = buildQFilter();
|
const qFilter = buildQFilter();
|
||||||
|
|
||||||
const count = await qController.count(tableName, qFilter);
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
setTotalRecords(count);
|
// assign a new query id to the query being issued here. then run both the count & query async //
|
||||||
setTableLabel(tableMetaData.label);
|
// and when they load, store their results associated with this id. //
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
const thisQueryId = latestQueryId + 1
|
||||||
|
setLatestQueryId(thisQueryId);
|
||||||
|
|
||||||
const columns = [] as GridColDef[];
|
console.log(`Issuing query: ${thisQueryId}`);
|
||||||
|
setTotalRecords(null);
|
||||||
|
qController.count(tableName, qFilter).then((count) =>
|
||||||
|
{
|
||||||
|
countResults[thisQueryId] = count;
|
||||||
|
setCountResults(countResults);
|
||||||
|
setReceivedCountTimestamp(new Date());
|
||||||
|
});
|
||||||
|
|
||||||
const results = await qController.query(
|
qController.query(tableName, qFilter, rowsPerPage, pageNumber * rowsPerPage).then((results) =>
|
||||||
tableName,
|
{
|
||||||
qFilter,
|
console.log(`Received results for query ${thisQueryId}`);
|
||||||
rowsPerPage,
|
queryResults[thisQueryId] = results;
|
||||||
pageNumber * rowsPerPage,
|
setQueryResults(queryResults);
|
||||||
)
|
setReceivedQueryTimestamp(new Date());
|
||||||
|
})
|
||||||
.catch((error) =>
|
.catch((error) =>
|
||||||
{
|
{
|
||||||
if (error.message)
|
if (error && error.message)
|
||||||
{
|
{
|
||||||
setAlertContent(error.message);
|
setAlertContent(error.message);
|
||||||
}
|
}
|
||||||
else
|
else if(error && error.response && error.response.data && error.response.data.error)
|
||||||
{
|
{
|
||||||
setAlertContent(error.response.data.error);
|
setAlertContent(error.response.data.error);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setAlertContent("Unexpected error running query");
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
throw error;
|
throw error;
|
||||||
});
|
});
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////
|
||||||
|
// display count results //
|
||||||
|
///////////////////////////
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
if (countResults[latestQueryId] === null)
|
||||||
|
{
|
||||||
|
///////////////////////////////////////////////
|
||||||
|
// see same idea in displaying query results //
|
||||||
|
///////////////////////////////////////////////
|
||||||
|
console.log(`No count results for id ${latestQueryId}...`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setTotalRecords(countResults[latestQueryId]);
|
||||||
|
delete countResults[latestQueryId];
|
||||||
|
}, [receivedCountTimestamp]);
|
||||||
|
|
||||||
|
///////////////////////////
|
||||||
|
// display query results //
|
||||||
|
///////////////////////////
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
if(!queryResults[latestQueryId])
|
||||||
|
{
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// to avoid showing results from an "older" query (e.g., one that was slow, and returned //
|
||||||
|
// AFTER a newer one) only ever show results here for the latestQueryId that was issued. //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
console.log(`No query results for id ${latestQueryId}...`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Outputting results for query ${latestQueryId}...`);
|
||||||
|
const results = queryResults[latestQueryId];
|
||||||
|
delete queryResults[latestQueryId];
|
||||||
|
|
||||||
const fields = [...tableMetaData.fields.values()];
|
const fields = [...tableMetaData.fields.values()];
|
||||||
const rows = [] as any[];
|
const rows = [] as any[];
|
||||||
results.forEach((record) =>
|
results.forEach((record: QRecord) =>
|
||||||
{
|
{
|
||||||
const row: any = {};
|
const row: any = {};
|
||||||
fields.forEach((field) =>
|
fields.forEach((field) =>
|
||||||
@ -271,6 +335,7 @@ function EntityList({table}: Props): JSX.Element
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const columns = [] as GridColDef[];
|
||||||
sortedKeys.forEach((key) =>
|
sortedKeys.forEach((key) =>
|
||||||
{
|
{
|
||||||
const field = tableMetaData.fields.get(key);
|
const field = tableMetaData.fields.get(key);
|
||||||
@ -335,8 +400,7 @@ function EntityList({table}: Props): JSX.Element
|
|||||||
setRows(rows);
|
setRows(rows);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
forceUpdate();
|
forceUpdate();
|
||||||
})();
|
}, [receivedQueryTimestamp]);
|
||||||
};
|
|
||||||
|
|
||||||
const handlePageChange = (page: number) =>
|
const handlePageChange = (page: number) =>
|
||||||
{
|
{
|
||||||
@ -470,8 +534,6 @@ function EntityList({table}: Props): JSX.Element
|
|||||||
format: string;
|
format: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo - figure out what's up here...
|
|
||||||
// eslint-disable-next-line react/no-unstable-nested-components
|
|
||||||
function ExportMenuItem(props: QExportMenuItemProps)
|
function ExportMenuItem(props: QExportMenuItemProps)
|
||||||
{
|
{
|
||||||
const {format, hideMenu} = props;
|
const {format, hideMenu} = props;
|
||||||
@ -602,10 +664,22 @@ function EntityList({table}: Props): JSX.Element
|
|||||||
};
|
};
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const defaultLabelDisplayedRows = ({from, to, count}) => `Showing ${from.toLocaleString()} to ${to.toLocaleString()} of ${count !== -1 ? `${count.toLocaleString()} records` : `more than ${to.toLocaleString()} records`}`;
|
const defaultLabelDisplayedRows = ({from, to, count}) =>
|
||||||
|
{
|
||||||
|
if(count !== null && count !== undefined)
|
||||||
|
{
|
||||||
|
if(count === 0)
|
||||||
|
{
|
||||||
|
return ("No rows");
|
||||||
|
}
|
||||||
|
return (`Showing ${from.toLocaleString()} to ${to.toLocaleString()} of ${count !== -1 ? `${count.toLocaleString()} records` : `more than ${to.toLocaleString()} records`}`);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return ("Counting records...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// todo - figure out what's up here...
|
|
||||||
// eslint-disable-next-line react/no-unstable-nested-components
|
|
||||||
function CustomPagination()
|
function CustomPagination()
|
||||||
{
|
{
|
||||||
return (
|
return (
|
||||||
@ -622,8 +696,6 @@ function EntityList({table}: Props): JSX.Element
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo - figure out what's up here...
|
|
||||||
// eslint-disable-next-line react/no-unstable-nested-components
|
|
||||||
function Loading()
|
function Loading()
|
||||||
{
|
{
|
||||||
return (
|
return (
|
||||||
@ -631,8 +703,6 @@ function EntityList({table}: Props): JSX.Element
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo - figure out what's up here...
|
|
||||||
// eslint-disable-next-line react/no-unstable-nested-components
|
|
||||||
function CustomToolbar()
|
function CustomToolbar()
|
||||||
{
|
{
|
||||||
return (
|
return (
|
||||||
|
Reference in New Issue
Block a user