u
This commit is contained in:
@@ -45,7 +45,7 @@ import authAutomat from './authAutomat';
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export const CHUNK_SIZE = 50;
|
export const CHUNK_SIZE = 50;
|
||||||
const PREFETCH_CHUNKS = 2;
|
const PREFETCH_CHUNKS = 1;
|
||||||
const CHUNK_DEBOUNCE_MS = 130;
|
const CHUNK_DEBOUNCE_MS = 130;
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
@@ -87,7 +87,7 @@ function clearChunkDebounce() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Executes chunk loading for the standstill target and prefetches lookahead chunks
|
// Executes chunk loading for the standstill target and prefetches lookahead chunks
|
||||||
function _executeRequiredChunks(chunks, targetEpoch) {
|
function _executeRequiredChunks(chunks, targetEpoch, prefetch = true) {
|
||||||
if (targetEpoch !== queryEpoch) {
|
if (targetEpoch !== queryEpoch) {
|
||||||
return Promise.resolve(automat.state.items);
|
return Promise.resolve(automat.state.items);
|
||||||
}
|
}
|
||||||
@@ -102,17 +102,21 @@ function _executeRequiredChunks(chunks, targetEpoch) {
|
|||||||
promises.push(actions.loadChunk(c, targetEpoch));
|
promises.push(actions.loadChunk(c, targetEpoch));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prefetch lookahead chunks after the highest requested chunk
|
// Once active chunks finish loading, prefetch the next lookahead chunk in the background
|
||||||
const maxChunk = chunkList[chunkList.length - 1];
|
return Promise.all(promises).then(() => {
|
||||||
const total = automat.state.total || 0;
|
if (targetEpoch !== queryEpoch) return automat.state.items;
|
||||||
for (let c = maxChunk + 1; c <= maxChunk + PREFETCH_CHUNKS; c++) {
|
if (prefetch) {
|
||||||
if (total > 0 && c * CHUNK_SIZE >= total) {
|
const maxChunk = chunkList[chunkList.length - 1];
|
||||||
break;
|
const total = automat.state.total || 0;
|
||||||
|
for (let c = maxChunk + 1; c <= maxChunk + PREFETCH_CHUNKS; c++) {
|
||||||
|
if (total > 0 && c * CHUNK_SIZE >= total) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
void actions.loadChunk(c, targetEpoch);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void actions.loadChunk(c, targetEpoch);
|
return automat.state.items;
|
||||||
}
|
});
|
||||||
|
|
||||||
return Promise.all(promises).then(() => automat.state.items);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: pure order helpers
|
// MARK: pure order helpers
|
||||||
@@ -214,10 +218,10 @@ function applyFilterReload() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const actions = {
|
const actions = {
|
||||||
// MARK: returns current items and triggers chunk 0 if not loaded
|
// MARK: returns current items and triggers chunk 0 if not loaded (no prefetch on entry)
|
||||||
getItems() {
|
getItems() {
|
||||||
if (automat.state.items === null) {
|
if (automat.state.items === null) {
|
||||||
void actions.requireChunk(0, 0, { immediate: true });
|
void actions.requireChunk(0, 0, { prefetch: false, immediate: true });
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return automat.state.items;
|
return automat.state.items;
|
||||||
@@ -250,13 +254,14 @@ const actions = {
|
|||||||
|
|
||||||
start = Math.max(0, Math.floor(start));
|
start = Math.max(0, Math.floor(start));
|
||||||
end = Math.max(start, Math.floor(end));
|
end = Math.max(start, Math.floor(end));
|
||||||
|
const prefetch = options.prefetch !== false;
|
||||||
|
|
||||||
// If initial items are null or immediate requested, bypass debounce and load immediately
|
// If initial items are null or immediate requested, bypass debounce and load immediately
|
||||||
if (options.immediate || automat.state.items === null) {
|
if (options.immediate || automat.state.items === null) {
|
||||||
clearChunkDebounce();
|
clearChunkDebounce();
|
||||||
const chunks = new Set();
|
const chunks = new Set();
|
||||||
for (let c = start; c <= end; c++) chunks.add(c);
|
for (let c = start; c <= end; c++) chunks.add(c);
|
||||||
return _executeRequiredChunks(chunks, queryEpoch);
|
return _executeRequiredChunks(chunks, queryEpoch, prefetch);
|
||||||
}
|
}
|
||||||
|
|
||||||
// New event tick (drag mousemove / pagination click) replaces previous target position
|
// New event tick (drag mousemove / pagination click) replaces previous target position
|
||||||
@@ -302,7 +307,7 @@ const actions = {
|
|||||||
pendingChunkResolve = null;
|
pendingChunkResolve = null;
|
||||||
pendingChunkReject = null;
|
pendingChunkReject = null;
|
||||||
|
|
||||||
_executeRequiredChunks(chunksToLoad, captureEpoch)
|
_executeRequiredChunks(chunksToLoad, captureEpoch, true)
|
||||||
.then((res) => resolve?.(res))
|
.then((res) => resolve?.(res))
|
||||||
.catch((err) => reject?.(err));
|
.catch((err) => reject?.(err));
|
||||||
}, CHUNK_DEBOUNCE_MS);
|
}, CHUNK_DEBOUNCE_MS);
|
||||||
@@ -363,15 +368,6 @@ const actions = {
|
|||||||
error: null,
|
error: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Trigger lookahead prefetching if first chunk just arrived
|
|
||||||
if (index === 0) {
|
|
||||||
for (let c = 1; c <= PREFETCH_CHUNKS; c++) {
|
|
||||||
if (c * CHUNK_SIZE < currentTotal) {
|
|
||||||
void actions.loadChunk(c, targetEpoch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return items;
|
return items;
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
|
|||||||
@@ -548,17 +548,6 @@ export class OrderList extends PureComponent {
|
|||||||
render() {
|
render() {
|
||||||
const { items, partiesById, busyId } = this.state;
|
const { items, partiesById, busyId } = this.state;
|
||||||
|
|
||||||
if (items === null) {
|
|
||||||
if (orderAutomat.state.status === 'failed') {
|
|
||||||
return <BackendError error={backendErrorFrom(orderAutomat.state.error)} onRetry={this.handleRetry} />;
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<Box sx={{ display: 'flex', justifyContent: 'center', py: 6 }}>
|
|
||||||
<CircularProgress />
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
rowContext.partiesById = partiesById;
|
rowContext.partiesById = partiesById;
|
||||||
rowContext.busyId = busyId;
|
rowContext.busyId = busyId;
|
||||||
rowContext.onOpen = this.handleOpen;
|
rowContext.onOpen = this.handleOpen;
|
||||||
@@ -566,18 +555,31 @@ export class OrderList extends PureComponent {
|
|||||||
rowContext.onTogglePaid = this.handleTogglePaid;
|
rowContext.onTogglePaid = this.handleTogglePaid;
|
||||||
rowContext.onToggleDelivered = this.handleToggleDelivered;
|
rowContext.onToggleDelivered = this.handleToggleDelivered;
|
||||||
|
|
||||||
|
if (items === null && orderAutomat.state.status === 'failed') {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<OrderSearchField inputRef={this.searchRef} onCreate={this.handleCreate} />
|
||||||
|
<PanelTileGrid>
|
||||||
|
<PanelTile wide={3} minHeight={0} color={cfg.listColor} sx={{ p: 2 }}>
|
||||||
|
<BackendError error={backendErrorFrom(orderAutomat.state.error)} onRetry={this.handleRetry} />
|
||||||
|
</PanelTile>
|
||||||
|
</PanelTileGrid>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<OrderSearchField inputRef={this.searchRef} onCreate={this.handleCreate} />
|
<OrderSearchField inputRef={this.searchRef} onCreate={this.handleCreate} />
|
||||||
<PanelTileGrid>
|
<PanelTileGrid>
|
||||||
<PanelTile wide={3} minHeight={0} color={cfg.listColor} sx={{ pb: 0 }}>
|
<PanelTile wide={3} minHeight={0} color={cfg.listColor} sx={{ pb: 0, position: 'relative' }}>
|
||||||
<FillSpace
|
<FillSpace
|
||||||
aboveRef={[this.searchRef]}
|
aboveRef={[this.searchRef]}
|
||||||
reserveBottom={32}
|
reserveBottom={32}
|
||||||
minPageSize={8}
|
minPageSize={8}
|
||||||
minHeight={0}
|
minHeight={0}
|
||||||
items={items}
|
items={items || []}
|
||||||
totalCount={items.length}
|
totalCount={items ? items.length : 0}
|
||||||
renderItem={OrderRow}
|
renderItem={OrderRow}
|
||||||
virtualScrollbar
|
virtualScrollbar
|
||||||
header={
|
header={
|
||||||
@@ -611,6 +613,24 @@ export class OrderList extends PureComponent {
|
|||||||
}
|
}
|
||||||
onPageChange={this.handlePageChange}
|
onPageChange={this.handlePageChange}
|
||||||
/>
|
/>
|
||||||
|
{items === null && (
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
position: 'absolute',
|
||||||
|
top: 52,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
bottom: 32,
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
pointerEvents: 'none',
|
||||||
|
zIndex: 2,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<CircularProgress size={32} />
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
</PanelTile>
|
</PanelTile>
|
||||||
</PanelTileGrid>
|
</PanelTileGrid>
|
||||||
</>
|
</>
|
||||||
|
|||||||
Reference in New Issue
Block a user