Skip to content

Commit a3c8a11

Browse files
authored
feat: Add pagination to data browser (#2659)
1 parent 35fc746 commit a3c8a11

7 files changed

+246
-126
lines changed

src/dashboard/Data/Browser/Browser.react.js

+110-83
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ import { Helmet } from 'react-helmet';
4141
import generatePath from 'lib/generatePath';
4242
import { withRouter } from 'lib/withRouter';
4343
import { get } from 'lib/AJAX';
44+
import BrowserFooter from './BrowserFooter.react';
4445

4546
// The initial and max amount of rows fetched by lazy loading
46-
const MAX_ROWS_FETCHED = 200;
4747
const BROWSER_LAST_LOCATION = 'brower_last_location';
4848

4949
@subscribeTo('Schema', 'schema')
@@ -54,6 +54,7 @@ class Browser extends DashboardView {
5454
this.section = 'Core';
5555
this.subsection = 'Browser';
5656
this.noteTimeout = null;
57+
const limit = window.localStorage?.getItem('browserLimit');
5758

5859
this.state = {
5960
showCreateClassDialog: false,
@@ -75,6 +76,8 @@ class Browser extends DashboardView {
7576
clp: {},
7677
filters: new List(),
7778
ordering: '-createdAt',
79+
skip: 0,
80+
limit: limit ? parseInt(limit) : 100,
7881
selection: {},
7982
exporting: false,
8083
exportingCount: 0,
@@ -894,7 +897,7 @@ class Browser extends DashboardView {
894897
}
895898

896899
async fetchParseData(source, filters) {
897-
const { useMasterKey } = this.state;
900+
const { useMasterKey, skip, limit } = this.state;
898901
const query = await queryFromFilters(source, filters);
899902
const sortDir = this.state.ordering[0] === '-' ? '-' : '+';
900903
const field = this.state.ordering.substr(sortDir === '-' ? 1 : 0);
@@ -904,8 +907,11 @@ class Browser extends DashboardView {
904907
} else {
905908
query.ascending(field);
906909
}
910+
query.skip(skip);
911+
query.limit(limit);
912+
913+
localStorage?.setItem('browserLimit', limit);
907914

908-
query.limit(MAX_ROWS_FETCHED);
909915
this.excludeFields(query, source);
910916
let promise = query.find({ useMasterKey });
911917
let isUnique = false;
@@ -957,7 +963,7 @@ class Browser extends DashboardView {
957963
this.setState({
958964
data: data,
959965
filters,
960-
lastMax: MAX_ROWS_FETCHED,
966+
lastMax: this.state.limit,
961967
filteredCounts: filteredCounts,
962968
});
963969
}
@@ -971,7 +977,7 @@ class Browser extends DashboardView {
971977
selection: {},
972978
data,
973979
filters,
974-
lastMax: MAX_ROWS_FETCHED,
980+
lastMax: this.state.limit,
975981
});
976982
}
977983

@@ -1024,7 +1030,7 @@ class Browser extends DashboardView {
10241030
query.lessThan('createdAt', this.state.data[this.state.data.length - 1].get('createdAt'));
10251031
query.addDescending('createdAt');
10261032
}
1027-
query.limit(MAX_ROWS_FETCHED);
1033+
query.limit(this.state.limit);
10281034
this.excludeFields(query, source);
10291035

10301036
const { useMasterKey } = this.state;
@@ -1035,7 +1041,7 @@ class Browser extends DashboardView {
10351041
}));
10361042
}
10371043
});
1038-
this.setState({ lastMax: this.state.lastMax + MAX_ROWS_FETCHED });
1044+
this.setState({ lastMax: this.state.lastMax + this.state.limit });
10391045
}
10401046

10411047
updateFilters(filters) {
@@ -1051,6 +1057,10 @@ class Browser extends DashboardView {
10511057
// filters param change is making the fetch call
10521058
this.props.navigate(generatePath(this.context, url));
10531059
}
1060+
1061+
this.setState({
1062+
skip: 0,
1063+
});
10541064
}
10551065

