Files
khadhroony-bot3/kb-app-demo-desktop/frontend/ts/demo_store_block_pagination.ts

115 lines
3.7 KiB
TypeScript

// file: kb-app-demo-desktop/frontend/ts/demo_store_block_pagination.ts
// version: 1
export type StoreBlockMetadata = {
blockSize: number;
blockIndex: number;
totalRows: string;
totalBlocks: number;
nextCursor: string | null;
};
export type StoreBlockState = {
blockSize: number;
currentBlock: number;
totalBlocks: number;
totalRows: string;
nextCursor: string | null;
cursors: Map<number, string | null>;
};
export type StoreBlockControls = {
firstSelector: string;
previousSelector: string;
nextSelector: string;
summarySelector: string;
};
export function createStoreBlockState(): StoreBlockState {
return {
blockSize: 500,
currentBlock: 0,
totalBlocks: 0,
totalRows: "0",
nextCursor: null,
cursors: new Map<number, string | null>([[1, null]]),
};
}
export function resetStoreBlockState(state: StoreBlockState): void {
state.blockSize = 500;
state.currentBlock = 0;
state.totalBlocks = 0;
state.totalRows = "0";
state.nextCursor = null;
state.cursors = new Map<number, string | null>([[1, null]]);
}
export function applyStoreBlockMetadata(
state: StoreBlockState,
metadata: StoreBlockMetadata,
controls: StoreBlockControls,
): void {
state.blockSize = metadata.blockSize;
state.currentBlock = metadata.blockIndex;
state.totalBlocks = metadata.totalBlocks;
state.totalRows = metadata.totalRows;
state.nextCursor = metadata.nextCursor;
if (metadata.blockIndex > 0 && metadata.nextCursor !== null) {
state.cursors.set(metadata.blockIndex + 1, metadata.nextCursor);
}
renderStoreBlockControls(state, controls);
}
export function renderStoreBlockControls(
state: StoreBlockState,
controls: StoreBlockControls,
): void {
const firstButton = document.querySelector<HTMLButtonElement>(controls.firstSelector);
const previousButton = document.querySelector<HTMLButtonElement>(controls.previousSelector);
const nextButton = document.querySelector<HTMLButtonElement>(controls.nextSelector);
const summary = document.querySelector<HTMLElement>(controls.summarySelector);
const hasRows = state.totalBlocks > 0;
if (firstButton !== null) {
firstButton.disabled = !hasRows || state.currentBlock <= 1;
}
if (previousButton !== null) {
previousButton.disabled = !hasRows || state.currentBlock <= 1;
}
if (nextButton !== null) {
nextButton.disabled = state.nextCursor === null;
}
if (summary !== null) {
summary.textContent = hasRows
? `Bloc ${state.currentBlock} / ${state.totalBlocks} · ${state.totalRows} résultat(s) · ${state.blockSize}/bloc`
: `Bloc 0 / 0 · 0 résultat · ${state.blockSize}/bloc`;
}
}
export function markStoreBlockFiltersDirty(
state: StoreBlockState,
controls: StoreBlockControls,
): void {
resetStoreBlockState(state);
const firstButton = document.querySelector<HTMLButtonElement>(controls.firstSelector);
const previousButton = document.querySelector<HTMLButtonElement>(controls.previousSelector);
const nextButton = document.querySelector<HTMLButtonElement>(controls.nextSelector);
const summary = document.querySelector<HTMLElement>(controls.summarySelector);
if (firstButton !== null) {
firstButton.disabled = true;
}
if (previousButton !== null) {
previousButton.disabled = true;
}
if (nextButton !== null) {
nextButton.disabled = true;
}
if (summary !== null) {
summary.textContent = "Filtres modifiés — rechargez le premier bloc.";
}
}
export function cursorForBlock(state: StoreBlockState, blockIndex: number): string | null | undefined {
return state.cursors.get(blockIndex);
}