@teleporthq/teleport-plugin-next-data-source 0.43.75 → 0.44.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/__tests__/_helpers/first-page-runtime.ts +184 -0
- package/__tests__/_helpers/pagination-widget-fixture.ts +154 -5
- package/__tests__/booking-item-transform.test.ts +120 -0
- package/__tests__/browser-row-policy.test.ts +210 -4
- package/__tests__/data-source-request-locale.test.ts +4 -3
- package/__tests__/fetchers.test.ts +7 -3
- package/__tests__/fixed-list-sort.test.ts +1 -1
- package/__tests__/infinite-scroll.test.ts +363 -9
- package/__tests__/list-sort-order.test.ts +61 -0
- package/__tests__/null-filter-where.test.ts +132 -0
- package/__tests__/page-data-visitor-read.test.ts +196 -0
- package/__tests__/pg-date-parser.test.ts +73 -0
- package/__tests__/plain-list-sort.test.ts +2 -2
- package/__tests__/plain-list-starting-sort.test.ts +323 -0
- package/__tests__/product-price-sort.ts +11 -6
- package/__tests__/range-control.test.ts +159 -0
- package/__tests__/refetch-loading-state.test.ts +158 -2
- package/__tests__/search-input-marker.test.ts +86 -0
- package/__tests__/search-url-sync.test.ts +34 -8
- package/__tests__/starting-sort-first-page.test.ts +285 -0
- package/__tests__/table-read-route-protected-tables.test.ts +33 -3
- package/dist/cjs/cache/ast.d.ts +2 -0
- package/dist/cjs/cache/ast.d.ts.map +1 -1
- package/dist/cjs/cache/ast.js +5 -2
- package/dist/cjs/cache/ast.js.map +1 -1
- package/dist/cjs/count-effect.d.ts +7 -1
- package/dist/cjs/count-effect.d.ts.map +1 -1
- package/dist/cjs/count-effect.js +15 -5
- package/dist/cjs/count-effect.js.map +1 -1
- package/dist/cjs/data-source-fetchers.d.ts.map +1 -1
- package/dist/cjs/data-source-fetchers.js +10 -2
- package/dist/cjs/data-source-fetchers.js.map +1 -1
- package/dist/cjs/fetchers/pg-client-import.d.ts +12 -0
- package/dist/cjs/fetchers/pg-client-import.d.ts.map +1 -0
- package/dist/cjs/fetchers/pg-client-import.js +15 -0
- package/dist/cjs/fetchers/pg-client-import.js.map +1 -0
- package/dist/cjs/fetchers/postgresql.d.ts.map +1 -1
- package/dist/cjs/fetchers/postgresql.js +3 -1
- package/dist/cjs/fetchers/postgresql.js.map +1 -1
- package/dist/cjs/fetchers/raw-query.d.ts.map +1 -1
- package/dist/cjs/fetchers/raw-query.js +2 -1
- package/dist/cjs/fetchers/raw-query.js.map +1 -1
- package/dist/cjs/fetchers/teleport.d.ts.map +1 -1
- package/dist/cjs/fetchers/teleport.js +4 -2
- package/dist/cjs/fetchers/teleport.js.map +1 -1
- package/dist/cjs/fetchers/utils/browser-row-policy.d.ts.map +1 -1
- package/dist/cjs/fetchers/utils/browser-row-policy.js +5 -1
- package/dist/cjs/fetchers/utils/browser-row-policy.js.map +1 -1
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +14 -2
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/infinite-scroll.d.ts +89 -4
- package/dist/cjs/infinite-scroll.d.ts.map +1 -1
- package/dist/cjs/infinite-scroll.js +243 -33
- package/dist/cjs/infinite-scroll.js.map +1 -1
- package/dist/cjs/list-sort-order.d.ts +14 -0
- package/dist/cjs/list-sort-order.d.ts.map +1 -0
- package/dist/cjs/list-sort-order.js +36 -0
- package/dist/cjs/list-sort-order.js.map +1 -0
- package/dist/cjs/loading-state.d.ts +23 -2
- package/dist/cjs/loading-state.d.ts.map +1 -1
- package/dist/cjs/loading-state.js +50 -15
- package/dist/cjs/loading-state.js.map +1 -1
- package/dist/cjs/pagination-controls.d.ts +22 -3
- package/dist/cjs/pagination-controls.d.ts.map +1 -1
- package/dist/cjs/pagination-controls.js +29 -3
- package/dist/cjs/pagination-controls.js.map +1 -1
- package/dist/cjs/pagination-plugin.d.ts.map +1 -1
- package/dist/cjs/pagination-plugin.js +336 -164
- package/dist/cjs/pagination-plugin.js.map +1 -1
- package/dist/cjs/range-control.d.ts +45 -0
- package/dist/cjs/range-control.d.ts.map +1 -0
- package/dist/cjs/range-control.js +165 -0
- package/dist/cjs/range-control.js.map +1 -0
- package/dist/cjs/row-order.d.ts +3 -2
- package/dist/cjs/row-order.d.ts.map +1 -1
- package/dist/cjs/row-order.js +5 -4
- package/dist/cjs/row-order.js.map +1 -1
- package/dist/cjs/search-input.d.ts +42 -0
- package/dist/cjs/search-input.d.ts.map +1 -0
- package/dist/cjs/search-input.js +158 -0
- package/dist/cjs/search-input.js.map +1 -0
- package/dist/cjs/sort-utils.d.ts +53 -1
- package/dist/cjs/sort-utils.d.ts.map +1 -1
- package/dist/cjs/sort-utils.js +105 -13
- package/dist/cjs/sort-utils.js.map +1 -1
- package/dist/cjs/transformations/booking-item.d.ts +24 -0
- package/dist/cjs/transformations/booking-item.d.ts.map +1 -0
- package/dist/cjs/transformations/booking-item.js +27 -0
- package/dist/cjs/transformations/booking-item.js.map +1 -0
- package/dist/cjs/transformations/index.d.ts +4 -2
- package/dist/cjs/transformations/index.d.ts.map +1 -1
- package/dist/cjs/transformations/index.js +14 -5
- package/dist/cjs/transformations/index.js.map +1 -1
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/cjs/utils.d.ts +3 -2
- package/dist/cjs/utils.d.ts.map +1 -1
- package/dist/cjs/utils.js +48 -18
- package/dist/cjs/utils.js.map +1 -1
- package/dist/esm/cache/ast.d.ts +2 -0
- package/dist/esm/cache/ast.d.ts.map +1 -1
- package/dist/esm/cache/ast.js +3 -1
- package/dist/esm/cache/ast.js.map +1 -1
- package/dist/esm/count-effect.d.ts +7 -1
- package/dist/esm/count-effect.d.ts.map +1 -1
- package/dist/esm/count-effect.js +15 -5
- package/dist/esm/count-effect.js.map +1 -1
- package/dist/esm/data-source-fetchers.d.ts.map +1 -1
- package/dist/esm/data-source-fetchers.js +10 -2
- package/dist/esm/data-source-fetchers.js.map +1 -1
- package/dist/esm/fetchers/pg-client-import.d.ts +12 -0
- package/dist/esm/fetchers/pg-client-import.d.ts.map +1 -0
- package/dist/esm/fetchers/pg-client-import.js +12 -0
- package/dist/esm/fetchers/pg-client-import.js.map +1 -0
- package/dist/esm/fetchers/postgresql.d.ts.map +1 -1
- package/dist/esm/fetchers/postgresql.js +3 -1
- package/dist/esm/fetchers/postgresql.js.map +1 -1
- package/dist/esm/fetchers/raw-query.d.ts.map +1 -1
- package/dist/esm/fetchers/raw-query.js +2 -1
- package/dist/esm/fetchers/raw-query.js.map +1 -1
- package/dist/esm/fetchers/teleport.d.ts.map +1 -1
- package/dist/esm/fetchers/teleport.js +4 -2
- package/dist/esm/fetchers/teleport.js.map +1 -1
- package/dist/esm/fetchers/utils/browser-row-policy.d.ts.map +1 -1
- package/dist/esm/fetchers/utils/browser-row-policy.js +6 -2
- package/dist/esm/fetchers/utils/browser-row-policy.js.map +1 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +14 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/infinite-scroll.d.ts +89 -4
- package/dist/esm/infinite-scroll.d.ts.map +1 -1
- package/dist/esm/infinite-scroll.js +237 -32
- package/dist/esm/infinite-scroll.js.map +1 -1
- package/dist/esm/list-sort-order.d.ts +14 -0
- package/dist/esm/list-sort-order.d.ts.map +1 -0
- package/dist/esm/list-sort-order.js +32 -0
- package/dist/esm/list-sort-order.js.map +1 -0
- package/dist/esm/loading-state.d.ts +23 -2
- package/dist/esm/loading-state.d.ts.map +1 -1
- package/dist/esm/loading-state.js +50 -15
- package/dist/esm/loading-state.js.map +1 -1
- package/dist/esm/pagination-controls.d.ts +22 -3
- package/dist/esm/pagination-controls.d.ts.map +1 -1
- package/dist/esm/pagination-controls.js +28 -2
- package/dist/esm/pagination-controls.js.map +1 -1
- package/dist/esm/pagination-plugin.d.ts.map +1 -1
- package/dist/esm/pagination-plugin.js +340 -168
- package/dist/esm/pagination-plugin.js.map +1 -1
- package/dist/esm/range-control.d.ts +45 -0
- package/dist/esm/range-control.d.ts.map +1 -0
- package/dist/esm/range-control.js +137 -0
- package/dist/esm/range-control.js.map +1 -0
- package/dist/esm/row-order.d.ts +3 -2
- package/dist/esm/row-order.d.ts.map +1 -1
- package/dist/esm/row-order.js +5 -4
- package/dist/esm/row-order.js.map +1 -1
- package/dist/esm/search-input.d.ts +42 -0
- package/dist/esm/search-input.d.ts.map +1 -0
- package/dist/esm/search-input.js +129 -0
- package/dist/esm/search-input.js.map +1 -0
- package/dist/esm/sort-utils.d.ts +53 -1
- package/dist/esm/sort-utils.d.ts.map +1 -1
- package/dist/esm/sort-utils.js +100 -12
- package/dist/esm/sort-utils.js.map +1 -1
- package/dist/esm/transformations/booking-item.d.ts +24 -0
- package/dist/esm/transformations/booking-item.d.ts.map +1 -0
- package/dist/esm/transformations/booking-item.js +23 -0
- package/dist/esm/transformations/booking-item.js.map +1 -0
- package/dist/esm/transformations/index.d.ts +4 -2
- package/dist/esm/transformations/index.d.ts.map +1 -1
- package/dist/esm/transformations/index.js +14 -5
- package/dist/esm/transformations/index.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/utils.d.ts +3 -2
- package/dist/esm/utils.d.ts.map +1 -1
- package/dist/esm/utils.js +49 -19
- package/dist/esm/utils.js.map +1 -1
- package/package.json +5 -5
- package/src/cache/ast.ts +4 -1
- package/src/count-effect.ts +31 -8
- package/src/data-source-fetchers.ts +33 -14
- package/src/fetchers/pg-client-import.ts +16 -0
- package/src/fetchers/postgresql.ts +15 -9
- package/src/fetchers/raw-query.ts +2 -1
- package/src/fetchers/teleport.ts +19 -10
- package/src/fetchers/utils/browser-row-policy.ts +79 -5
- package/src/index.ts +8 -2
- package/src/infinite-scroll.ts +420 -81
- package/src/list-sort-order.ts +34 -0
- package/src/loading-state.ts +85 -13
- package/src/pagination-controls.ts +26 -3
- package/src/pagination-plugin.ts +532 -218
- package/src/range-control.ts +207 -0
- package/src/row-order.ts +5 -4
- package/src/search-input.ts +190 -0
- package/src/sort-utils.ts +164 -21
- package/src/transformations/booking-item.ts +71 -0
- package/src/transformations/index.ts +25 -2
- package/src/utils.ts +55 -18
|
@@ -85,6 +85,8 @@ var loading_state_1 = require("./loading-state");
|
|
|
85
85
|
var config_1 = require("./cache/config");
|
|
86
86
|
var ast_1 = require("./cache/ast");
|
|
87
87
|
var pagination_controls_1 = require("./pagination-controls");
|
|
88
|
+
var range_control_1 = require("./range-control");
|
|
89
|
+
var search_input_1 = require("./search-input");
|
|
88
90
|
var count_effect_1 = require("./count-effect");
|
|
89
91
|
var search_clear_1 = require("./search-clear");
|
|
90
92
|
var numbered_pagination_1 = require("./numbered-pagination");
|
|
@@ -299,7 +301,7 @@ function buildFilterDestinationExpression(destination) {
|
|
|
299
301
|
return teleport_plugin_common_1.ASTUtils.convertFilterDestinationToExpression(destination);
|
|
300
302
|
}
|
|
301
303
|
// Scan UIDL to find all data source usages and build a registry
|
|
302
|
-
function buildStateRegistry(uidlNode) {
|
|
304
|
+
function buildStateRegistry(uidlNode, stateDefinitions) {
|
|
303
305
|
var usages = [];
|
|
304
306
|
var byDataSourceId = new Map();
|
|
305
307
|
var byArrayMapperRenderProp = new Map();
|
|
@@ -356,16 +358,19 @@ function buildStateRegistry(uidlNode) {
|
|
|
356
358
|
// is skipped for a dynamic sort) — the pre-rendered HTML carried no
|
|
357
359
|
// posts, and the browser fetched page 1 a second time. Only a sort
|
|
358
360
|
// bound to state (the admin panel's sortable columns) is dynamic.
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
361
|
+
//
|
|
362
|
+
// A sort the visitor picks still starts somewhere — the store's sort
|
|
363
|
+
// dropdown at "Name A-Z". Known at build time, it orders the
|
|
364
|
+
// server-side first page, which the list then shows while the visitor
|
|
365
|
+
// leaves the sort alone. Read as a plain list's page fetch reads it.
|
|
366
|
+
var repeaterSort = !sorts || sorts.length === 0
|
|
367
|
+
? (0, sort_utils_1.readRepeaterSort)(content.sort, content.sortDirection, stateDefinitions)
|
|
368
|
+
: {};
|
|
369
|
+
if (repeaterSort.fixed) {
|
|
370
|
+
sorts = [repeaterSort.fixed];
|
|
368
371
|
}
|
|
372
|
+
var dynamicSort = repeaterSort.dynamic;
|
|
373
|
+
var startingSort = repeaterSort.starting;
|
|
369
374
|
// Extract filters from parent's resource params, keeping the group tree
|
|
370
375
|
// the inspector authored (see `readFilterTree`).
|
|
371
376
|
var filters = [];
|
|
@@ -433,6 +438,7 @@ function buildStateRegistry(uidlNode) {
|
|
|
433
438
|
index: index++,
|
|
434
439
|
dataSourceIdentifier: parentDataSource.identifier,
|
|
435
440
|
arrayMapperRenderProp: arrayMapperRenderProp,
|
|
441
|
+
nodeId: typeof content.nodeId === 'string' ? content.nodeId : undefined,
|
|
436
442
|
resourceDefinition: {
|
|
437
443
|
dataSourceId: parentDataSource.resourceDef.dataSourceId || '',
|
|
438
444
|
tableName: parentDataSource.resourceDef.tableName || '',
|
|
@@ -447,6 +453,7 @@ function buildStateRegistry(uidlNode) {
|
|
|
447
453
|
queryColumns: queryColumns,
|
|
448
454
|
sorts: sorts,
|
|
449
455
|
dynamicSort: dynamicSort,
|
|
456
|
+
startingSort: startingSort,
|
|
450
457
|
filters: filters,
|
|
451
458
|
filterStateIds: filterStateIds,
|
|
452
459
|
filterPropIds: filterPropIds,
|
|
@@ -528,6 +535,8 @@ function getStateVarsForUsage(usage) {
|
|
|
528
535
|
setPageStateVar: "setDs_".concat(idx, "_page"),
|
|
529
536
|
maxPagesStateVar: "ds_".concat(idx, "_maxPages"),
|
|
530
537
|
setMaxPagesStateVar: "setDs_".concat(idx, "_maxPages"),
|
|
538
|
+
totalStateVar: "ds_".concat(idx, "_total"),
|
|
539
|
+
setTotalStateVar: "setDs_".concat(idx, "_total"),
|
|
531
540
|
searchQueryVar: "ds_".concat(idx, "_searchQuery"),
|
|
532
541
|
setSearchQueryVar: "setDs_".concat(idx, "_searchQuery"),
|
|
533
542
|
debouncedSearchQueryVar: "ds_".concat(idx, "_debouncedQuery"),
|
|
@@ -605,19 +614,27 @@ function pushSearchUrlSyncEffects(effectStatements, usage, vars) {
|
|
|
605
614
|
effectStatements.push(teleport_plugin_common_1.URLSearchParamSync.buildUrlWriteBackEffect(usage.searchUrlParamKey, buildDebouncedValueExpr(), buildDebouncedValueExpr(), undefined, adoptedRefVar));
|
|
606
615
|
// read-back: `?<searchUrlParamKey>=` → the input AND the applied query at once
|
|
607
616
|
// (`ds_N_adoptUrlSearch`), so an address is not a typed change: it skips the
|
|
608
|
-
// debounce and keeps
|
|
617
|
+
// debounce and keeps a page the address carries — `?searchKeyword=x&page=3`
|
|
618
|
+
// lands on page 3.
|
|
609
619
|
effectStatements.push(teleport_plugin_common_1.URLSearchParamSync.buildUrlReadBackEffect(usage.searchUrlParamKey, adopterVar, undefined, adoptedRefVar));
|
|
610
620
|
}
|
|
611
621
|
// `const ds_N_adoptUrlSearch = (update) => { … }`: the setter the search's URL
|
|
612
622
|
// read-back calls with its `(prev) => next` updater. It moves the input and the
|
|
613
|
-
// applied (debounced) query together
|
|
614
|
-
// page
|
|
623
|
+
// applied (debounced) query together. A list whose page is in the address
|
|
624
|
+
// keeps its page — the page sync sets it from the same address. Any other
|
|
625
|
+
// list starts the new query on page 1, as a typed change does in the debounce
|
|
626
|
+
// effect: an appending list has usually advanced past page 1 by the time the
|
|
627
|
+
// router is ready, and the query's first answer would otherwise be its page 2
|
|
628
|
+
// — empty for a query only a few rows match.
|
|
615
629
|
function buildUrlSearchAdopter(adopterVar, usage, vars) {
|
|
616
630
|
var update = types.identifier('update');
|
|
631
|
+
var pageReset = usageHasPageUrlSync(usage)
|
|
632
|
+
? []
|
|
633
|
+
: [types.objectProperty(types.identifier('page'), types.numericLiteral(1))];
|
|
617
634
|
var applyToDebounced = usage.category === 'paginated+search'
|
|
618
635
|
? // setDs_N_state((state) => {
|
|
619
636
|
// const next = update(state.debouncedQuery)
|
|
620
|
-
// return next === state.debouncedQuery ? state : { ...state, debouncedQuery: next }
|
|
637
|
+
// return next === state.debouncedQuery ? state : { ...state, page: 1, debouncedQuery: next }
|
|
621
638
|
// })
|
|
622
639
|
types.callExpression(types.identifier(vars.setCombinedStateVar), [
|
|
623
640
|
types.arrowFunctionExpression([types.identifier('state')], types.blockStatement([
|
|
@@ -626,10 +643,11 @@ function buildUrlSearchAdopter(adopterVar, usage, vars) {
|
|
|
626
643
|
types.memberExpression(types.identifier('state'), types.identifier('debouncedQuery')),
|
|
627
644
|
])),
|
|
628
645
|
]),
|
|
629
|
-
types.returnStatement(types.conditionalExpression(types.binaryExpression('===', types.identifier('next'), types.memberExpression(types.identifier('state'), types.identifier('debouncedQuery'))), types.identifier('state'), types.objectExpression([
|
|
630
|
-
types.spreadElement(types.identifier('state'))
|
|
646
|
+
types.returnStatement(types.conditionalExpression(types.binaryExpression('===', types.identifier('next'), types.memberExpression(types.identifier('state'), types.identifier('debouncedQuery'))), types.identifier('state'), types.objectExpression(__spreadArray(__spreadArray([
|
|
647
|
+
types.spreadElement(types.identifier('state'))
|
|
648
|
+
], pageReset, true), [
|
|
631
649
|
types.objectProperty(types.identifier('debouncedQuery'), types.identifier('next')),
|
|
632
|
-
]))),
|
|
650
|
+
], false)))),
|
|
633
651
|
])),
|
|
634
652
|
])
|
|
635
653
|
: types.callExpression(types.identifier(vars.setDebouncedSearchQueryVar), [update]);
|
|
@@ -792,7 +810,7 @@ function pushFilterSortPageResetEffect(stateDeclarations, effectStatements, usag
|
|
|
792
810
|
// ==================== MAIN PLUGIN ====================
|
|
793
811
|
var createNextArrayMapperPaginationPlugin = function () {
|
|
794
812
|
var paginationPlugin = function (structure) { return __awaiter(void 0, void 0, void 0, function () {
|
|
795
|
-
var uidl, chunks, dependencies, options, componentChunk, variableDeclaration, declarator, arrowFunction, blockStatement, registry, getStaticPropsChunk, isPage, localized, stateDeclarations, effectStatements, needsUseRouter, returnIndex, insertIndex, dataProviders, dataProvidersWithRepeaters, usageIndexByDataSourceId, loadingStateDeclarations, usagesWithLoadingState, usageByProviderNode, cacheDeclarations, sharedOptions, cachedScopes, dataProvidersWithoutRepeaters, searchInputs,
|
|
813
|
+
var uidl, chunks, dependencies, options, componentChunk, variableDeclaration, declarator, arrowFunction, blockStatement, rangeControls, hasRangeControl, registry, getStaticPropsChunk, isPage, localized, stateDeclarations, effectStatements, needsUseRouter, returnIndex, insertIndex, dataProviders, dataProvidersWithRepeaters, usageIndexByDataSourceId, loadingStateDeclarations, usagesWithLoadingState, usageByProviderNode, cacheDeclarations, firstPageDeclarations, sharedOptions, cachedScopes, dataProvidersWithoutRepeaters, searchInputs, usageBySearchInput, _i, searchInputs_1, input, usage;
|
|
796
814
|
var _a, _b;
|
|
797
815
|
return __generator(this, function (_c) {
|
|
798
816
|
uidl = structure.uidl, chunks = structure.chunks, dependencies = structure.dependencies, options = structure.options;
|
|
@@ -816,7 +834,9 @@ var createNextArrayMapperPaginationPlugin = function () {
|
|
|
816
834
|
return [2 /*return*/, structure];
|
|
817
835
|
}
|
|
818
836
|
blockStatement = arrowFunction.body;
|
|
819
|
-
|
|
837
|
+
rangeControls = (0, range_control_1.findRangeControls)(blockStatement);
|
|
838
|
+
hasRangeControl = rangeControls.length > 0;
|
|
839
|
+
registry = buildStateRegistry(uidl.node, uidl.stateDefinitions);
|
|
820
840
|
if (registry.usages.length === 0) {
|
|
821
841
|
return [2 /*return*/, structure];
|
|
822
842
|
}
|
|
@@ -984,11 +1004,15 @@ var createNextArrayMapperPaginationPlugin = function () {
|
|
|
984
1004
|
(0, filter_utils_1.pushPropIdsAsDeps)(countEffectDeps, countEffectSeen, usage.filterPropIds);
|
|
985
1005
|
// Same goes for URL-driven filters (already documented above).
|
|
986
1006
|
pushUrlSearchParamMemoDeps(countEffectDeps, usage);
|
|
1007
|
+
if (hasRangeControl) {
|
|
1008
|
+
stateDeclarations.push(buildTotalDeclaration(vars));
|
|
1009
|
+
}
|
|
987
1010
|
stateDeclarations.push((0, count_effect_1.buildCountSeqDeclaration)(vars.countSeqRefVar));
|
|
988
1011
|
effectStatements.push((0, count_effect_1.buildCountFetchEffect)({
|
|
989
1012
|
fileName: fileName,
|
|
990
1013
|
perPage: usage.perPage,
|
|
991
1014
|
setMaxPagesVar: vars.setMaxPagesStateVar,
|
|
1015
|
+
setTotalVar: hasRangeControl ? vars.setTotalStateVar : undefined,
|
|
992
1016
|
urlParams: urlParams,
|
|
993
1017
|
deps: countEffectDeps,
|
|
994
1018
|
countSeqRefVar: vars.countSeqRefVar,
|
|
@@ -1030,7 +1054,9 @@ var createNextArrayMapperPaginationPlugin = function () {
|
|
|
1030
1054
|
// "Next" button, but not to label a numbered strip or to know when an
|
|
1031
1055
|
// infinite list has reached its end, so those two modes fetch a live
|
|
1032
1056
|
// count as well.
|
|
1033
|
-
|
|
1057
|
+
// A range text needs the live count too: the build-time count only
|
|
1058
|
+
// ever became a page count, never the total it shows.
|
|
1059
|
+
var needsLiveCount = !isPage || usage.paginationMode === 'numbered' || usage.infiniteScroll || hasRangeControl;
|
|
1034
1060
|
if (needsLiveCount) {
|
|
1035
1061
|
var fileName = (0, utils_1.generateSafeFileName)(usage.resourceDefinition.dataSourceType, usage.resourceDefinition.tableName, usage.resourceDefinition.dataSourceId);
|
|
1036
1062
|
// ⛔ This list has no search input, so no `query` param — but it may
|
|
@@ -1052,11 +1078,15 @@ var createNextArrayMapperPaginationPlugin = function () {
|
|
|
1052
1078
|
(0, filter_utils_1.pushStateIdsAsDeps)(countDeps, countDepsSeen, usage.filterStateIds);
|
|
1053
1079
|
(0, filter_utils_1.pushPropIdsAsDeps)(countDeps, countDepsSeen, usage.filterPropIds);
|
|
1054
1080
|
pushUrlSearchParamMemoDeps(countDeps, usage);
|
|
1081
|
+
if (hasRangeControl) {
|
|
1082
|
+
stateDeclarations.push(buildTotalDeclaration(vars));
|
|
1083
|
+
}
|
|
1055
1084
|
stateDeclarations.push((0, count_effect_1.buildCountSeqDeclaration)(vars.countSeqRefVar));
|
|
1056
1085
|
effectStatements.push((0, count_effect_1.buildCountFetchEffect)({
|
|
1057
1086
|
fileName: fileName,
|
|
1058
1087
|
perPage: usage.perPage,
|
|
1059
1088
|
setMaxPagesVar: vars.setMaxPagesStateVar,
|
|
1089
|
+
setTotalVar: hasRangeControl ? vars.setTotalStateVar : undefined,
|
|
1060
1090
|
urlParams: countUrlParams,
|
|
1061
1091
|
deps: countDeps,
|
|
1062
1092
|
countSeqRefVar: vars.countSeqRefVar,
|
|
@@ -1141,6 +1171,7 @@ var createNextArrayMapperPaginationPlugin = function () {
|
|
|
1141
1171
|
usagesWithLoadingState = new Set();
|
|
1142
1172
|
usageByProviderNode = new Map();
|
|
1143
1173
|
cacheDeclarations = [];
|
|
1174
|
+
firstPageDeclarations = isPage ? [] : undefined;
|
|
1144
1175
|
dataProvidersWithRepeaters.forEach(function (dp) {
|
|
1145
1176
|
var _a, _b;
|
|
1146
1177
|
var nameAttr = dp.openingElement.attributes.find(function (attr) { return attr.type === 'JSXAttribute' && attr.name.name === 'name'; });
|
|
@@ -1161,10 +1192,10 @@ var createNextArrayMapperPaginationPlugin = function () {
|
|
|
1161
1192
|
var fileName = (0, utils_1.generateSafeFileName)(usage.resourceDefinition.dataSourceType, usage.resourceDefinition.tableName, usage.resourceDefinition.dataSourceId);
|
|
1162
1193
|
// Update DataProvider based on category
|
|
1163
1194
|
if (usage.category === 'paginated+search') {
|
|
1164
|
-
updateDataProviderForPaginatedSearch(dp, usage, vars, fileName, cacheDeclarations, localized);
|
|
1195
|
+
updateDataProviderForPaginatedSearch(dp, usage, vars, fileName, cacheDeclarations, localized, firstPageDeclarations);
|
|
1165
1196
|
}
|
|
1166
1197
|
else if (usage.category === 'paginated-only') {
|
|
1167
|
-
updateDataProviderForPaginationOnly(dp, usage, vars, fileName, cacheDeclarations, localized);
|
|
1198
|
+
updateDataProviderForPaginationOnly(dp, usage, vars, fileName, cacheDeclarations, localized, firstPageDeclarations);
|
|
1168
1199
|
}
|
|
1169
1200
|
else if (usage.category === 'search-only') {
|
|
1170
1201
|
updateDataProviderForSearchOnly(dp, usage, vars, fileName, cacheDeclarations, localized);
|
|
@@ -1176,9 +1207,14 @@ var createNextArrayMapperPaginationPlugin = function () {
|
|
|
1176
1207
|
// change refetches, instead of leaving the previous rows on screen with
|
|
1177
1208
|
// no feedback. Runs last so it sees the `fetchData` and
|
|
1178
1209
|
// `persistDataDuringLoading` attributes the updaters above just wrote.
|
|
1210
|
+
// An appending list keeps its rows on screen while its next page loads;
|
|
1211
|
+
// only a list loading afresh falls through to the loading slot.
|
|
1179
1212
|
var loadingVars = (0, loading_state_1.getLoadingStateVars)(usage.index);
|
|
1180
|
-
|
|
1181
|
-
|
|
1213
|
+
var appendingRequest = usage.infiniteScroll && usage.paginated
|
|
1214
|
+
? (0, infinite_scroll_1.buildAppendingRequestCheck)((0, infinite_scroll_1.getInfiniteScrollVars)(usage.index))
|
|
1215
|
+
: undefined;
|
|
1216
|
+
if ((0, loading_state_1.applyLoadingStateToDataProvider)(dp, loadingVars, appendingRequest)) {
|
|
1217
|
+
loadingStateDeclarations.push.apply(loadingStateDeclarations, (0, loading_state_1.buildLoadingStateDeclarations)(loadingVars, !!appendingRequest));
|
|
1182
1218
|
// Recorded because the loading state is only declared for a provider
|
|
1183
1219
|
// that HAS a loading slot; a Load More button wired later may only
|
|
1184
1220
|
// reference `ds_N_isFetching` if it actually exists.
|
|
@@ -1187,7 +1223,9 @@ var createNextArrayMapperPaginationPlugin = function () {
|
|
|
1187
1223
|
// An auto-loading list needs something at the end of the rows for its
|
|
1188
1224
|
// IntersectionObserver to watch.
|
|
1189
1225
|
if (usage.infiniteScroll && usage.paginated && !usage.infiniteScrollLoadMore) {
|
|
1190
|
-
insertSentinelAfterProvider(blockStatement, dp, (
|
|
1226
|
+
insertSentinelAfterProvider(blockStatement, dp, function (parentTag) {
|
|
1227
|
+
return (0, infinite_scroll_1.buildSentinelElement)((0, infinite_scroll_1.getInfiniteScrollVars)(usage.index), parentTag);
|
|
1228
|
+
});
|
|
1191
1229
|
}
|
|
1192
1230
|
// Create API route for all categories (including 'plain' for components)
|
|
1193
1231
|
ensureAPIRouteExists(options.extractedResources, usage, options.dataSources, (0, transformations_1.buildProductTransformOptions)(options));
|
|
@@ -1221,6 +1259,11 @@ var createNextArrayMapperPaginationPlugin = function () {
|
|
|
1221
1259
|
teleport_shared_1.ASTStatementOrder.insertStatementsAfterDependencies(blockStatement, cacheDeclarations);
|
|
1222
1260
|
(0, ast_1.registerCacheClientImports)(dependencies, (_a = uidl.outputOptions) === null || _a === void 0 ? void 0 : _a.folderPath);
|
|
1223
1261
|
}
|
|
1262
|
+
// After the cache declarations: a cached list's first page reads the
|
|
1263
|
+
// `ds_N_params` they hoisted.
|
|
1264
|
+
if (firstPageDeclarations === null || firstPageDeclarations === void 0 ? void 0 : firstPageDeclarations.length) {
|
|
1265
|
+
teleport_shared_1.ASTStatementOrder.insertStatementsAfterDependencies(blockStatement, firstPageDeclarations);
|
|
1266
|
+
}
|
|
1224
1267
|
dataProvidersWithoutRepeaters = dataProviders.filter(function (dp) {
|
|
1225
1268
|
var hasRepeater = findArrayMapperRenderPropInDataProvider(dp) !== undefined;
|
|
1226
1269
|
return !hasRepeater;
|
|
@@ -1228,18 +1271,15 @@ var createNextArrayMapperPaginationPlugin = function () {
|
|
|
1228
1271
|
dataProvidersWithoutRepeaters.forEach(function (dp) {
|
|
1229
1272
|
stabilizeDataProviderWithoutRepeater(dp);
|
|
1230
1273
|
});
|
|
1231
|
-
searchInputs = findAllSearchInputsInJSX(blockStatement);
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1274
|
+
searchInputs = (0, search_input_1.findAllSearchInputsInJSX)(blockStatement);
|
|
1275
|
+
usageBySearchInput = (0, search_input_1.pairSearchInputs)(searchInputs, registry.usages);
|
|
1276
|
+
for (_i = 0, searchInputs_1 = searchInputs; _i < searchInputs_1.length; _i++) {
|
|
1277
|
+
input = searchInputs_1[_i];
|
|
1278
|
+
usage = usageBySearchInput.get(input.node);
|
|
1279
|
+
if (usage) {
|
|
1280
|
+
(0, search_input_1.wireSearchInput)(input, getStateVarsForUsage(usage));
|
|
1237
1281
|
}
|
|
1238
|
-
|
|
1239
|
-
var vars = getStateVarsForUsage(usage);
|
|
1240
|
-
wireSearchInput(input.node, vars);
|
|
1241
|
-
usageBySearchInput.set(input.node, usage);
|
|
1242
|
-
});
|
|
1282
|
+
}
|
|
1243
1283
|
// STEP 4.5: Wire the clear buttons, each to the input it shares a parent with.
|
|
1244
1284
|
(0, search_clear_1.findAllSearchClearButtonsInJSX)(blockStatement).forEach(function (button) {
|
|
1245
1285
|
var input = (0, search_clear_1.findSiblingSearchInput)(button, searchInputs.map(function (entry) { return entry.node; }));
|
|
@@ -1266,9 +1306,29 @@ var createNextArrayMapperPaginationPlugin = function () {
|
|
|
1266
1306
|
}
|
|
1267
1307
|
wirePaginationWidget(node, usage, getStateVarsForUsage(usage), usagesWithLoadingState.has(usage.index));
|
|
1268
1308
|
});
|
|
1269
|
-
// STEP
|
|
1309
|
+
// STEP 5b: Wire the range texts that name their mapper.
|
|
1310
|
+
//
|
|
1311
|
+
// A `range` control carrying `data-tq-pagination-for` belongs to the mapper
|
|
1312
|
+
// whose editor node id it names, wherever it sits — a template's footer or
|
|
1313
|
+
// toolbar is laid out by the author, not inside a pagination container, so
|
|
1314
|
+
// the container-ownership rule above cannot reach it. One without the
|
|
1315
|
+
// attribute was wired by its container in STEP 5; one naming a mapper this
|
|
1316
|
+
// component does not render stays as drawn.
|
|
1317
|
+
rangeControls.forEach(function (control) {
|
|
1318
|
+
var ownerNodeId = (0, pagination_controls_1.readJSXAttributeString)(control, pagination_controls_1.PAGINATION_FOR_ATTR);
|
|
1319
|
+
if (!ownerNodeId) {
|
|
1320
|
+
return;
|
|
1321
|
+
}
|
|
1322
|
+
var owner = registry.usages.find(function (usage) { return usage.nodeId === ownerNodeId; });
|
|
1323
|
+
if (owner) {
|
|
1324
|
+
wireRangeControlFor(control, owner, getStateVarsForUsage(owner));
|
|
1325
|
+
}
|
|
1326
|
+
});
|
|
1327
|
+
// STEP 6: Update getStaticProps if this is a page. Its rows are what the
|
|
1328
|
+
// page renders, so they are read as a visitor is served them — unless only
|
|
1329
|
+
// the store's trusted readers can open the page (`pageDataReadArguments`).
|
|
1270
1330
|
if (isPage) {
|
|
1271
|
-
updateGetStaticProps(chunks, registry, dependencies, (_b = uidl.outputOptions) === null || _b === void 0 ? void 0 : _b.folderPath, localized);
|
|
1331
|
+
updateGetStaticProps(chunks, registry, dependencies, (_b = uidl.outputOptions) === null || _b === void 0 ? void 0 : _b.folderPath, localized, function () { return teleport_plugin_common_1.RouteUtils.pageDataReadArguments(uidl, options.auth); });
|
|
1272
1332
|
}
|
|
1273
1333
|
return [2 /*return*/, structure];
|
|
1274
1334
|
});
|
|
@@ -1284,39 +1344,59 @@ exports.createNextArrayMapperPaginationPlugin = createNextArrayMapperPaginationP
|
|
|
1284
1344
|
* It has to be a sibling: the provider's own child is a render-prop function,
|
|
1285
1345
|
* and anything placed inside it would be re-created on every fetch — the
|
|
1286
1346
|
* observer would then be watching an element that is no longer in the document.
|
|
1347
|
+
* The sentinel is built for the element it lands in (`buildSentinelElement`):
|
|
1348
|
+
* a fragment is transparent, a component's children may go anywhere.
|
|
1287
1349
|
*
|
|
1288
1350
|
* Returns false when the provider has no element parent to splice into (a
|
|
1289
1351
|
* provider returned directly from the component), leaving the list on its
|
|
1290
1352
|
* count-driven `hasMore` rather than injecting a stray node.
|
|
1291
1353
|
*/
|
|
1292
|
-
function insertSentinelAfterProvider(blockStatement, provider,
|
|
1354
|
+
function insertSentinelAfterProvider(blockStatement, provider, buildSentinel) {
|
|
1293
1355
|
var inserted = false;
|
|
1294
|
-
var
|
|
1356
|
+
var elementTagOf = function (node, enclosing) {
|
|
1357
|
+
var _a;
|
|
1358
|
+
if ((node === null || node === void 0 ? void 0 : node.type) === 'JSXFragment') {
|
|
1359
|
+
return enclosing;
|
|
1360
|
+
}
|
|
1361
|
+
if ((node === null || node === void 0 ? void 0 : node.type) !== 'JSXElement') {
|
|
1362
|
+
return enclosing;
|
|
1363
|
+
}
|
|
1364
|
+
var name = (_a = node.openingElement) === null || _a === void 0 ? void 0 : _a.name;
|
|
1365
|
+
if ((name === null || name === void 0 ? void 0 : name.type) !== 'JSXIdentifier') {
|
|
1366
|
+
return null;
|
|
1367
|
+
}
|
|
1368
|
+
if (name.name === 'Fragment') {
|
|
1369
|
+
return enclosing;
|
|
1370
|
+
}
|
|
1371
|
+
return /^[a-z]/.test(name.name) ? name.name : null;
|
|
1372
|
+
};
|
|
1373
|
+
var traverse = function (node, enclosing) {
|
|
1295
1374
|
if (!node || inserted) {
|
|
1296
1375
|
return;
|
|
1297
1376
|
}
|
|
1377
|
+
var tag = elementTagOf(node, enclosing);
|
|
1298
1378
|
if (Array.isArray(node.children)) {
|
|
1299
1379
|
var at = node.children.indexOf(provider);
|
|
1300
1380
|
if (at !== -1) {
|
|
1301
|
-
node.children.splice(at + 1, 0,
|
|
1381
|
+
node.children.splice(at + 1, 0, buildSentinel(tag));
|
|
1302
1382
|
inserted = true;
|
|
1303
1383
|
return;
|
|
1304
1384
|
}
|
|
1305
|
-
node.children.forEach(traverse);
|
|
1385
|
+
node.children.forEach(function (child) { return traverse(child, tag); });
|
|
1306
1386
|
}
|
|
1307
1387
|
if (node.body) {
|
|
1308
1388
|
if (Array.isArray(node.body)) {
|
|
1309
|
-
node.body.forEach(traverse);
|
|
1389
|
+
node.body.forEach(function (child) { return traverse(child, tag); });
|
|
1310
1390
|
}
|
|
1311
1391
|
else {
|
|
1312
|
-
traverse(node.body);
|
|
1392
|
+
traverse(node.body, tag);
|
|
1313
1393
|
}
|
|
1314
1394
|
}
|
|
1315
1395
|
if (node.consequent) {
|
|
1316
|
-
traverse(node.consequent);
|
|
1396
|
+
traverse(node.consequent, tag);
|
|
1317
1397
|
}
|
|
1318
1398
|
if (node.alternate) {
|
|
1319
|
-
traverse(node.alternate);
|
|
1399
|
+
traverse(node.alternate, tag);
|
|
1320
1400
|
}
|
|
1321
1401
|
// `{activeTabIndex === 0 && (<div>…<DataProvider/>…</div>)}` — a tab
|
|
1322
1402
|
// panel, a gated section: the provider sits on the RIGHT of a logical
|
|
@@ -1324,22 +1404,22 @@ function insertSentinelAfterProvider(blockStatement, provider, sentinel) {
|
|
|
1324
1404
|
// an argument. Left unvisited, the products list under the first tab of
|
|
1325
1405
|
// a shop was never paginated or seeded, and rendered nothing.
|
|
1326
1406
|
if (node.left) {
|
|
1327
|
-
traverse(node.left);
|
|
1407
|
+
traverse(node.left, tag);
|
|
1328
1408
|
}
|
|
1329
1409
|
if (node.right) {
|
|
1330
|
-
traverse(node.right);
|
|
1410
|
+
traverse(node.right, tag);
|
|
1331
1411
|
}
|
|
1332
1412
|
if (node.test) {
|
|
1333
|
-
traverse(node.test);
|
|
1413
|
+
traverse(node.test, tag);
|
|
1334
1414
|
}
|
|
1335
1415
|
if (node.expression) {
|
|
1336
|
-
traverse(node.expression);
|
|
1416
|
+
traverse(node.expression, tag);
|
|
1337
1417
|
}
|
|
1338
1418
|
if (node.argument) {
|
|
1339
|
-
traverse(node.argument);
|
|
1419
|
+
traverse(node.argument, tag);
|
|
1340
1420
|
}
|
|
1341
1421
|
};
|
|
1342
|
-
traverse(blockStatement);
|
|
1422
|
+
traverse(blockStatement, null);
|
|
1343
1423
|
return inserted;
|
|
1344
1424
|
}
|
|
1345
1425
|
function findAllDataProvidersInJSX(blockStatement) {
|
|
@@ -1434,61 +1514,6 @@ function findArrayMapperRenderPropInDataProvider(dataProvider) {
|
|
|
1434
1514
|
}
|
|
1435
1515
|
return renderItemAttr.value.expression.params[0].name;
|
|
1436
1516
|
}
|
|
1437
|
-
function findAllSearchInputsInJSX(blockStatement) {
|
|
1438
|
-
var results = [];
|
|
1439
|
-
var traverse = function (node) {
|
|
1440
|
-
var _a, _b, _c, _d, _e, _f;
|
|
1441
|
-
if (!node) {
|
|
1442
|
-
return;
|
|
1443
|
-
}
|
|
1444
|
-
if (node.type === 'JSXElement' && ((_b = (_a = node.openingElement) === null || _a === void 0 ? void 0 : _a.name) === null || _b === void 0 ? void 0 : _b.name) === 'input') {
|
|
1445
|
-
var classAttr = (_c = node.openingElement.attributes) === null || _c === void 0 ? void 0 : _c.find(function (attr) { return attr.type === 'JSXAttribute' && attr.name.name === 'className'; });
|
|
1446
|
-
var className = ((_d = classAttr === null || classAttr === void 0 ? void 0 : classAttr.value) === null || _d === void 0 ? void 0 : _d.value) || ((_f = (_e = classAttr === null || classAttr === void 0 ? void 0 : classAttr.value) === null || _e === void 0 ? void 0 : _e.expression) === null || _f === void 0 ? void 0 : _f.value) || '';
|
|
1447
|
-
if (className.includes('search-input')) {
|
|
1448
|
-
results.push({ node: node, className: className });
|
|
1449
|
-
}
|
|
1450
|
-
}
|
|
1451
|
-
if (node.children && Array.isArray(node.children)) {
|
|
1452
|
-
node.children.forEach(function (c) { return traverse(c); });
|
|
1453
|
-
}
|
|
1454
|
-
if (node.body) {
|
|
1455
|
-
if (Array.isArray(node.body)) {
|
|
1456
|
-
node.body.forEach(function (s) { return traverse(s); });
|
|
1457
|
-
}
|
|
1458
|
-
else {
|
|
1459
|
-
traverse(node.body);
|
|
1460
|
-
}
|
|
1461
|
-
}
|
|
1462
|
-
if (node.consequent) {
|
|
1463
|
-
traverse(node.consequent);
|
|
1464
|
-
}
|
|
1465
|
-
if (node.alternate) {
|
|
1466
|
-
traverse(node.alternate);
|
|
1467
|
-
}
|
|
1468
|
-
// `{activeTabIndex === 0 && (<div>…<DataProvider/>…</div>)}` — a tab
|
|
1469
|
-
// panel, a gated section: the provider sits on the RIGHT of a logical
|
|
1470
|
-
// expression (or in a ternary's `test`), which is not a child, a body or
|
|
1471
|
-
// an argument. Left unvisited, the products list under the first tab of
|
|
1472
|
-
// a shop was never paginated or seeded, and rendered nothing.
|
|
1473
|
-
if (node.left) {
|
|
1474
|
-
traverse(node.left);
|
|
1475
|
-
}
|
|
1476
|
-
if (node.right) {
|
|
1477
|
-
traverse(node.right);
|
|
1478
|
-
}
|
|
1479
|
-
if (node.test) {
|
|
1480
|
-
traverse(node.test);
|
|
1481
|
-
}
|
|
1482
|
-
if (node.expression) {
|
|
1483
|
-
traverse(node.expression);
|
|
1484
|
-
}
|
|
1485
|
-
if (node.argument) {
|
|
1486
|
-
traverse(node.argument);
|
|
1487
|
-
}
|
|
1488
|
-
};
|
|
1489
|
-
traverse(blockStatement);
|
|
1490
|
-
return results;
|
|
1491
|
-
}
|
|
1492
1517
|
/**
|
|
1493
1518
|
* Every pagination widget in the JSX, paired with the mapper it belongs to.
|
|
1494
1519
|
*
|
|
@@ -1563,34 +1588,97 @@ function findPaginationNodesWithOwners(blockStatement, usageByProviderNode) {
|
|
|
1563
1588
|
*
|
|
1564
1589
|
* An uncached mapper keeps the inline `params={useMemo(...)}` it has always had,
|
|
1565
1590
|
* byte for byte. A cached one hoists that memo into a component const so the
|
|
1566
|
-
* peek can depend on the same object identity instead of rebuilding it
|
|
1591
|
+
* peek can depend on the same object identity instead of rebuilding it; so does
|
|
1592
|
+
* an appending list that starts from its page's rows (`hoistInto`), whose first
|
|
1593
|
+
* page is filed in the accumulator under those params.
|
|
1567
1594
|
*
|
|
1568
|
-
* Returns the identifier holding the
|
|
1569
|
-
*
|
|
1595
|
+
* Returns the identifier holding the params when they were hoisted, and the one
|
|
1596
|
+
* holding the peeked rows when this mapper caches.
|
|
1570
1597
|
*/
|
|
1571
1598
|
function pushParamsAttribute(
|
|
1572
1599
|
// tslint:disable-next-line:no-any
|
|
1573
|
-
dp, usage, paramsProps, memoDeps, cacheDeclarations) {
|
|
1600
|
+
dp, usage, paramsProps, memoDeps, cacheDeclarations, hoistInto) {
|
|
1574
1601
|
var _a;
|
|
1575
1602
|
var paramsMemo = types.callExpression(types.identifier('useMemo'), [
|
|
1576
1603
|
types.arrowFunctionExpression([], types.objectExpression(paramsProps)),
|
|
1577
1604
|
types.arrayExpression(memoDeps),
|
|
1578
1605
|
]);
|
|
1579
|
-
// A state-bound sort
|
|
1580
|
-
//
|
|
1581
|
-
//
|
|
1582
|
-
//
|
|
1606
|
+
// A state-bound sort gets no cache peek. The peek is `initialData` by another
|
|
1607
|
+
// name, and such a list takes the server's rows only while its sort is still
|
|
1608
|
+
// where the visitor starts (`buildStartingSortGuard`); the peek was never
|
|
1609
|
+
// extended to it.
|
|
1583
1610
|
var cache = ((_a = usage.cache) === null || _a === void 0 ? void 0 : _a.client) && !usage.dynamicSort ? usage.cache : undefined;
|
|
1584
1611
|
if (!cache) {
|
|
1585
|
-
|
|
1586
|
-
|
|
1612
|
+
if (!hoistInto) {
|
|
1613
|
+
dp.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('params'), types.jsxExpressionContainer(paramsMemo)));
|
|
1614
|
+
return {};
|
|
1615
|
+
}
|
|
1616
|
+
var paramsIdentifier = (0, ast_1.paramsVarFor)(usage.index);
|
|
1617
|
+
hoistInto.push(types.variableDeclaration('const', [
|
|
1618
|
+
types.variableDeclarator(types.identifier(paramsIdentifier), paramsMemo),
|
|
1619
|
+
]));
|
|
1620
|
+
dp.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('params'), types.jsxExpressionContainer(types.identifier(paramsIdentifier))));
|
|
1621
|
+
return { paramsIdentifier: paramsIdentifier };
|
|
1587
1622
|
}
|
|
1588
1623
|
var hoisted = (0, ast_1.buildCachedParamsDeclarations)({ index: usage.index, paramsMemo: paramsMemo, cache: cache });
|
|
1589
1624
|
cacheDeclarations.push.apply(cacheDeclarations, hoisted.declarations);
|
|
1590
1625
|
dp.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('params'), types.jsxExpressionContainer(types.identifier(hoisted.paramsIdentifier))));
|
|
1591
|
-
return hoisted.cachedIdentifier;
|
|
1626
|
+
return { paramsIdentifier: hoisted.paramsIdentifier, cachedIdentifier: hoisted.cachedIdentifier };
|
|
1627
|
+
}
|
|
1628
|
+
// Whether the rows `getStaticProps` fetched can be this list's first page at
|
|
1629
|
+
// all. A sort bound to state can only be served them when the build knows the
|
|
1630
|
+
// sort the visitor starts with (`startingSort`) and fetched by it; otherwise
|
|
1631
|
+
// the fetch has no sort, and its rows are not the list's first page.
|
|
1632
|
+
function prefetchFollowsSort(usage) {
|
|
1633
|
+
return !usage.dynamicSort || !!usage.startingSort;
|
|
1634
|
+
}
|
|
1635
|
+
// `sortBy === "name-asc"`: the visitor has not moved the sort from where it
|
|
1636
|
+
// starts, so the build-time rows are still its first page. `null` for a list
|
|
1637
|
+
// whose sort the visitor cannot pick, or one that reads no state.
|
|
1638
|
+
function buildStartingSortGuard(usage) {
|
|
1639
|
+
return usage.dynamicSort && usage.startingSort ? (0, sort_utils_1.buildSortAtStartGuard)(usage.startingSort) : null;
|
|
1640
|
+
}
|
|
1641
|
+
// `<condition> && <starting-sort guard>`, or the condition alone.
|
|
1642
|
+
function withStartingSortGuard(condition, usage) {
|
|
1643
|
+
var sortGuard = buildStartingSortGuard(usage);
|
|
1644
|
+
return sortGuard ? types.logicalExpression('&&', condition, sortGuard) : condition;
|
|
1645
|
+
}
|
|
1646
|
+
// An appending list on a page starts from the rows its `getStaticProps`
|
|
1647
|
+
// fetched, when they can be its first page (`prefetchFollowsSort`).
|
|
1648
|
+
function startsFromServerRows(usage) {
|
|
1649
|
+
return usage.infiniteScroll && usage.paginated && prefetchFollowsSort(usage);
|
|
1650
|
+
}
|
|
1651
|
+
/**
|
|
1652
|
+
* `initialData={ds_N_firstPage}` on an appending list, beside the frozen first
|
|
1653
|
+
* page and the effect that files it as page 1 of the accumulator (see
|
|
1654
|
+
* `infinite-scroll.ts`).
|
|
1655
|
+
*
|
|
1656
|
+
* The rows stand in for page 1 only while they answer the list's query: no
|
|
1657
|
+
* search (`queryGuard`), the sort where the visitor starts, no filter set (the
|
|
1658
|
+
* guards the paged lists use), and at least one row — an empty build-time
|
|
1659
|
+
* answer, which a failed fetch also gives, leaves the browser to fetch page 1
|
|
1660
|
+
* as before.
|
|
1661
|
+
*/
|
|
1662
|
+
function pushInfiniteScrollFirstPage(
|
|
1663
|
+
// tslint:disable-next-line:no-any
|
|
1664
|
+
dp, usage, vars, paramsIdentifier, declarations, queryGuard, instanceDeps) {
|
|
1665
|
+
var infiniteVars = (0, infinite_scroll_1.getInfiniteScrollVars)(usage.index);
|
|
1666
|
+
var serverPayload = function () {
|
|
1667
|
+
return types.optionalMemberExpression(types.identifier('props'), types.identifier(vars.propsPrefix), false, true);
|
|
1668
|
+
};
|
|
1669
|
+
var hasServerRows = types.binaryExpression('>', types.optionalMemberExpression((0, infinite_scroll_1.buildServerRowsExpression)(serverPayload(), usage.itemsPath), types.identifier('length'), false, true), types.numericLiteral(0));
|
|
1670
|
+
var startsFromServer = [
|
|
1671
|
+
queryGuard,
|
|
1672
|
+
buildStartingSortGuard(usage),
|
|
1673
|
+
buildNoUrlFilterGuard(usage),
|
|
1674
|
+
hasServerRows,
|
|
1675
|
+
]
|
|
1676
|
+
.filter(function (guard) { return guard !== null; })
|
|
1677
|
+
.reduce(function (all, guard) { return types.logicalExpression('&&', all, guard); });
|
|
1678
|
+
declarations.push((0, infinite_scroll_1.buildFirstPageDeclaration)(infiniteVars, startsFromServer, serverPayload(), instanceDeps), (0, infinite_scroll_1.buildFirstPageSeedEffect)(infiniteVars, paramsIdentifier, usage.perPage, usage.itemsPath));
|
|
1679
|
+
dp.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('initialData'), types.jsxExpressionContainer(types.identifier(infiniteVars.firstPageVar))));
|
|
1592
1680
|
}
|
|
1593
|
-
function updateDataProviderForPaginatedSearch(dp, usage, vars, fileName, cacheDeclarations, localized) {
|
|
1681
|
+
function updateDataProviderForPaginatedSearch(dp, usage, vars, fileName, cacheDeclarations, localized, firstPageDeclarations) {
|
|
1594
1682
|
var attrs = dp.openingElement.attributes;
|
|
1595
1683
|
// Remove existing params, key, initialData, fetchData, persistDataDuringLoading
|
|
1596
1684
|
dp.openingElement.attributes = attrs.filter(function (attr) {
|
|
@@ -1623,20 +1711,29 @@ function updateDataProviderForPaginatedSearch(dp, usage, vars, fileName, cacheDe
|
|
|
1623
1711
|
if (localized) {
|
|
1624
1712
|
(0, request_locale_1.appendClientLocaleParam)(paramsProps, memoDeps);
|
|
1625
1713
|
}
|
|
1626
|
-
var
|
|
1627
|
-
|
|
1628
|
-
//
|
|
1629
|
-
//
|
|
1630
|
-
// the
|
|
1631
|
-
//
|
|
1632
|
-
//
|
|
1714
|
+
var seedInto = startsFromServerRows(usage) ? firstPageDeclarations : undefined;
|
|
1715
|
+
var _a = pushParamsAttribute(dp, usage, paramsProps, memoDeps, cacheDeclarations, seedInto), paramsIdentifier = _a.paramsIdentifier, cachedInitialData = _a.cachedIdentifier;
|
|
1716
|
+
// Add initialData: the server-prefetched page 1 while it is the page on show
|
|
1717
|
+
// — page 1, no search, no filter set, and a sort the visitor picks still where
|
|
1718
|
+
// they start (the prefetch ran by that sort). A list whose starting sort the
|
|
1719
|
+
// build cannot know never takes it: that prefetch ran without a sort, so
|
|
1720
|
+
// reusing it would mask the current sort AND make DataProvider skip its first
|
|
1721
|
+
// client fetch (its internal guard only skips when initialData is defined on
|
|
1722
|
+
// mount). Any other sort is fetched fresh, through the useMemo params.
|
|
1633
1723
|
//
|
|
1634
|
-
// An appending list
|
|
1635
|
-
//
|
|
1636
|
-
//
|
|
1637
|
-
//
|
|
1638
|
-
|
|
1639
|
-
|
|
1724
|
+
// An appending list takes its own: `initialData` makes DataProvider skip its
|
|
1725
|
+
// first fetch, so the prefetched page 1 has to be filed in the accumulator
|
|
1726
|
+
// too, or appending page 2 would REPLACE the visible rows with page 2 alone.
|
|
1727
|
+
// The provider remounts per query (its `key`), so the first page is frozen
|
|
1728
|
+
// per query.
|
|
1729
|
+
if (seedInto && paramsIdentifier) {
|
|
1730
|
+
var appliedQuery = function () {
|
|
1731
|
+
return types.memberExpression(types.identifier(vars.combinedStateVar), types.identifier('debouncedQuery'));
|
|
1732
|
+
};
|
|
1733
|
+
pushInfiniteScrollFirstPage(dp, usage, vars, paramsIdentifier, seedInto, types.unaryExpression('!', appliedQuery(), true), [appliedQuery()]);
|
|
1734
|
+
}
|
|
1735
|
+
else if (prefetchFollowsSort(usage) && !usage.infiniteScroll) {
|
|
1736
|
+
var initialDataCondition = wrapInitialDataWithUrlFilterGuard(withStartingSortGuard(types.logicalExpression('&&', types.binaryExpression('===', types.memberExpression(types.identifier(vars.combinedStateVar), types.identifier('page')), types.numericLiteral(1)), types.unaryExpression('!', types.memberExpression(types.identifier(vars.combinedStateVar), types.identifier('debouncedQuery')), true)), usage), usage);
|
|
1640
1737
|
dp.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('initialData'), types.jsxExpressionContainer(types.conditionalExpression(initialDataCondition, types.optionalMemberExpression(types.identifier('props'), types.identifier(vars.propsPrefix), false, true), cachedInitialData ? types.identifier(cachedInitialData) : types.identifier('undefined')))));
|
|
1641
1738
|
}
|
|
1642
1739
|
// Add key. Sort is intentionally NOT part of the key — a key change would
|
|
@@ -1674,7 +1771,7 @@ function updateDataProviderForPaginatedSearch(dp, usage, vars, fileName, cacheDe
|
|
|
1674
1771
|
// Add persistDataDuringLoading
|
|
1675
1772
|
dp.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('persistDataDuringLoading'), types.jsxExpressionContainer(types.booleanLiteral(true))));
|
|
1676
1773
|
}
|
|
1677
|
-
function updateDataProviderForPaginationOnly(dp, usage, vars, fileName, cacheDeclarations, localized) {
|
|
1774
|
+
function updateDataProviderForPaginationOnly(dp, usage, vars, fileName, cacheDeclarations, localized, firstPageDeclarations) {
|
|
1678
1775
|
var attrs = dp.openingElement.attributes;
|
|
1679
1776
|
dp.openingElement.attributes = attrs.filter(function (attr) {
|
|
1680
1777
|
var _a;
|
|
@@ -1703,12 +1800,17 @@ function updateDataProviderForPaginationOnly(dp, usage, vars, fileName, cacheDec
|
|
|
1703
1800
|
(0, request_locale_1.appendClientLocaleParam)(paramsProps, memoDeps);
|
|
1704
1801
|
}
|
|
1705
1802
|
// Add params
|
|
1706
|
-
var
|
|
1707
|
-
|
|
1708
|
-
//
|
|
1709
|
-
//
|
|
1710
|
-
|
|
1711
|
-
|
|
1803
|
+
var seedInto = startsFromServerRows(usage) ? firstPageDeclarations : undefined;
|
|
1804
|
+
var _a = pushParamsAttribute(dp, usage, paramsProps, memoDeps, cacheDeclarations, seedInto), paramsIdentifier = _a.paramsIdentifier, cachedInitialData = _a.cachedIdentifier;
|
|
1805
|
+
// Add initialData. See paginated+search updater for when a sort the visitor
|
|
1806
|
+
// picks may reuse the prefetch, and how an appending list takes its own. This
|
|
1807
|
+
// provider never remounts (no `key`), so its first page is frozen for the
|
|
1808
|
+
// page's lifetime.
|
|
1809
|
+
if (seedInto && paramsIdentifier) {
|
|
1810
|
+
pushInfiniteScrollFirstPage(dp, usage, vars, paramsIdentifier, seedInto, null, []);
|
|
1811
|
+
}
|
|
1812
|
+
else if (prefetchFollowsSort(usage) && !usage.infiniteScroll) {
|
|
1813
|
+
dp.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('initialData'), types.jsxExpressionContainer(types.conditionalExpression(wrapInitialDataWithUrlFilterGuard(withStartingSortGuard(types.binaryExpression('===', types.identifier(vars.pageStateVar), types.numericLiteral(1)), usage), usage), types.optionalMemberExpression(types.identifier('props'), types.identifier(vars.propsPrefix), false, true), cachedInitialData ? types.identifier(cachedInitialData) : types.identifier('undefined')))));
|
|
1712
1814
|
}
|
|
1713
1815
|
// Add key — sort is intentionally NOT included; see paginated+search updater,
|
|
1714
1816
|
// which also explains why an appending list keys on nothing at all (there is
|
|
@@ -1758,11 +1860,11 @@ function updateDataProviderForSearchOnly(dp, usage, vars, fileName, cacheDeclara
|
|
|
1758
1860
|
if (localized) {
|
|
1759
1861
|
(0, request_locale_1.appendClientLocaleParam)(paramsProps, memoDeps);
|
|
1760
1862
|
}
|
|
1761
|
-
var cachedInitialData = pushParamsAttribute(dp, usage, paramsProps, memoDeps, cacheDeclarations);
|
|
1762
|
-
// Add initialData. See paginated+search updater for
|
|
1763
|
-
//
|
|
1764
|
-
if (
|
|
1765
|
-
dp.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('initialData'), types.jsxExpressionContainer(types.conditionalExpression(wrapInitialDataWithUrlFilterGuard(types.unaryExpression('!', types.identifier(vars.debouncedSearchQueryVar), true), usage), types.optionalMemberExpression(types.identifier('props'), types.identifier(vars.propsPrefix), false, true), cachedInitialData ? types.identifier(cachedInitialData) : types.identifier('undefined')))));
|
|
1863
|
+
var cachedInitialData = pushParamsAttribute(dp, usage, paramsProps, memoDeps, cacheDeclarations).cachedIdentifier;
|
|
1864
|
+
// Add initialData. See paginated+search updater for when a sort the visitor
|
|
1865
|
+
// picks may reuse the prefetch.
|
|
1866
|
+
if (prefetchFollowsSort(usage)) {
|
|
1867
|
+
dp.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('initialData'), types.jsxExpressionContainer(types.conditionalExpression(wrapInitialDataWithUrlFilterGuard(withStartingSortGuard(types.unaryExpression('!', types.identifier(vars.debouncedSearchQueryVar), true), usage), usage), types.optionalMemberExpression(types.identifier('props'), types.identifier(vars.propsPrefix), false, true), cachedInitialData ? types.identifier(cachedInitialData) : types.identifier('undefined')))));
|
|
1766
1868
|
}
|
|
1767
1869
|
// Add key — sort is intentionally NOT included; see paginated+search updater.
|
|
1768
1870
|
dp.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('key'), types.jsxExpressionContainer(types.templateLiteral([
|
|
@@ -1773,14 +1875,42 @@ function updateDataProviderForSearchOnly(dp, usage, vars, fileName, cacheDeclara
|
|
|
1773
1875
|
dp.openingElement.attributes.push(createFetchDataAttribute(fileName, ((_a = usage.cache) === null || _a === void 0 ? void 0 : _a.client) ? usage.cache : undefined));
|
|
1774
1876
|
dp.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('persistDataDuringLoading'), types.jsxExpressionContainer(types.booleanLiteral(true))));
|
|
1775
1877
|
}
|
|
1878
|
+
/**
|
|
1879
|
+
* A plain list on a page is seeded with the rows its `getStaticProps` fetched
|
|
1880
|
+
* (`extractDataSourceIntoGetStaticProps`), and a seeded provider skips its first
|
|
1881
|
+
* fetch. With a sort the visitor picks, those rows are the list's only while the
|
|
1882
|
+
* sort is where a visitor starts — the build fetched them by it:
|
|
1883
|
+
*
|
|
1884
|
+
* initialData={sortBy === "name-asc" ? props.items_products : undefined}
|
|
1885
|
+
*
|
|
1886
|
+
* — and any other sort is fetched fresh, through the params it changes. When the
|
|
1887
|
+
* build cannot know where the sort starts (`prefetchFollowsSort`), it fetched
|
|
1888
|
+
* the rows unsorted, and the list is never seeded with them. A plain list has no
|
|
1889
|
+
* search, and is only seeded without a filter a visitor sets.
|
|
1890
|
+
*/
|
|
1891
|
+
function seedPlainListWhileSortStarts(dp, usage) {
|
|
1892
|
+
if (!usage.dynamicSort) {
|
|
1893
|
+
return;
|
|
1894
|
+
}
|
|
1895
|
+
var attrs = dp.openingElement.attributes;
|
|
1896
|
+
var index = attrs.findIndex(function (attr) { var _a; return attr.type === 'JSXAttribute' && ((_a = attr.name) === null || _a === void 0 ? void 0 : _a.name) === 'initialData'; });
|
|
1897
|
+
if (index === -1) {
|
|
1898
|
+
return;
|
|
1899
|
+
}
|
|
1900
|
+
if (!prefetchFollowsSort(usage)) {
|
|
1901
|
+
attrs.splice(index, 1);
|
|
1902
|
+
return;
|
|
1903
|
+
}
|
|
1904
|
+
var sortGuard = buildStartingSortGuard(usage);
|
|
1905
|
+
var seeded = attrs[index].value;
|
|
1906
|
+
if (!sortGuard || (seeded === null || seeded === void 0 ? void 0 : seeded.type) !== 'JSXExpressionContainer') {
|
|
1907
|
+
return;
|
|
1908
|
+
}
|
|
1909
|
+
attrs[index] = types.jsxAttribute(types.jsxIdentifier('initialData'), types.jsxExpressionContainer(types.conditionalExpression(sortGuard, seeded.expression, types.identifier('undefined'))));
|
|
1910
|
+
}
|
|
1776
1911
|
function updateDataProviderForPlain(dp, fileName, usage, localized) {
|
|
1777
1912
|
var _a, _b, _c, _d, _e, _f;
|
|
1778
|
-
|
|
1779
|
-
// pre-rendered in the table's order would stand in for it, since a seeded
|
|
1780
|
-
// provider skips its first fetch — the paginated lists drop them the same way.
|
|
1781
|
-
if (usage.dynamicSort) {
|
|
1782
|
-
dp.openingElement.attributes = dp.openingElement.attributes.filter(function (attr) { var _a; return !(attr.type === 'JSXAttribute' && ((_a = attr.name) === null || _a === void 0 ? void 0 : _a.name) === 'initialData'); });
|
|
1783
|
-
}
|
|
1913
|
+
seedPlainListWhileSortStarts(dp, usage);
|
|
1784
1914
|
var attrs = dp.openingElement.attributes;
|
|
1785
1915
|
var clientCache = ((_a = usage.cache) === null || _a === void 0 ? void 0 : _a.client) ? usage.cache : undefined;
|
|
1786
1916
|
// Check if fetchData already exists
|
|
@@ -1933,21 +2063,18 @@ accumulate) {
|
|
|
1933
2063
|
? (0, ast_1.buildCacheStoreThen)(cache)
|
|
1934
2064
|
: uncachedTail;
|
|
1935
2065
|
var networkChain = types.callExpression(types.memberExpression(parsedJson, types.identifier('then')), [responseTail]);
|
|
2066
|
+
// An appending list records the request it now stands on before making it
|
|
2067
|
+
// (see `buildAccumulatingRequestMark`).
|
|
1936
2068
|
var arrow = cache
|
|
1937
2069
|
? types.arrowFunctionExpression([types.identifier('params')], (0, ast_1.buildCachedFetchBody)(networkChain, cache))
|
|
1938
|
-
:
|
|
2070
|
+
: accumulate
|
|
2071
|
+
? types.arrowFunctionExpression([types.identifier('params')], types.blockStatement([
|
|
2072
|
+
(0, infinite_scroll_1.buildAccumulatingRequestMark)((0, infinite_scroll_1.getInfiniteScrollVars)(accumulate.usage.index)),
|
|
2073
|
+
types.returnStatement(networkChain),
|
|
2074
|
+
]))
|
|
2075
|
+
: types.arrowFunctionExpression([types.identifier('params')], networkChain);
|
|
1939
2076
|
return types.jsxAttribute(types.jsxIdentifier('fetchData'), types.jsxExpressionContainer(types.callExpression(types.identifier('useCallback'), [arrow, types.arrayExpression([])])));
|
|
1940
2077
|
}
|
|
1941
|
-
function wireSearchInput(inputNode, vars) {
|
|
1942
|
-
// Remove existing onChange and value
|
|
1943
|
-
inputNode.openingElement.attributes = inputNode.openingElement.attributes.filter(function (attr) { var _a; return !['onChange', 'value'].includes((_a = attr.name) === null || _a === void 0 ? void 0 : _a.name); });
|
|
1944
|
-
// Add onChange
|
|
1945
|
-
inputNode.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('onChange'), types.jsxExpressionContainer(types.arrowFunctionExpression([types.identifier('e')], types.callExpression(types.identifier(vars.setSearchQueryVar), [
|
|
1946
|
-
types.memberExpression(types.memberExpression(types.identifier('e'), types.identifier('target')), types.identifier('value')),
|
|
1947
|
-
])))));
|
|
1948
|
-
// Add value
|
|
1949
|
-
inputNode.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('value'), types.jsxExpressionContainer(types.identifier(vars.searchQueryVar))));
|
|
1950
|
-
}
|
|
1951
2078
|
/**
|
|
1952
2079
|
* The `fetchData` attribute for one paginated usage.
|
|
1953
2080
|
*
|
|
@@ -1963,6 +2090,32 @@ function buildFetchDataForUsage(fileName, usage) {
|
|
|
1963
2090
|
}
|
|
1964
2091
|
return createFetchDataAttribute(fileName, ((_a = usage.cache) === null || _a === void 0 ? void 0 : _a.client) ? usage.cache : undefined);
|
|
1965
2092
|
}
|
|
2093
|
+
/** `const [ds_N_total, setDs_N_total] = useState(null)` — declared only beside a range control. */
|
|
2094
|
+
function buildTotalDeclaration(vars) {
|
|
2095
|
+
return types.variableDeclaration('const', [
|
|
2096
|
+
types.variableDeclarator(types.arrayPattern([
|
|
2097
|
+
types.identifier(vars.totalStateVar),
|
|
2098
|
+
types.identifier(vars.setTotalStateVar),
|
|
2099
|
+
]), types.callExpression(types.identifier('useState'), [types.nullLiteral()])),
|
|
2100
|
+
]);
|
|
2101
|
+
}
|
|
2102
|
+
/**
|
|
2103
|
+
* Fills one `range` text with the live row range of `usage` (see
|
|
2104
|
+
* `range-control.ts`). A mapper that does not page has no count to show, so
|
|
2105
|
+
* its range text is left as drawn.
|
|
2106
|
+
*/
|
|
2107
|
+
function wireRangeControlFor(control, usage, vars) {
|
|
2108
|
+
if (!usage.paginated) {
|
|
2109
|
+
return;
|
|
2110
|
+
}
|
|
2111
|
+
var currentPageExpr = getPageAccessors(usage, vars).currentPageExpr;
|
|
2112
|
+
(0, range_control_1.wireRangeControl)(control, {
|
|
2113
|
+
totalVar: vars.totalStateVar,
|
|
2114
|
+
currentPageExpr: currentPageExpr(),
|
|
2115
|
+
perPage: usage.perPage,
|
|
2116
|
+
infiniteScroll: usage.infiniteScroll,
|
|
2117
|
+
});
|
|
2118
|
+
}
|
|
1966
2119
|
/**
|
|
1967
2120
|
* Wires the authored Load More button of an appending list.
|
|
1968
2121
|
*
|
|
@@ -2002,6 +2155,11 @@ function wireLoadMoreButton(paginationNode, usage, vars, hasLoadingState) {
|
|
|
2002
2155
|
* buttons beside its Load More.
|
|
2003
2156
|
*/
|
|
2004
2157
|
function wirePaginationWidget(paginationNode, usage, vars, hasLoadingState) {
|
|
2158
|
+
// A range text inside the container takes the container's owner, like the
|
|
2159
|
+
// buttons beside it; one naming its own mapper is wired in STEP 5b instead.
|
|
2160
|
+
(0, pagination_controls_1.findAllPaginationControls)(paginationNode, 'range')
|
|
2161
|
+
.filter(function (control) { return !(0, pagination_controls_1.readJSXAttributeString)(control, pagination_controls_1.PAGINATION_FOR_ATTR); })
|
|
2162
|
+
.forEach(function (control) { return wireRangeControlFor(control, usage, vars); });
|
|
2005
2163
|
if (usage.infiniteScroll) {
|
|
2006
2164
|
// Only the Load More button survives; page controls make no sense for a
|
|
2007
2165
|
// list the visitor never leaves.
|
|
@@ -2206,7 +2364,15 @@ function ensureAPIRouteExists(extractedResources, usage, dataSources, transformO
|
|
|
2206
2364
|
};
|
|
2207
2365
|
}
|
|
2208
2366
|
}
|
|
2209
|
-
|
|
2367
|
+
// `fetchCount(<params>, <read arguments>)`: the params may be left out only
|
|
2368
|
+
// when nothing follows them.
|
|
2369
|
+
var countReadArguments = function (countParams, readArguments) {
|
|
2370
|
+
return countParams.length > 0 || readArguments.length > 0
|
|
2371
|
+
? __spreadArray([types.objectExpression(countParams)], readArguments, true) : [];
|
|
2372
|
+
};
|
|
2373
|
+
function updateGetStaticProps(chunks, registry, dependencies, folderPath, localized,
|
|
2374
|
+
// The arguments every read hands the module after its params (fresh nodes per call).
|
|
2375
|
+
readArguments) {
|
|
2210
2376
|
var _a;
|
|
2211
2377
|
var getStaticPropsChunk = chunks.find(function (c) { return c.name === 'getStaticProps'; });
|
|
2212
2378
|
if (!getStaticPropsChunk || getStaticPropsChunk.type !== teleport_types_1.ChunkType.AST) {
|
|
@@ -2287,6 +2453,12 @@ function updateGetStaticProps(chunks, registry, dependencies, folderPath, locali
|
|
|
2287
2453
|
})),
|
|
2288
2454
|
])));
|
|
2289
2455
|
}
|
|
2456
|
+
else if (usage.dynamicSort && usage.startingSort) {
|
|
2457
|
+
// A sort the visitor picks: page 1 by the sort they start with, sent
|
|
2458
|
+
// as the very string the browser sends for it, so page 2 continues
|
|
2459
|
+
// this page exactly (see `buildStartingSortsValue`).
|
|
2460
|
+
fetchParams.push(types.objectProperty(types.identifier('sorts'), (0, sort_utils_1.buildStartingSortsValue)(usage.dynamicSort, usage.startingSort)));
|
|
2461
|
+
}
|
|
2290
2462
|
// Add filters if present
|
|
2291
2463
|
// Filter out dynamic destinations for getStaticProps (they can't be resolved at build time)
|
|
2292
2464
|
var staticFilters = staticFiltersOf(usage);
|
|
@@ -2302,7 +2474,7 @@ function updateGetStaticProps(chunks, registry, dependencies, folderPath, locali
|
|
|
2302
2474
|
var existingFetchIndex = arrayPattern.elements.findIndex(function (el) { return (el === null || el === void 0 ? void 0 : el.type) === 'Identifier' && el.name === vars.propsPrefix; });
|
|
2303
2475
|
if (existingFetchIndex === -1) {
|
|
2304
2476
|
arrayPattern.elements.push(types.identifier(vars.propsPrefix));
|
|
2305
|
-
fetchesArray.elements.push(types.callExpression(types.memberExpression(types.callExpression(types.memberExpression(types.identifier(fetcherImportName), types.identifier('fetchData')), [types.objectExpression(fetchParams)]), types.identifier('catch')), [
|
|
2477
|
+
fetchesArray.elements.push(types.callExpression(types.memberExpression(types.callExpression(types.memberExpression(types.identifier(fetcherImportName), types.identifier('fetchData')), __spreadArray([types.objectExpression(fetchParams)], readArguments(), true)), types.identifier('catch')), [
|
|
2306
2478
|
types.arrowFunctionExpression([types.identifier('error')], types.blockStatement([
|
|
2307
2479
|
types.expressionStatement(types.callExpression(types.memberExpression(types.identifier('console'), types.identifier('error')), [
|
|
2308
2480
|
types.stringLiteral("Error fetching ".concat(vars.propsPrefix, ":")),
|
|
@@ -2405,7 +2577,7 @@ function updateGetStaticProps(chunks, registry, dependencies, folderPath, locali
|
|
|
2405
2577
|
countParams.push(types.objectProperty(types.identifier('filters'), (0, filter_utils_1.buildStaticFiltersStringifyCall)(staticFiltersForCount)));
|
|
2406
2578
|
}
|
|
2407
2579
|
(0, items_path_1.appendItemsPathParam)(countParams, firstUsage.itemsPath, 'collectionPath');
|
|
2408
|
-
fetchesArray.elements.push(types.callExpression(types.memberExpression(types.callExpression(types.memberExpression(types.identifier(fetcherImportName), types.identifier('fetchCount')), countParams
|
|
2580
|
+
fetchesArray.elements.push(types.callExpression(types.memberExpression(types.callExpression(types.memberExpression(types.identifier(fetcherImportName), types.identifier('fetchCount')), countReadArguments(countParams, readArguments())), types.identifier('catch')), [
|
|
2409
2581
|
types.arrowFunctionExpression([types.identifier('error')], types.blockStatement([
|
|
2410
2582
|
types.expressionStatement(types.callExpression(types.memberExpression(types.identifier('console'), types.identifier('error')), [
|
|
2411
2583
|
types.stringLiteral("Error fetching ".concat(countVarName, ":")),
|