10561066
saveFilters(filters, name) {
@@ -1302,7 +1312,7 @@ class Browser extends DashboardView {
13021312
this.state.counts[className] = 0;
13031313
this.setState({
13041314
data: [],
1305-
lastMax: MAX_ROWS_FETCHED,
1315+
lastMax: this.state.limit,
13061316
selection: {},
13071317
});
13081318
}
@@ -1362,7 +1372,7 @@ class Browser extends DashboardView {
13621372

13631373
// If after deletion, the remaining elements on the table is lesser than the maximum allowed elements
13641374
// we fetch more data to fill the table
1365-
if (this.state.data.length < MAX_ROWS_FETCHED) {
1375+
if (this.state.data.length < this.state.limit) {
13661376
this.prefetchData(this.props, this.context);
13671377
} else {
13681378
this.forceUpdate();
@@ -2005,80 +2015,96 @@ class Browser extends DashboardView {
20052015
}
20062016
}
20072017
browser = (
2008-
<DataBrowser
2009-
app={this.context}
2010-
ref={this.dataBrowserRef}
2011-
isUnique={this.state.isUnique}
2012-
uniqueField={this.state.uniqueField}
2013-
count={count}
2014-
perms={this.state.clp[className]}
2015-
schema={this.props.schema}
2016-
filters={this.state.filters}
2017-
onFilterChange={this.updateFilters}
2018-
onFilterSave={(...args) => this.saveFilters(...args)}
2019-
onRemoveColumn={this.showRemoveColumn}
2020-
onDeleteRows={this.showDeleteRows}
2021-
onDropClass={this.showDropClass}
2022-
onExport={this.showExport}
2023-
onChangeCLP={this.handleCLPChange}
2024-
onRefresh={this.refresh}
2025-
onAttachRows={this.showAttachRowsDialog}
2026-
onAttachSelectedRows={this.showAttachSelectedRowsDialog}
2027-
onExecuteScriptRows={this.showExecuteScriptRowsDialog}
2028-
onCloneSelectedRows={this.showCloneSelectedRowsDialog}
2029-
onEditSelectedRow={this.showEditRowDialog}
2030-
onEditPermissions={this.onDialogToggle}
2031-
onExportSelectedRows={this.showExportSelectedRowsDialog}
2032-
onExportSchema={this.showExportSchemaDialog}
2033-
onSaveNewRow={this.saveNewRow}
2034-
onShowPointerKey={this.showPointerKeyDialog}
2035-
onAbortAddRow={this.abortAddRow}
2036-
onSaveEditCloneRow={this.saveEditCloneRow}
2037-
onAbortEditCloneRow={this.abortEditCloneRow}
2038-
onCancelPendingEditRows={this.cancelPendingEditRows}
2039-
currentUser={this.state.currentUser}
2040-
useMasterKey={this.state.useMasterKey}
2041-
login={this.login}
2042-
logout={this.logout}
2043-
toggleMasterKeyUsage={this.toggleMasterKeyUsage}
2044-
markRequiredFieldRow={this.state.markRequiredFieldRow}
2045-
requiredColumnFields={this.state.requiredColumnFields}
2046-
columns={columns}
2047-
className={className}
2048-
fetchNextPage={this.fetchNextPage}
2049-
maxFetched={this.state.lastMax}
2050-
selectRow={this.selectRow}
2051-
selection={this.state.selection}
2052-
data={this.state.data}
2053-
ordering={this.state.ordering}
2054-
newObject={this.state.newObject}
2055-
editCloneRows={this.state.editCloneRows}
2056-
relation={this.state.relation}
2057-
disableKeyControls={this.hasExtras()}
2058-
updateRow={this.updateRow}
2059-
updateOrdering={this.updateOrdering}
2060-
onPointerClick={this.handlePointerClick}
2061-
onPointerCmdClick={this.handlePointerCmdClick}
2062-
setRelation={this.setRelation}
2063-
onAddColumn={this.showAddColumn}
2064-
onAddRow={this.addRow}
2065-
onAddRowWithModal={this.addRowWithModal}
2066-
onAddClass={this.showCreateClass}
2067-
showNote={this.showNote}
2068-
onMouseDownRowCheckBox={this.onMouseDownRowCheckBox}
2069-
onMouseUpRowCheckBox={this.onMouseUpRowCheckBox}
2070-
onMouseOverRowCheckBox={this.onMouseOverRowCheckBox}
2071-
classes={this.classes}
2072-
classwiseCloudFunctions={this.state.classwiseCloudFunctions}
2073-
callCloudFunction={this.fetchAggregationPanelData}
2074-
isLoadingCloudFunction={this.state.isLoading}
2075-
setLoading={this.setLoading}
2076-
AggregationPanelData={this.state.AggregationPanelData}
2077-
setAggregationPanelData={this.setAggregationPanelData}
2078-
setErrorAggregatedData={this.setErrorAggregatedData}
2079-
errorAggregatedData={this.state.errorAggregatedData}
2080-
appName={this.props.params.appId}
2081-
/>
2018+
<>
2019+
<DataBrowser
2020+
app={this.context}
2021+
ref={this.dataBrowserRef}
2022+
isUnique={this.state.isUnique}
2023+
uniqueField={this.state.uniqueField}
2024+
count={count}
2025+
perms={this.state.clp[className]}
2026+
schema={this.props.schema}
2027+
filters={this.state.filters}
2028+
onFilterChange={this.updateFilters}
2029+
onFilterSave={(...args) => this.saveFilters(...args)}
2030+
onRemoveColumn={this.showRemoveColumn}
2031+
onDeleteRows={this.showDeleteRows}
2032+
onDropClass={this.showDropClass}
2033+
onExport={this.showExport}
2034+
onChangeCLP={this.handleCLPChange}
2035+
onRefresh={this.refresh}
2036+
onAttachRows={this.showAttachRowsDialog}
2037+
onAttachSelectedRows={this.showAttachSelectedRowsDialog}
2038+
onExecuteScriptRows={this.showExecuteScriptRowsDialog}
2039+
onCloneSelectedRows={this.showCloneSelectedRowsDialog}
2040+
onEditSelectedRow={this.showEditRowDialog}
2041+
onEditPermissions={this.onDialogToggle}
2042+
onExportSelectedRows={this.showExportSelectedRowsDialog}
2043+
onExportSchema={this.showExportSchemaDialog}
2044+
onSaveNewRow={this.saveNewRow}
2045+
onShowPointerKey={this.showPointerKeyDialog}
2046+
onAbortAddRow={this.abortAddRow}
2047+
onSaveEditCloneRow={this.saveEditCloneRow}
2048+
onAbortEditCloneRow={this.abortEditCloneRow}
2049+
onCancelPendingEditRows={this.cancelPendingEditRows}
2050+
currentUser={this.state.currentUser}
2051+
useMasterKey={this.state.useMasterKey}
2052+
login={this.login}
2053+
logout={this.logout}
2054+
toggleMasterKeyUsage={this.toggleMasterKeyUsage}
2055+
markRequiredFieldRow={this.state.markRequiredFieldRow}
2056+
requiredColumnFields={this.state.requiredColumnFields}
2057+
columns={columns}
2058+
className={className}
2059+
fetchNextPage={this.fetchNextPage}
2060+
maxFetched={this.state.lastMax}
2061+
selectRow={this.selectRow}
2062+
selection={this.state.selection}
2063+
data={this.state.data}
2064+
ordering={this.state.ordering}
2065+
newObject={this.state.newObject}
2066+
editCloneRows={this.state.editCloneRows}
2067+
relation={this.state.relation}
2068+
disableKeyControls={this.hasExtras()}
2069+
updateRow={this.updateRow}
2070+
updateOrdering={this.updateOrdering}
2071+
onPointerClick={this.handlePointerClick}
2072+
onPointerCmdClick={this.handlePointerCmdClick}
2073+
setRelation={this.setRelation}
2074+
onAddColumn={this.showAddColumn}
2075+
onAddRow={this.addRow}
2076+
onAddRowWithModal={this.addRowWithModal}
2077+
onAddClass={this.showCreateClass}
2078+
showNote={this.showNote}
2079+
onMouseDownRowCheckBox={this.onMouseDownRowCheckBox}
2080+
onMouseUpRowCheckBox={this.onMouseUpRowCheckBox}
2081+
onMouseOverRowCheckBox={this.onMouseOverRowCheckBox}
2082+
classes={this.classes}
2083+
classwiseCloudFunctions={this.state.classwiseCloudFunctions}
2084+
callCloudFunction={this.fetchAggregationPanelData}
2085+
isLoadingCloudFunction={this.state.isLoading}
2086+
setLoading={this.setLoading}
2087+
AggregationPanelData={this.state.AggregationPanelData}
2088+
setAggregationPanelData={this.setAggregationPanelData}
2089+
setErrorAggregatedData={this.setErrorAggregatedData}
2090+
errorAggregatedData={this.state.errorAggregatedData}
2091+
appName={this.props.params.appId}
2092+
limit={this.state.limit}
2093+
/>
2094+
<BrowserFooter
2095+
skip={this.state.skip}
2096+
setSkip={skip => {
2097+
this.setState({ skip });
2098+
this.updateOrdering(this.state.ordering);
2099+
}}
2100+
count={count}
2101+
limit={this.state.limit}
2102+
setLimit={limit => {
2103+
this.setState({ limit });
2104+
this.updateOrdering(this.state.ordering);
2105+
}}
2106+
/>
2107+
</>
20822108
);
20832109
}
20842110
}
@@ -2268,6 +2294,7 @@ class Browser extends DashboardView {
22682294
confirmAttachSelectedRows={this.confirmAttachSelectedRows}
22692295
schema={this.props.schema}
22702296
useMasterKey={this.state.useMasterKey}
2297+
limit={this.state.limit}
22712298
/>
22722299
);
22732300
} else if (this.state.rowsToExport) {

src/dashboard/Data/Browser/Browser.scss

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
top: 96px;
1313
left: 300px;
1414
right: 0;
15-
bottom: 0;
15+
bottom: 36px;
1616
overflow: auto;
1717
}
1818

0 commit comments

Comments
 (0)