@teleporthq/teleport-plugin-next-data-source 0.43.59 → 0.43.61
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/pagination-widget-fixture.ts +230 -0
- package/__tests__/ecommerce-product-discounts.test.ts +196 -0
- package/__tests__/infinite-scroll.test.ts +143 -0
- package/__tests__/numbered-pagination.test.ts +113 -0
- package/__tests__/page-reset-on-filter-sort.test.ts +182 -0
- package/__tests__/page-url-sync.test.ts +208 -0
- package/__tests__/product-price-sort.ts +313 -0
- package/__tests__/search-url-sync.test.ts +7 -3
- package/dist/cjs/array-mapper-pagination.d.ts +9 -0
- package/dist/cjs/array-mapper-pagination.d.ts.map +1 -1
- package/dist/cjs/array-mapper-pagination.js.map +1 -1
- package/dist/cjs/cache/ast.d.ts.map +1 -1
- package/dist/cjs/cache/ast.js +2 -2
- package/dist/cjs/cache/ast.js.map +1 -1
- package/dist/cjs/count-effect.d.ts +42 -0
- package/dist/cjs/count-effect.d.ts.map +1 -0
- package/dist/cjs/count-effect.js +81 -0
- package/dist/cjs/count-effect.js.map +1 -0
- package/dist/cjs/fetchers/postgresql.d.ts.map +1 -1
- package/dist/cjs/fetchers/postgresql.js +2 -1
- package/dist/cjs/fetchers/postgresql.js.map +1 -1
- package/dist/cjs/fetchers/teleport.d.ts.map +1 -1
- package/dist/cjs/fetchers/teleport.js +3 -2
- package/dist/cjs/fetchers/teleport.js.map +1 -1
- package/dist/cjs/infinite-scroll.d.ts +65 -0
- package/dist/cjs/infinite-scroll.d.ts.map +1 -0
- package/dist/cjs/infinite-scroll.js +190 -0
- package/dist/cjs/infinite-scroll.js.map +1 -0
- package/dist/cjs/numbered-pagination.d.ts +42 -0
- package/dist/cjs/numbered-pagination.d.ts.map +1 -0
- package/dist/cjs/numbered-pagination.js +167 -0
- package/dist/cjs/numbered-pagination.js.map +1 -0
- package/dist/cjs/page-reset.d.ts +42 -0
- package/dist/cjs/page-reset.d.ts.map +1 -0
- package/dist/cjs/page-reset.js +116 -0
- package/dist/cjs/page-reset.js.map +1 -0
- package/dist/cjs/page-url-sync.d.ts +42 -0
- package/dist/cjs/page-url-sync.d.ts.map +1 -0
- package/dist/cjs/page-url-sync.js +180 -0
- package/dist/cjs/page-url-sync.js.map +1 -0
- package/dist/cjs/pagination-controls.d.ts +55 -0
- package/dist/cjs/pagination-controls.d.ts.map +1 -0
- package/dist/cjs/pagination-controls.js +159 -0
- package/dist/cjs/pagination-controls.js.map +1 -0
- package/dist/cjs/pagination-plugin.d.ts.map +1 -1
- package/dist/cjs/pagination-plugin.js +508 -164
- package/dist/cjs/pagination-plugin.js.map +1 -1
- package/dist/cjs/product-price-sort.d.ts +116 -0
- package/dist/cjs/product-price-sort.d.ts.map +1 -0
- package/dist/cjs/product-price-sort.js +169 -0
- package/dist/cjs/product-price-sort.js.map +1 -0
- package/dist/cjs/transformations/ecommerce-product.d.ts.map +1 -1
- package/dist/cjs/transformations/ecommerce-product.js +1 -1
- package/dist/cjs/transformations/ecommerce-product.js.map +1 -1
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/cjs/utils.d.ts.map +1 -1
- package/dist/cjs/utils.js +5 -7
- package/dist/cjs/utils.js.map +1 -1
- package/dist/esm/array-mapper-pagination.d.ts +9 -0
- package/dist/esm/array-mapper-pagination.d.ts.map +1 -1
- package/dist/esm/array-mapper-pagination.js.map +1 -1
- package/dist/esm/cache/ast.d.ts.map +1 -1
- package/dist/esm/cache/ast.js +2 -2
- package/dist/esm/cache/ast.js.map +1 -1
- package/dist/esm/count-effect.d.ts +42 -0
- package/dist/esm/count-effect.d.ts.map +1 -0
- package/dist/esm/count-effect.js +53 -0
- package/dist/esm/count-effect.js.map +1 -0
- package/dist/esm/fetchers/postgresql.d.ts.map +1 -1
- package/dist/esm/fetchers/postgresql.js +2 -1
- package/dist/esm/fetchers/postgresql.js.map +1 -1
- package/dist/esm/fetchers/teleport.d.ts.map +1 -1
- package/dist/esm/fetchers/teleport.js +3 -2
- package/dist/esm/fetchers/teleport.js.map +1 -1
- package/dist/esm/infinite-scroll.d.ts +65 -0
- package/dist/esm/infinite-scroll.d.ts.map +1 -0
- package/dist/esm/infinite-scroll.js +159 -0
- package/dist/esm/infinite-scroll.js.map +1 -0
- package/dist/esm/numbered-pagination.d.ts +42 -0
- package/dist/esm/numbered-pagination.d.ts.map +1 -0
- package/dist/esm/numbered-pagination.js +138 -0
- package/dist/esm/numbered-pagination.js.map +1 -0
- package/dist/esm/page-reset.d.ts +42 -0
- package/dist/esm/page-reset.d.ts.map +1 -0
- package/dist/esm/page-reset.js +87 -0
- package/dist/esm/page-reset.js.map +1 -0
- package/dist/esm/page-url-sync.d.ts +42 -0
- package/dist/esm/page-url-sync.d.ts.map +1 -0
- package/dist/esm/page-url-sync.js +152 -0
- package/dist/esm/page-url-sync.js.map +1 -0
- package/dist/esm/pagination-controls.d.ts +55 -0
- package/dist/esm/pagination-controls.d.ts.map +1 -0
- package/dist/esm/pagination-controls.js +126 -0
- package/dist/esm/pagination-controls.js.map +1 -0
- package/dist/esm/pagination-plugin.d.ts.map +1 -1
- package/dist/esm/pagination-plugin.js +510 -166
- package/dist/esm/pagination-plugin.js.map +1 -1
- package/dist/esm/product-price-sort.d.ts +116 -0
- package/dist/esm/product-price-sort.d.ts.map +1 -0
- package/dist/esm/product-price-sort.js +160 -0
- package/dist/esm/product-price-sort.js.map +1 -0
- package/dist/esm/transformations/ecommerce-product.d.ts.map +1 -1
- package/dist/esm/transformations/ecommerce-product.js +2 -2
- package/dist/esm/transformations/ecommerce-product.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/utils.d.ts.map +1 -1
- package/dist/esm/utils.js +6 -8
- package/dist/esm/utils.js.map +1 -1
- package/package.json +5 -5
- package/src/array-mapper-pagination.ts +10 -0
- package/src/cache/ast.ts +2 -2
- package/src/count-effect.ts +137 -0
- package/src/fetchers/postgresql.ts +52 -13
- package/src/fetchers/teleport.ts +53 -13
- package/src/infinite-scroll.ts +401 -0
- package/src/numbered-pagination.ts +292 -0
- package/src/page-reset.ts +162 -0
- package/src/page-url-sync.ts +241 -0
- package/src/pagination-controls.ts +176 -0
- package/src/pagination-plugin.ts +758 -351
- package/src/product-price-sort.ts +204 -0
- package/src/transformations/ecommerce-product.ts +33 -7
- package/src/utils.ts +6 -8
- package/dist/cjs/array-mapper-registry.d.ts +0 -85
- package/dist/cjs/array-mapper-registry.d.ts.map +0 -1
- package/dist/cjs/array-mapper-registry.js +0 -296
- package/dist/cjs/array-mapper-registry.js.map +0 -1
- package/dist/cjs/pagination-with-count.d.ts +0 -6
- package/dist/cjs/pagination-with-count.d.ts.map +0 -1
- package/dist/cjs/pagination-with-count.js +0 -63
- package/dist/cjs/pagination-with-count.js.map +0 -1
- package/dist/esm/array-mapper-registry.d.ts +0 -85
- package/dist/esm/array-mapper-registry.d.ts.map +0 -1
- package/dist/esm/array-mapper-registry.js +0 -292
- package/dist/esm/array-mapper-registry.js.map +0 -1
- package/dist/esm/pagination-with-count.d.ts +0 -6
- package/dist/esm/pagination-with-count.d.ts.map +0 -1
- package/dist/esm/pagination-with-count.js +0 -34
- package/dist/esm/pagination-with-count.js.map +0 -1
- package/src/array-mapper-registry.ts +0 -416
- package/src/pagination-with-count.ts +0 -89
|
@@ -58,6 +58,15 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
58
58
|
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
59
59
|
}
|
|
60
60
|
};
|
|
61
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
62
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
63
|
+
if (ar || !(i in from)) {
|
|
64
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
65
|
+
ar[i] = from[i];
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
69
|
+
};
|
|
61
70
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
62
71
|
exports.createNextArrayMapperPaginationPlugin = void 0;
|
|
63
72
|
var teleport_types_1 = require("@teleporthq/teleport-types");
|
|
@@ -73,6 +82,12 @@ var filter_utils_1 = require("./filter-utils");
|
|
|
73
82
|
var loading_state_1 = require("./loading-state");
|
|
74
83
|
var config_1 = require("./cache/config");
|
|
75
84
|
var ast_1 = require("./cache/ast");
|
|
85
|
+
var pagination_controls_1 = require("./pagination-controls");
|
|
86
|
+
var count_effect_1 = require("./count-effect");
|
|
87
|
+
var numbered_pagination_1 = require("./numbered-pagination");
|
|
88
|
+
var infinite_scroll_1 = require("./infinite-scroll");
|
|
89
|
+
var page_reset_1 = require("./page-reset");
|
|
90
|
+
var page_url_sync_1 = require("./page-url-sync");
|
|
76
91
|
// tslint:disable-next-line:no-any
|
|
77
92
|
function parseSearchDefaultValue(raw) {
|
|
78
93
|
if (!raw || typeof raw !== 'object') {
|
|
@@ -426,6 +441,17 @@ function buildStateRegistry(uidlNode) {
|
|
|
426
441
|
content.searchUrlParamKey.trim().length > 0
|
|
427
442
|
? content.searchUrlParamKey.trim()
|
|
428
443
|
: undefined;
|
|
444
|
+
// An accumulating list has no discrete pages, so it can neither jump
|
|
445
|
+
// between them nor put one in the URL. Normalising here — rather than at
|
|
446
|
+
// each of the ~6 emit sites — keeps every downstream branch able to trust
|
|
447
|
+
// `paginationMode` / `pageUrlParamKey` on their own.
|
|
448
|
+
var infiniteScroll = !!content.infiniteScroll;
|
|
449
|
+
var pageUrlParamKey = !infiniteScroll &&
|
|
450
|
+
typeof content.pageUrlParamKey === 'string' &&
|
|
451
|
+
content.pageUrlParamKey.trim().length > 0
|
|
452
|
+
? content.pageUrlParamKey.trim()
|
|
453
|
+
: undefined;
|
|
454
|
+
var paginationMode = !infiniteScroll && content.paginationMode === 'numbered' ? 'numbered' : 'buttons';
|
|
429
455
|
var usage = {
|
|
430
456
|
index: index++,
|
|
431
457
|
dataSourceIdentifier: parentDataSource.identifier,
|
|
@@ -449,6 +475,10 @@ function buildStateRegistry(uidlNode) {
|
|
|
449
475
|
filterPropIds: filterPropIds,
|
|
450
476
|
filterUrlSearchParamKeys: filterUrlSearchParamKeys,
|
|
451
477
|
cache: (0, config_1.resolveCacheFromRepeaterContent)(content.cache, parentDataSource.resourceDef),
|
|
478
|
+
paginationMode: paginationMode,
|
|
479
|
+
infiniteScroll: infiniteScroll,
|
|
480
|
+
infiniteScrollLoadMore: infiniteScroll && !!content.infiniteScrollLoadMore,
|
|
481
|
+
pageUrlParamKey: pageUrlParamKey,
|
|
452
482
|
category: 'plain',
|
|
453
483
|
};
|
|
454
484
|
// Determine category
|
|
@@ -540,6 +570,16 @@ function usageHasSearchUrlSync(usage) {
|
|
|
540
570
|
return (!!usage.searchUrlParamKey &&
|
|
541
571
|
(usage.category === 'paginated+search' || usage.category === 'search-only'));
|
|
542
572
|
}
|
|
573
|
+
// The page ⇄ URL counterpart of `usageHasSearchUrlSync`: the usage must carry a
|
|
574
|
+
// `pageUrlParamKey` AND own a page state (only the paginated categories declare
|
|
575
|
+
// `ds_N_page` / `ds_N_state.page`). `infiniteScroll` usages are already excluded
|
|
576
|
+
// by the registry, which clears their key.
|
|
577
|
+
function usageHasPageUrlSync(usage) {
|
|
578
|
+
return (!!usage.pageUrlParamKey &&
|
|
579
|
+
usage.paginated &&
|
|
580
|
+
!usage.infiniteScroll &&
|
|
581
|
+
(usage.category === 'paginated+search' || usage.category === 'paginated-only'));
|
|
582
|
+
}
|
|
543
583
|
// Emits the two URL-sync effects for a search input bound to a URL param
|
|
544
584
|
// (`searchUrlParamKey`), reusing the shared `URLSearchParamSync` builders so the
|
|
545
585
|
// search input behaves exactly like the `selectedCategory` / `sortBy` dropdowns:
|
|
@@ -579,10 +619,157 @@ function pushSearchUrlSyncEffects(effectStatements, usage, vars) {
|
|
|
579
619
|
// debounce effect propagates the change into the debounced value + fetch.
|
|
580
620
|
effectStatements.push(teleport_plugin_common_1.URLSearchParamSync.buildUrlReadBackEffect(usage.searchUrlParamKey, vars.setSearchQueryVar));
|
|
581
621
|
}
|
|
622
|
+
// How one usage reads and writes its current page.
|
|
623
|
+
//
|
|
624
|
+
// A paginated+search list keeps the page inside a combined
|
|
625
|
+
// `{ page, debouncedQuery }` object so a search reset can replace both at once,
|
|
626
|
+
// while a paginated-only list has a plain `ds_N_page`. Every control that moves
|
|
627
|
+
// the page goes through this pair rather than re-deriving the distinction.
|
|
628
|
+
function getPageAccessors(usage, vars) {
|
|
629
|
+
var isCombinedState = usage.category === 'paginated+search';
|
|
630
|
+
return {
|
|
631
|
+
currentPageExpr: function () {
|
|
632
|
+
return isCombinedState
|
|
633
|
+
? types.memberExpression(types.identifier(vars.combinedStateVar), types.identifier('page'))
|
|
634
|
+
: types.identifier(vars.pageStateVar);
|
|
635
|
+
},
|
|
636
|
+
// Functional updates that bail when the page is unchanged: clicking the
|
|
637
|
+
// page you are already on must not schedule a render, and with it a refetch.
|
|
638
|
+
buildSetPageStatement: function (pageExpr) {
|
|
639
|
+
return isCombinedState
|
|
640
|
+
? types.callExpression(types.identifier(vars.setCombinedStateVar), [
|
|
641
|
+
types.arrowFunctionExpression([types.identifier('state')], types.conditionalExpression(types.binaryExpression('===', types.memberExpression(types.identifier('state'), types.identifier('page')), types.cloneNode(pageExpr, true)), types.identifier('state'), types.objectExpression([
|
|
642
|
+
types.spreadElement(types.identifier('state')),
|
|
643
|
+
types.objectProperty(types.identifier('page'), types.cloneNode(pageExpr, true)),
|
|
644
|
+
]))),
|
|
645
|
+
])
|
|
646
|
+
: types.callExpression(types.identifier(vars.setPageStateVar), [
|
|
647
|
+
types.arrowFunctionExpression([types.identifier('page')], types.conditionalExpression(types.binaryExpression('===', types.identifier('page'), types.cloneNode(pageExpr, true)), types.identifier('page'), types.cloneNode(pageExpr, true))),
|
|
648
|
+
]);
|
|
649
|
+
},
|
|
650
|
+
};
|
|
651
|
+
}
|
|
652
|
+
/**
|
|
653
|
+
* Advance one page, unless the count already says this is the last one. Shared
|
|
654
|
+
* by the scroll sentinel and the Load More button.
|
|
655
|
+
*
|
|
656
|
+
* ⛔ The next page is derived from the updater's OWN argument, never from the
|
|
657
|
+
* page in scope. The sentinel's effect is re-armed on `hasMore` / `maxPages`,
|
|
658
|
+
* and neither changes on an append while the total is unknown — so a captured
|
|
659
|
+
* `ds_N_page` would still read 1 on the second intersection and the list would
|
|
660
|
+
* stop growing after one page, on exactly the sources that cannot be counted.
|
|
661
|
+
*/
|
|
662
|
+
function buildAdvancePageStatement(usage, vars) {
|
|
663
|
+
var isCombinedState = usage.category === 'paginated+search';
|
|
664
|
+
var paramName = isCombinedState ? 'state' : 'page';
|
|
665
|
+
var pageOfParam = function () {
|
|
666
|
+
return isCombinedState
|
|
667
|
+
? types.memberExpression(types.identifier(paramName), types.identifier('page'))
|
|
668
|
+
: types.identifier(paramName);
|
|
669
|
+
};
|
|
670
|
+
// maxPages > 0 && <param page> >= maxPages
|
|
671
|
+
var atLastPage = types.logicalExpression('&&', types.binaryExpression('>', types.identifier(vars.maxPagesStateVar), types.numericLiteral(0)), types.binaryExpression('>=', pageOfParam(), types.identifier(vars.maxPagesStateVar)));
|
|
672
|
+
var nextPage = types.binaryExpression('+', pageOfParam(), types.numericLiteral(1));
|
|
673
|
+
return types.expressionStatement(types.callExpression(types.identifier(isCombinedState ? vars.setCombinedStateVar : vars.setPageStateVar), [
|
|
674
|
+
types.arrowFunctionExpression([types.identifier(paramName)], types.conditionalExpression(atLastPage, types.identifier(paramName), isCombinedState
|
|
675
|
+
? types.objectExpression([
|
|
676
|
+
types.spreadElement(types.identifier(paramName)),
|
|
677
|
+
types.objectProperty(types.identifier('page'), nextPage),
|
|
678
|
+
])
|
|
679
|
+
: nextPage)),
|
|
680
|
+
]));
|
|
681
|
+
}
|
|
682
|
+
// The accumulator, the end-of-data flag and (in auto mode) the sentinel ref,
|
|
683
|
+
// declared only for a mapper that appends.
|
|
684
|
+
function pushInfiniteScrollDeclarations(stateDeclarations, effectStatements, usage, vars) {
|
|
685
|
+
if (!usage.infiniteScroll || !usage.paginated) {
|
|
686
|
+
return;
|
|
687
|
+
}
|
|
688
|
+
var infiniteVars = (0, infinite_scroll_1.getInfiniteScrollVars)(usage.index);
|
|
689
|
+
var currentPageExpr = getPageAccessors(usage, vars).currentPageExpr;
|
|
690
|
+
var usesSentinel = !usage.infiniteScrollLoadMore;
|
|
691
|
+
stateDeclarations.push.apply(stateDeclarations, (0, infinite_scroll_1.buildInfiniteScrollDeclarations)(infiniteVars, vars.maxPagesStateVar, currentPageExpr(), usesSentinel));
|
|
692
|
+
if (usesSentinel) {
|
|
693
|
+
effectStatements.push((0, infinite_scroll_1.buildSentinelObserverEffect)(infiniteVars, vars.maxPagesStateVar, function () {
|
|
694
|
+
return buildAdvancePageStatement(usage, vars);
|
|
695
|
+
}));
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
// The `useMemo` holding the visible page numbers, declared only for a mapper in
|
|
699
|
+
// numbered mode.
|
|
700
|
+
function pushPageTokensDeclaration(stateDeclarations, usage, vars) {
|
|
701
|
+
if (usage.paginationMode !== 'numbered' || !usage.paginated) {
|
|
702
|
+
return;
|
|
703
|
+
}
|
|
704
|
+
var currentPageExpr = getPageAccessors(usage, vars).currentPageExpr;
|
|
705
|
+
stateDeclarations.push((0, numbered_pagination_1.buildPageTokensDeclaration)(usage.index, vars.maxPagesStateVar, currentPageExpr()));
|
|
706
|
+
}
|
|
707
|
+
// Emits the page ⇄ `?<key>=` sync for a mapper bound to `pageUrlParamKey` — the
|
|
708
|
+
// pagination counterpart of `pushSearchUrlSyncEffects`, but a SINGLE effect
|
|
709
|
+
// that owns both directions. `page-url-sync.ts` explains at length why the
|
|
710
|
+
// usual read-back / write-back pair cannot be used here.
|
|
711
|
+
//
|
|
712
|
+
// ⛔ MUST be pushed AFTER the filter/sort reset effect. Both can fire in one
|
|
713
|
+
// flush on a navigation that changes filter and page together; effects run in
|
|
714
|
+
// emission order, so this one running LAST is what makes the URL win when it
|
|
715
|
+
// carries a page, while a plain user filter change (whose URL has not moved
|
|
716
|
+
// yet) is left with the reset's page 1 and writes that back.
|
|
717
|
+
function pushPageUrlSyncEffects(stateDeclarations, effectStatements, usage, vars) {
|
|
718
|
+
if (!usageHasPageUrlSync(usage)) {
|
|
719
|
+
return;
|
|
720
|
+
}
|
|
721
|
+
var refVar = "ds_".concat(usage.index, "_pageUrlRef");
|
|
722
|
+
var _a = getPageAccessors(usage, vars), currentPageExpr = _a.currentPageExpr, buildSetPageStatement = _a.buildSetPageStatement;
|
|
723
|
+
stateDeclarations.push((0, page_url_sync_1.buildPageUrlRefDeclaration)(refVar));
|
|
724
|
+
effectStatements.push((0, page_url_sync_1.buildPageUrlSyncEffect)({
|
|
725
|
+
paramKey: usage.pageUrlParamKey,
|
|
726
|
+
refVar: refVar,
|
|
727
|
+
currentPageExpr: currentPageExpr,
|
|
728
|
+
buildSetPageStatement: buildSetPageStatement,
|
|
729
|
+
}));
|
|
730
|
+
}
|
|
731
|
+
// The name of the ref holding this usage's last-seen filter/sort signature.
|
|
732
|
+
function getPageResetRefVar(usage) {
|
|
733
|
+
return "ds_".concat(usage.index, "_filterResetRef");
|
|
734
|
+
}
|
|
735
|
+
// Everything that can narrow this list: filter destinations (state-, prop- and
|
|
736
|
+
// URL-bound) plus the state a dynamic sort reads. Sort does not change WHICH
|
|
737
|
+
// rows match, but it does change which row is on which page, so holding the
|
|
738
|
+
// visitor on page 5 across a sort change shows them an arbitrary window of a
|
|
739
|
+
// list they just reordered.
|
|
740
|
+
function collectPageResetDeps(usage) {
|
|
741
|
+
var _a, _b;
|
|
742
|
+
return {
|
|
743
|
+
stateIds: __spreadArray(__spreadArray([], usage.filterStateIds, true), ((_b = (_a = usage.dynamicSort) === null || _a === void 0 ? void 0 : _a.depStateIds) !== null && _b !== void 0 ? _b : []), true),
|
|
744
|
+
propIds: usage.filterPropIds,
|
|
745
|
+
urlSearchParamKeys: usage.filterUrlSearchParamKeys,
|
|
746
|
+
};
|
|
747
|
+
}
|
|
748
|
+
// Emits the "a filter or sort changed ⇒ go back to page 1" effect for one
|
|
749
|
+
// paginated usage. No-op for a list nothing can filter or reorder, so a mapper
|
|
750
|
+
// without filters generates byte-for-byte what it always did.
|
|
751
|
+
function pushFilterSortPageResetEffect(stateDeclarations, effectStatements, usage, vars) {
|
|
752
|
+
if (!usage.paginated) {
|
|
753
|
+
return;
|
|
754
|
+
}
|
|
755
|
+
var deps = collectPageResetDeps(usage);
|
|
756
|
+
if ((0, page_reset_1.hasNoPageResetDeps)(deps)) {
|
|
757
|
+
return;
|
|
758
|
+
}
|
|
759
|
+
var refVar = getPageResetRefVar(usage);
|
|
760
|
+
stateDeclarations.push((0, page_reset_1.buildPageResetRefDeclaration)(refVar));
|
|
761
|
+
// The setter bails when the page is already 1 (see `getPageAccessors`), so a
|
|
762
|
+
// visitor who was on page 1 all along and merely ticked a category does not
|
|
763
|
+
// get an extra render — and with it an extra fetch.
|
|
764
|
+
var buildSetPageStatement = getPageAccessors(usage, vars).buildSetPageStatement;
|
|
765
|
+
effectStatements.push((0, page_reset_1.buildFilterSortPageResetEffect)(refVar, deps, function () {
|
|
766
|
+
return types.expressionStatement(buildSetPageStatement(types.numericLiteral(1)));
|
|
767
|
+
}));
|
|
768
|
+
}
|
|
582
769
|
// ==================== MAIN PLUGIN ====================
|
|
583
770
|
var createNextArrayMapperPaginationPlugin = function () {
|
|
584
771
|
var paginationPlugin = function (structure) { return __awaiter(void 0, void 0, void 0, function () {
|
|
585
|
-
var uidl, chunks, dependencies, options, componentChunk, variableDeclaration, declarator, arrowFunction, blockStatement, registry, getStaticPropsChunk, isPage, stateDeclarations, effectStatements, needsUseRouter, hasRouterDecl, returnIndex, insertIndex, dataProviders, dataProvidersWithRepeaters, usageIndexByDataSourceId, loadingStateDeclarations, cacheDeclarations, sharedOptions, cachedScopes, dataProvidersWithoutRepeaters, searchInputs, searchEnabledUsages
|
|
772
|
+
var uidl, chunks, dependencies, options, componentChunk, variableDeclaration, declarator, arrowFunction, blockStatement, registry, getStaticPropsChunk, isPage, stateDeclarations, effectStatements, needsUseRouter, hasRouterDecl, returnIndex, insertIndex, dataProviders, dataProvidersWithRepeaters, usageIndexByDataSourceId, loadingStateDeclarations, usagesWithLoadingState, usageByProviderNode, cacheDeclarations, sharedOptions, cachedScopes, dataProvidersWithoutRepeaters, searchInputs, searchEnabledUsages;
|
|
586
773
|
var _a, _b;
|
|
587
774
|
return __generator(this, function (_c) {
|
|
588
775
|
uidl = structure.uidl, chunks = structure.chunks, dependencies = structure.dependencies, options = structure.options;
|
|
@@ -714,11 +901,19 @@ var createNextArrayMapperPaginationPlugin = function () {
|
|
|
714
901
|
types.variableDeclaration('const', [
|
|
715
902
|
types.variableDeclarator(types.identifier('timer'), types.callExpression(types.identifier('setTimeout'), [
|
|
716
903
|
types.arrowFunctionExpression([], types.blockStatement([
|
|
904
|
+
// ⛔ Functional, and a no-op when the query has not
|
|
905
|
+
// actually moved. This effect fires on ANY change to
|
|
906
|
+
// the input state — including the URL read-back
|
|
907
|
+
// echoing back a value the visitor never typed (a
|
|
908
|
+
// browser Forward to `?searchKeyword=x&page=3`) — and
|
|
909
|
+
// replacing the whole object would silently drop the
|
|
910
|
+
// page it had just adopted, as well as remount the
|
|
911
|
+
// provider on a `key` that contains the query.
|
|
717
912
|
types.expressionStatement(types.callExpression(types.identifier(vars.setCombinedStateVar), [
|
|
718
|
-
types.objectExpression([
|
|
913
|
+
types.arrowFunctionExpression([types.identifier('state')], types.conditionalExpression(types.binaryExpression('===', types.memberExpression(types.identifier('state'), types.identifier('debouncedQuery')), types.identifier(vars.searchQueryVar)), types.identifier('state'), types.objectExpression([
|
|
719
914
|
types.objectProperty(types.identifier('page'), types.numericLiteral(1)),
|
|
720
915
|
types.objectProperty(types.identifier('debouncedQuery'), types.identifier(vars.searchQueryVar)),
|
|
721
|
-
]),
|
|
916
|
+
]))),
|
|
722
917
|
])),
|
|
723
918
|
])),
|
|
724
919
|
types.numericLiteral(usage.searchDebounce),
|
|
@@ -751,42 +946,6 @@ var createNextArrayMapperPaginationPlugin = function () {
|
|
|
751
946
|
}
|
|
752
947
|
// Add filters to count fetch params if present
|
|
753
948
|
(0, filter_utils_1.appendFiltersParam)(urlParams, usage.filters, buildFilterDestinationExpression);
|
|
754
|
-
// Build the count fetch effect body
|
|
755
|
-
var countFetchEffectBody = [];
|
|
756
|
-
// Refresh the count on mount (no skip-on-mount guard). Pages seed maxPages
|
|
757
|
-
// from the build-time `getStaticProps` count, but that snapshot goes stale:
|
|
758
|
-
// rows added AFTER the build (e.g. the normalized product_variants table,
|
|
759
|
-
// which is seeded/grows past one page during store generation) are not
|
|
760
|
-
// reflected, so a frozen maxPages of 0/1 leaves "Next" permanently disabled
|
|
761
|
-
// on data-heavy tables. Re-fetching the live count on mount corrects
|
|
762
|
-
// maxPages so pagination tracks the real row count. The effect still runs
|
|
763
|
-
// when the search query or a filter changes (see deps below).
|
|
764
|
-
// Add the fetch call
|
|
765
|
-
countFetchEffectBody.push(types.expressionStatement(types.callExpression(types.memberExpression(types.callExpression(types.memberExpression(types.callExpression(types.identifier('fetch'), [
|
|
766
|
-
types.templateLiteral([
|
|
767
|
-
types.templateElement({
|
|
768
|
-
raw: "/api/".concat(fileName, "-count?"),
|
|
769
|
-
cooked: "/api/".concat(fileName, "-count?"),
|
|
770
|
-
}),
|
|
771
|
-
types.templateElement({ raw: '', cooked: '' }),
|
|
772
|
-
], [
|
|
773
|
-
types.newExpression(types.identifier('URLSearchParams'), [
|
|
774
|
-
types.objectExpression(urlParams),
|
|
775
|
-
]),
|
|
776
|
-
]),
|
|
777
|
-
]), types.identifier('then')), [
|
|
778
|
-
types.arrowFunctionExpression([types.identifier('res')], types.callExpression(types.memberExpression(types.identifier('res'), types.identifier('json')), [])),
|
|
779
|
-
]), types.identifier('then')), [
|
|
780
|
-
types.arrowFunctionExpression([types.identifier('data')], types.blockStatement([
|
|
781
|
-
types.ifStatement(types.logicalExpression('&&', types.identifier('data'), types.binaryExpression('in', types.stringLiteral('count'), types.identifier('data'))), types.blockStatement([
|
|
782
|
-
types.expressionStatement(types.callExpression(types.identifier(vars.setMaxPagesStateVar), [
|
|
783
|
-
types.conditionalExpression(types.binaryExpression('===', types.memberExpression(types.identifier('data'), types.identifier('count')), types.numericLiteral(0)), types.numericLiteral(0), types.callExpression(types.memberExpression(types.identifier('Math'), types.identifier('ceil')), [
|
|
784
|
-
types.binaryExpression('/', types.memberExpression(types.identifier('data'), types.identifier('count')), types.numericLiteral(usage.perPage)),
|
|
785
|
-
])),
|
|
786
|
-
])),
|
|
787
|
-
])),
|
|
788
|
-
])),
|
|
789
|
-
])));
|
|
790
949
|
var countEffectDeps = [
|
|
791
950
|
types.memberExpression(types.identifier(vars.combinedStateVar), types.identifier('debouncedQuery')),
|
|
792
951
|
];
|
|
@@ -801,12 +960,24 @@ var createNextArrayMapperPaginationPlugin = function () {
|
|
|
801
960
|
(0, filter_utils_1.pushPropIdsAsDeps)(countEffectDeps, countEffectSeen, usage.filterPropIds);
|
|
802
961
|
// Same goes for URL-driven filters (already documented above).
|
|
803
962
|
pushUrlSearchParamMemoDeps(countEffectDeps, usage);
|
|
804
|
-
effectStatements.push(
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
963
|
+
effectStatements.push((0, count_effect_1.buildCountFetchEffect)({
|
|
964
|
+
fileName: fileName,
|
|
965
|
+
perPage: usage.perPage,
|
|
966
|
+
setMaxPagesVar: vars.setMaxPagesStateVar,
|
|
967
|
+
urlParams: urlParams,
|
|
968
|
+
deps: countEffectDeps,
|
|
969
|
+
}));
|
|
808
970
|
// Two-way URL sync for the search input when bound to a URL param.
|
|
809
971
|
pushSearchUrlSyncEffects(effectStatements, usage, vars);
|
|
972
|
+
// Visible page numbers, when this mapper draws a numbered strip.
|
|
973
|
+
pushPageTokensDeclaration(stateDeclarations, usage, vars);
|
|
974
|
+
// Accumulation state, when it appends instead of paging.
|
|
975
|
+
pushInfiniteScrollDeclarations(stateDeclarations, effectStatements, usage, vars);
|
|
976
|
+
// A filter or sort change invalidates the page the visitor is on.
|
|
977
|
+
pushFilterSortPageResetEffect(stateDeclarations, effectStatements, usage, vars);
|
|
978
|
+
// Ordering matters — see `pushPageUrlSyncEffects`: the read-back runs
|
|
979
|
+
// after the reset so a URL that names a page wins over it.
|
|
980
|
+
pushPageUrlSyncEffects(stateDeclarations, effectStatements, usage, vars);
|
|
810
981
|
}
|
|
811
982
|
else if (usage.category === 'paginated-only') {
|
|
812
983
|
// Simple page state
|
|
@@ -825,42 +996,52 @@ var createNextArrayMapperPaginationPlugin = function () {
|
|
|
825
996
|
types.identifier(vars.setPageStateVar),
|
|
826
997
|
]), types.callExpression(types.identifier('useState'), [types.numericLiteral(1)])),
|
|
827
998
|
]));
|
|
828
|
-
//
|
|
829
|
-
//
|
|
830
|
-
|
|
999
|
+
// The live row count behind `ds_N_maxPages`.
|
|
1000
|
+
//
|
|
1001
|
+
// Components have never had a build-time count to fall back on, so they
|
|
1002
|
+
// have always fetched one here. Pages seed theirs from `getStaticProps`,
|
|
1003
|
+
// which only knows the STATIC filters — good enough to enable/disable a
|
|
1004
|
+
// "Next" button, but not to label a numbered strip or to know when an
|
|
1005
|
+
// infinite list has reached its end, so those two modes fetch a live
|
|
1006
|
+
// count as well.
|
|
1007
|
+
var needsLiveCount = !isPage || usage.paginationMode === 'numbered' || usage.infiniteScroll;
|
|
1008
|
+
if (needsLiveCount) {
|
|
831
1009
|
var fileName = (0, utils_1.generateSafeFileName)(usage.resourceDefinition.dataSourceType, usage.resourceDefinition.tableName, usage.resourceDefinition.dataSourceId);
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
(0, filter_utils_1.pushStateIdsAsDeps)(deps, depsSeen, usage.filterStateIds);
|
|
858
|
-
(0, filter_utils_1.pushPropIdsAsDeps)(deps, depsSeen, usage.filterPropIds);
|
|
859
|
-
pushUrlSearchParamMemoDeps(deps, usage);
|
|
860
|
-
return deps;
|
|
861
|
-
})()),
|
|
862
|
-
])));
|
|
1010
|
+
// ⛔ This list has no search input, so no `query` param — but it may
|
|
1011
|
+
// well have filters, and omitting them (as this call site did until
|
|
1012
|
+
// the shared builder replaced it) counts the WHOLE table: "Next"
|
|
1013
|
+
// stayed enabled far past the end of a filtered result set.
|
|
1014
|
+
var countUrlParams = [];
|
|
1015
|
+
if (usage.queryColumns.length > 0) {
|
|
1016
|
+
countUrlParams.push(types.objectProperty(types.identifier('queryColumns'), types.callExpression(types.memberExpression(types.identifier('JSON'), types.identifier('stringify')), [types.arrayExpression(usage.queryColumns.map(function (c) { return types.stringLiteral(c); }))])));
|
|
1017
|
+
}
|
|
1018
|
+
(0, filter_utils_1.appendFiltersParam)(countUrlParams, usage.filters, buildFilterDestinationExpression);
|
|
1019
|
+
// Default to mount-only; refresh when ANY filter destination
|
|
1020
|
+
// changes — state-bound (e.g. `selectedCategory`) and URL-driven —
|
|
1021
|
+
// so the pagination control reflects the current filtered count
|
|
1022
|
+
// instead of the unfiltered mount-time total.
|
|
1023
|
+
var countDeps = [];
|
|
1024
|
+
var countDepsSeen = new Set();
|
|
1025
|
+
(0, filter_utils_1.pushStateIdsAsDeps)(countDeps, countDepsSeen, usage.filterStateIds);
|
|
1026
|
+
(0, filter_utils_1.pushPropIdsAsDeps)(countDeps, countDepsSeen, usage.filterPropIds);
|
|
1027
|
+
pushUrlSearchParamMemoDeps(countDeps, usage);
|
|
1028
|
+
effectStatements.push((0, count_effect_1.buildCountFetchEffect)({
|
|
1029
|
+
fileName: fileName,
|
|
1030
|
+
perPage: usage.perPage,
|
|
1031
|
+
setMaxPagesVar: vars.setMaxPagesStateVar,
|
|
1032
|
+
urlParams: countUrlParams,
|
|
1033
|
+
deps: countDeps,
|
|
1034
|
+
}));
|
|
863
1035
|
}
|
|
1036
|
+
// Visible page numbers, when this mapper draws a numbered strip.
|
|
1037
|
+
pushPageTokensDeclaration(stateDeclarations, usage, vars);
|
|
1038
|
+
// Accumulation state, when it appends instead of paging.
|
|
1039
|
+
pushInfiniteScrollDeclarations(stateDeclarations, effectStatements, usage, vars);
|
|
1040
|
+
// A filter or sort change invalidates the page the visitor is on.
|
|
1041
|
+
pushFilterSortPageResetEffect(stateDeclarations, effectStatements, usage, vars);
|
|
1042
|
+
// Ordering matters — see `pushPageUrlSyncEffects`: the read-back runs
|
|
1043
|
+
// after the reset so a URL that names a page wins over it.
|
|
1044
|
+
pushPageUrlSyncEffects(stateDeclarations, effectStatements, usage, vars);
|
|
864
1045
|
}
|
|
865
1046
|
else if (usage.category === 'search-only') {
|
|
866
1047
|
// Search-only state
|
|
@@ -906,7 +1087,7 @@ var createNextArrayMapperPaginationPlugin = function () {
|
|
|
906
1087
|
});
|
|
907
1088
|
// Insert state declarations at the beginning
|
|
908
1089
|
stateDeclarations.reverse().forEach(function (s) { return blockStatement.body.unshift(s); });
|
|
909
|
-
needsUseRouter = registry.usages.some(function (u) { return hasUrlSearchParamFilters(u) || usageHasSearchUrlSync(u); });
|
|
1090
|
+
needsUseRouter = registry.usages.some(function (u) { return hasUrlSearchParamFilters(u) || usageHasSearchUrlSync(u) || usageHasPageUrlSync(u); });
|
|
910
1091
|
if (needsUseRouter) {
|
|
911
1092
|
if (!dependencies.useRouter) {
|
|
912
1093
|
// Match the shape the sibling Next.js plugins use (i18n locale mapper,
|
|
@@ -936,6 +1117,13 @@ var createNextArrayMapperPaginationPlugin = function () {
|
|
|
936
1117
|
]));
|
|
937
1118
|
}
|
|
938
1119
|
}
|
|
1120
|
+
// Both the search write-back and the page ⇄ URL effect write the URL through
|
|
1121
|
+
// the shared `URLQueryWriter`, so the ref + helper they close over must be in
|
|
1122
|
+
// the body. Idempotent with `createNextUrlSearchParamsPlugin`, which needs the
|
|
1123
|
+
// same pair for the category/sort dropdowns and may have run first.
|
|
1124
|
+
if (registry.usages.some(function (u) { return usageHasSearchUrlSync(u) || usageHasPageUrlSync(u); })) {
|
|
1125
|
+
teleport_plugin_common_1.URLQueryWriter.ensureQuerySyncDeclarations(blockStatement.body);
|
|
1126
|
+
}
|
|
939
1127
|
returnIndex = blockStatement.body.findIndex(function (s) { return s.type === 'ReturnStatement'; });
|
|
940
1128
|
insertIndex = returnIndex !== -1 ? returnIndex : blockStatement.body.length;
|
|
941
1129
|
effectStatements.reverse().forEach(function (e) { return blockStatement.body.splice(insertIndex, 0, e); });
|
|
@@ -946,6 +1134,8 @@ var createNextArrayMapperPaginationPlugin = function () {
|
|
|
946
1134
|
});
|
|
947
1135
|
usageIndexByDataSourceId = new Map();
|
|
948
1136
|
loadingStateDeclarations = [];
|
|
1137
|
+
usagesWithLoadingState = new Set();
|
|
1138
|
+
usageByProviderNode = new Map();
|
|
949
1139
|
cacheDeclarations = [];
|
|
950
1140
|
dataProvidersWithRepeaters.forEach(function (dp) {
|
|
951
1141
|
var _a, _b;
|
|
@@ -962,6 +1152,7 @@ var createNextArrayMapperPaginationPlugin = function () {
|
|
|
962
1152
|
}
|
|
963
1153
|
var usage = usages[currentIndex];
|
|
964
1154
|
usageIndexByDataSourceId.set(dataSourceIdentifier, currentIndex + 1);
|
|
1155
|
+
usageByProviderNode.set(dp, usage);
|
|
965
1156
|
var vars = getStateVarsForUsage(usage);
|
|
966
1157
|
var fileName = (0, utils_1.generateSafeFileName)(usage.resourceDefinition.dataSourceType, usage.resourceDefinition.tableName, usage.resourceDefinition.dataSourceId);
|
|
967
1158
|
// Update DataProvider based on category
|
|
@@ -984,6 +1175,15 @@ var createNextArrayMapperPaginationPlugin = function () {
|
|
|
984
1175
|
var loadingVars = (0, loading_state_1.getLoadingStateVars)(usage.index);
|
|
985
1176
|
if ((0, loading_state_1.applyLoadingStateToDataProvider)(dp, loadingVars)) {
|
|
986
1177
|
loadingStateDeclarations.push.apply(loadingStateDeclarations, (0, loading_state_1.buildLoadingStateDeclarations)(loadingVars));
|
|
1178
|
+
// Recorded because the loading state is only declared for a provider
|
|
1179
|
+
// that HAS a loading slot; a Load More button wired later may only
|
|
1180
|
+
// reference `ds_N_isFetching` if it actually exists.
|
|
1181
|
+
usagesWithLoadingState.add(usage.index);
|
|
1182
|
+
}
|
|
1183
|
+
// An auto-loading list needs something at the end of the rows for its
|
|
1184
|
+
// IntersectionObserver to watch.
|
|
1185
|
+
if (usage.infiniteScroll && usage.paginated && !usage.infiniteScrollLoadMore) {
|
|
1186
|
+
insertSentinelAfterProvider(blockStatement, dp, (0, infinite_scroll_1.buildSentinelElement)((0, infinite_scroll_1.getInfiniteScrollVars)(usage.index)));
|
|
987
1187
|
}
|
|
988
1188
|
// Create API route for all categories (including 'plain' for components)
|
|
989
1189
|
ensureAPIRouteExists(options.extractedResources, usage, options.dataSources, (0, transformations_1.buildProductTransformOptions)(options));
|
|
@@ -1035,16 +1235,23 @@ var createNextArrayMapperPaginationPlugin = function () {
|
|
|
1035
1235
|
var vars = getStateVarsForUsage(usage);
|
|
1036
1236
|
wireSearchInput(input.node, vars);
|
|
1037
1237
|
});
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
//
|
|
1041
|
-
|
|
1042
|
-
|
|
1238
|
+
// STEP 5: Wire pagination widgets
|
|
1239
|
+
//
|
|
1240
|
+
// Each widget belongs to the mapper whose `DataProvider` it follows in the
|
|
1241
|
+
// document — the builder emits it as a sibling of (or inside) that provider.
|
|
1242
|
+
//
|
|
1243
|
+
// ⛔ Not a positional zip of "widgets" against "paginated usages": the two
|
|
1244
|
+
// lists no longer have to be the same length, because an infinite-scroll
|
|
1245
|
+
// mapper renders no widget. Counting one for it would shift every later
|
|
1246
|
+
// mapper onto the wrong usage and wire one list's buttons to another list's
|
|
1247
|
+
// state. Anchoring on the provider cannot drift for the same reason the
|
|
1248
|
+
// provider loop above cannot.
|
|
1249
|
+
findPaginationNodesWithOwners(blockStatement, usageByProviderNode).forEach(function (_a) {
|
|
1250
|
+
var node = _a.node, usage = _a.usage;
|
|
1251
|
+
if (!usage) {
|
|
1043
1252
|
return;
|
|
1044
1253
|
}
|
|
1045
|
-
|
|
1046
|
-
var vars = getStateVarsForUsage(usage);
|
|
1047
|
-
wirePaginationButtons(paginationNode.node, usage, vars);
|
|
1254
|
+
wirePaginationWidget(node, usage, getStateVarsForUsage(usage), usagesWithLoadingState.has(usage.index));
|
|
1048
1255
|
});
|
|
1049
1256
|
// STEP 6: Update getStaticProps if this is a page
|
|
1050
1257
|
if (isPage) {
|
|
@@ -1057,6 +1264,57 @@ var createNextArrayMapperPaginationPlugin = function () {
|
|
|
1057
1264
|
};
|
|
1058
1265
|
exports.createNextArrayMapperPaginationPlugin = createNextArrayMapperPaginationPlugin;
|
|
1059
1266
|
// ==================== HELPER FUNCTIONS ====================
|
|
1267
|
+
/**
|
|
1268
|
+
* Inserts the scroll sentinel immediately after a `DataProvider`, as its next
|
|
1269
|
+
* sibling, so it sits below the rendered rows.
|
|
1270
|
+
*
|
|
1271
|
+
* It has to be a sibling: the provider's own child is a render-prop function,
|
|
1272
|
+
* and anything placed inside it would be re-created on every fetch — the
|
|
1273
|
+
* observer would then be watching an element that is no longer in the document.
|
|
1274
|
+
*
|
|
1275
|
+
* Returns false when the provider has no element parent to splice into (a
|
|
1276
|
+
* provider returned directly from the component), leaving the list on its
|
|
1277
|
+
* count-driven `hasMore` rather than injecting a stray node.
|
|
1278
|
+
*/
|
|
1279
|
+
function insertSentinelAfterProvider(blockStatement, provider, sentinel) {
|
|
1280
|
+
var inserted = false;
|
|
1281
|
+
var traverse = function (node) {
|
|
1282
|
+
if (!node || inserted) {
|
|
1283
|
+
return;
|
|
1284
|
+
}
|
|
1285
|
+
if (Array.isArray(node.children)) {
|
|
1286
|
+
var at = node.children.indexOf(provider);
|
|
1287
|
+
if (at !== -1) {
|
|
1288
|
+
node.children.splice(at + 1, 0, sentinel);
|
|
1289
|
+
inserted = true;
|
|
1290
|
+
return;
|
|
1291
|
+
}
|
|
1292
|
+
node.children.forEach(traverse);
|
|
1293
|
+
}
|
|
1294
|
+
if (node.body) {
|
|
1295
|
+
if (Array.isArray(node.body)) {
|
|
1296
|
+
node.body.forEach(traverse);
|
|
1297
|
+
}
|
|
1298
|
+
else {
|
|
1299
|
+
traverse(node.body);
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
if (node.consequent) {
|
|
1303
|
+
traverse(node.consequent);
|
|
1304
|
+
}
|
|
1305
|
+
if (node.alternate) {
|
|
1306
|
+
traverse(node.alternate);
|
|
1307
|
+
}
|
|
1308
|
+
if (node.expression) {
|
|
1309
|
+
traverse(node.expression);
|
|
1310
|
+
}
|
|
1311
|
+
if (node.argument) {
|
|
1312
|
+
traverse(node.argument);
|
|
1313
|
+
}
|
|
1314
|
+
};
|
|
1315
|
+
traverse(blockStatement);
|
|
1316
|
+
return inserted;
|
|
1317
|
+
}
|
|
1060
1318
|
function findAllDataProvidersInJSX(blockStatement) {
|
|
1061
1319
|
var results = [];
|
|
1062
1320
|
var traverse = function (node) {
|
|
@@ -1176,18 +1434,32 @@ function findAllSearchInputsInJSX(blockStatement) {
|
|
|
1176
1434
|
traverse(blockStatement);
|
|
1177
1435
|
return results;
|
|
1178
1436
|
}
|
|
1179
|
-
|
|
1437
|
+
/**
|
|
1438
|
+
* Every pagination widget in the JSX, paired with the mapper it belongs to.
|
|
1439
|
+
*
|
|
1440
|
+
* Ownership follows document order: a widget belongs to the most recent
|
|
1441
|
+
* `DataProvider` seen before it, which is exactly how the builder emits it —
|
|
1442
|
+
* as a sibling that follows its provider, or nested inside that provider's
|
|
1443
|
+
* subtree. A widget that precedes every provider (nothing sensible to wire it
|
|
1444
|
+
* to) comes back with no owner and is left alone.
|
|
1445
|
+
*/
|
|
1446
|
+
function findPaginationNodesWithOwners(blockStatement, usageByProviderNode) {
|
|
1180
1447
|
var results = [];
|
|
1448
|
+
var currentUsage;
|
|
1181
1449
|
var traverse = function (node) {
|
|
1182
1450
|
var _a, _b, _c, _d, _e;
|
|
1183
1451
|
if (!node) {
|
|
1184
1452
|
return;
|
|
1185
1453
|
}
|
|
1186
1454
|
if (node.type === 'JSXElement') {
|
|
1455
|
+
var owner = usageByProviderNode.get(node);
|
|
1456
|
+
if (owner) {
|
|
1457
|
+
currentUsage = owner;
|
|
1458
|
+
}
|
|
1187
1459
|
var classAttr = (_b = (_a = node.openingElement) === null || _a === void 0 ? void 0 : _a.attributes) === null || _b === void 0 ? void 0 : _b.find(function (attr) { return attr.type === 'JSXAttribute' && attr.name.name === 'className'; });
|
|
1188
1460
|
var className = ((_c = classAttr === null || classAttr === void 0 ? void 0 : classAttr.value) === null || _c === void 0 ? void 0 : _c.value) || ((_e = (_d = classAttr === null || classAttr === void 0 ? void 0 : classAttr.value) === null || _d === void 0 ? void 0 : _d.expression) === null || _e === void 0 ? void 0 : _e.value) || '';
|
|
1189
1461
|
if (className.includes('cms-pagination-node')) {
|
|
1190
|
-
results.push({ node: node,
|
|
1462
|
+
results.push({ node: node, usage: currentUsage });
|
|
1191
1463
|
}
|
|
1192
1464
|
}
|
|
1193
1465
|
if (node.children && Array.isArray(node.children)) {
|
|
@@ -1250,7 +1522,6 @@ dp, usage, paramsProps, memoDeps, cacheDeclarations) {
|
|
|
1250
1522
|
return hoisted.cachedIdentifier;
|
|
1251
1523
|
}
|
|
1252
1524
|
function updateDataProviderForPaginatedSearch(dp, usage, vars, fileName, cacheDeclarations) {
|
|
1253
|
-
var _a;
|
|
1254
1525
|
var attrs = dp.openingElement.attributes;
|
|
1255
1526
|
// Remove existing params, key, initialData, fetchData, persistDataDuringLoading
|
|
1256
1527
|
dp.openingElement.attributes = attrs.filter(function (attr) {
|
|
@@ -1286,7 +1557,12 @@ function updateDataProviderForPaginatedSearch(dp, usage, vars, fileName, cacheDe
|
|
|
1286
1557
|
// the first client fetch (its internal guard only skips when initialData is
|
|
1287
1558
|
// defined on mount). Without that skip, toggling sort correctly triggers a
|
|
1288
1559
|
// refetch via the useMemo params dependency chain.
|
|
1289
|
-
|
|
1560
|
+
//
|
|
1561
|
+
// An appending list skips it for a second reason: `initialData` makes
|
|
1562
|
+
// DataProvider skip its first fetch, so page 1 would render from the prefetch
|
|
1563
|
+
// and never enter the accumulator — appending page 2 would then REPLACE the
|
|
1564
|
+
// visible rows with page 2 alone.
|
|
1565
|
+
if (!usage.dynamicSort && !usage.infiniteScroll) {
|
|
1290
1566
|
var initialDataCondition = wrapInitialDataWithUrlFilterGuard(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);
|
|
1291
1567
|
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')))));
|
|
1292
1568
|
}
|
|
@@ -1295,24 +1571,37 @@ function updateDataProviderForPaginatedSearch(dp, usage, vars, fileName, cacheDe
|
|
|
1295
1571
|
// "skip-first-fetch-when-we-have-initialData" guard, which would prevent the
|
|
1296
1572
|
// new sort params from reaching the fetcher. Leaving sort out of the key
|
|
1297
1573
|
// lets the useMemo params identity change alone drive refetch.
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
types.
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1574
|
+
//
|
|
1575
|
+
// ⛔ The page is left out too when the list APPENDS: remounting on every
|
|
1576
|
+
// appended page would unmount the accumulated rows and refetch from scratch.
|
|
1577
|
+
// The query stays in the key, so a new search still starts a clean list.
|
|
1578
|
+
dp.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('key'), types.jsxExpressionContainer(usage.infiniteScroll
|
|
1579
|
+
? types.templateLiteral([
|
|
1580
|
+
types.templateElement({
|
|
1581
|
+
raw: "".concat(usage.dataSourceIdentifier, "-"),
|
|
1582
|
+
cooked: "".concat(usage.dataSourceIdentifier, "-"),
|
|
1583
|
+
}),
|
|
1584
|
+
types.templateElement({ raw: '', cooked: '' }),
|
|
1585
|
+
], [
|
|
1586
|
+
types.memberExpression(types.identifier(vars.combinedStateVar), types.identifier('debouncedQuery')),
|
|
1587
|
+
])
|
|
1588
|
+
: types.templateLiteral([
|
|
1589
|
+
types.templateElement({
|
|
1590
|
+
raw: "".concat(usage.dataSourceIdentifier, "-"),
|
|
1591
|
+
cooked: "".concat(usage.dataSourceIdentifier, "-"),
|
|
1592
|
+
}),
|
|
1593
|
+
types.templateElement({ raw: '-', cooked: '-' }),
|
|
1594
|
+
types.templateElement({ raw: '', cooked: '' }),
|
|
1595
|
+
], [
|
|
1596
|
+
types.memberExpression(types.identifier(vars.combinedStateVar), types.identifier('page')),
|
|
1597
|
+
types.memberExpression(types.identifier(vars.combinedStateVar), types.identifier('debouncedQuery')),
|
|
1598
|
+
]))));
|
|
1309
1599
|
// Add fetchData
|
|
1310
|
-
dp.openingElement.attributes.push(
|
|
1600
|
+
dp.openingElement.attributes.push(buildFetchDataForUsage(fileName, usage));
|
|
1311
1601
|
// Add persistDataDuringLoading
|
|
1312
1602
|
dp.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('persistDataDuringLoading'), types.jsxExpressionContainer(types.booleanLiteral(true))));
|
|
1313
1603
|
}
|
|
1314
1604
|
function updateDataProviderForPaginationOnly(dp, usage, vars, fileName, cacheDeclarations) {
|
|
1315
|
-
var _a;
|
|
1316
1605
|
var attrs = dp.openingElement.attributes;
|
|
1317
1606
|
dp.openingElement.attributes = attrs.filter(function (attr) {
|
|
1318
1607
|
var _a;
|
|
@@ -1339,20 +1628,26 @@ function updateDataProviderForPaginationOnly(dp, usage, vars, fileName, cacheDec
|
|
|
1339
1628
|
// Add params
|
|
1340
1629
|
var cachedInitialData = pushParamsAttribute(dp, usage, paramsProps, memoDeps, cacheDeclarations);
|
|
1341
1630
|
// Add initialData. See paginated+search updater for why we skip prefetch
|
|
1342
|
-
// reuse when a dynamic state-bound sort is active
|
|
1343
|
-
|
|
1631
|
+
// reuse when a dynamic state-bound sort is active, and why an appending list
|
|
1632
|
+
// skips it too.
|
|
1633
|
+
if (!usage.dynamicSort && !usage.infiniteScroll) {
|
|
1344
1634
|
dp.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('initialData'), types.jsxExpressionContainer(types.conditionalExpression(wrapInitialDataWithUrlFilterGuard(types.binaryExpression('===', types.identifier(vars.pageStateVar), types.numericLiteral(1)), usage), types.optionalMemberExpression(types.identifier('props'), types.identifier(vars.propsPrefix), false, true), cachedInitialData ? types.identifier(cachedInitialData) : types.identifier('undefined')))));
|
|
1345
1635
|
}
|
|
1346
|
-
// Add key — sort is intentionally NOT included; see paginated+search updater
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1636
|
+
// Add key — sort is intentionally NOT included; see paginated+search updater,
|
|
1637
|
+
// which also explains why an appending list keys on nothing at all (there is
|
|
1638
|
+
// no query here to vary it by; a filter change restarts the accumulator
|
|
1639
|
+
// through its signature instead).
|
|
1640
|
+
if (!usage.infiniteScroll) {
|
|
1641
|
+
dp.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('key'), types.jsxExpressionContainer(types.templateLiteral([
|
|
1642
|
+
types.templateElement({
|
|
1643
|
+
raw: "".concat(usage.dataSourceIdentifier, "-page-"),
|
|
1644
|
+
cooked: "".concat(usage.dataSourceIdentifier, "-page-"),
|
|
1645
|
+
}),
|
|
1646
|
+
types.templateElement({ raw: '', cooked: '' }),
|
|
1647
|
+
], [types.identifier(vars.pageStateVar)]))));
|
|
1648
|
+
}
|
|
1354
1649
|
// Add fetchData
|
|
1355
|
-
dp.openingElement.attributes.push(
|
|
1650
|
+
dp.openingElement.attributes.push(buildFetchDataForUsage(fileName, usage));
|
|
1356
1651
|
dp.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('persistDataDuringLoading'), types.jsxExpressionContainer(types.booleanLiteral(true))));
|
|
1357
1652
|
}
|
|
1358
1653
|
function updateDataProviderForSearchOnly(dp, usage, vars, fileName, cacheDeclarations) {
|
|
@@ -1485,7 +1780,10 @@ function stabilizeDataProviderWithoutRepeater(dp) {
|
|
|
1485
1780
|
// Replace the params attribute
|
|
1486
1781
|
attrs[paramsAttrIndex] = types.jsxAttribute(types.jsxIdentifier('params'), types.jsxExpressionContainer(memoizedParams));
|
|
1487
1782
|
}
|
|
1488
|
-
function createFetchDataAttribute(fileName, cache
|
|
1783
|
+
function createFetchDataAttribute(fileName, cache,
|
|
1784
|
+
// When set, the resolved value is every page fetched so far rather than just
|
|
1785
|
+
// the page that was requested — see `infinite-scroll.ts`.
|
|
1786
|
+
accumulate) {
|
|
1489
1787
|
var fetchCall = types.callExpression(types.identifier('fetch'), [
|
|
1490
1788
|
types.templateLiteral([
|
|
1491
1789
|
types.templateElement({
|
|
@@ -1506,7 +1804,16 @@ function createFetchDataAttribute(fileName, cache) {
|
|
|
1506
1804
|
// The uncached tail is left exactly as it has always been emitted, so a
|
|
1507
1805
|
// project that does not cache produces byte-identical output.
|
|
1508
1806
|
var uncachedTail = types.arrowFunctionExpression([types.identifier('response')], types.optionalMemberExpression(types.identifier('response'), types.identifier('data'), false, true));
|
|
1509
|
-
|
|
1807
|
+
// ⛔ Accumulation and the client cache are mutually exclusive: a cache hit
|
|
1808
|
+
// short-circuits the fetch and hands back one page's rows, which would drop
|
|
1809
|
+
// every page already accumulated. The caller suppresses the client cache for
|
|
1810
|
+
// an appending list, so this branch never sees both.
|
|
1811
|
+
var responseTail = accumulate
|
|
1812
|
+
? (0, infinite_scroll_1.buildAccumulatingResponseHandler)((0, infinite_scroll_1.getInfiniteScrollVars)(accumulate.usage.index), accumulate.usage.perPage)
|
|
1813
|
+
: cache
|
|
1814
|
+
? (0, ast_1.buildCacheStoreThen)(cache)
|
|
1815
|
+
: uncachedTail;
|
|
1816
|
+
var networkChain = types.callExpression(types.memberExpression(parsedJson, types.identifier('then')), [responseTail]);
|
|
1510
1817
|
var arrow = cache
|
|
1511
1818
|
? types.arrowFunctionExpression([types.identifier('params')], (0, ast_1.buildCachedFetchBody)(networkChain, cache))
|
|
1512
1819
|
: types.arrowFunctionExpression([types.identifier('params')], networkChain);
|
|
@@ -1522,45 +1829,91 @@ function wireSearchInput(inputNode, vars) {
|
|
|
1522
1829
|
// Add value
|
|
1523
1830
|
inputNode.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('value'), types.jsxExpressionContainer(types.identifier(vars.searchQueryVar))));
|
|
1524
1831
|
}
|
|
1832
|
+
/**
|
|
1833
|
+
* The `fetchData` attribute for one paginated usage.
|
|
1834
|
+
*
|
|
1835
|
+
* ⛔ An appending list gets no CLIENT cache: a cache hit resolves with one
|
|
1836
|
+
* page's rows without going through the accumulator, which would silently
|
|
1837
|
+
* discard every page already loaded. The SERVER cache is untouched — it sits
|
|
1838
|
+
* behind the API route and returns the same page either way.
|
|
1839
|
+
*/
|
|
1840
|
+
function buildFetchDataForUsage(fileName, usage) {
|
|
1841
|
+
var _a;
|
|
1842
|
+
if (usage.infiniteScroll) {
|
|
1843
|
+
return createFetchDataAttribute(fileName, undefined, { usage: usage });
|
|
1844
|
+
}
|
|
1845
|
+
return createFetchDataAttribute(fileName, ((_a = usage.cache) === null || _a === void 0 ? void 0 : _a.client) ? usage.cache : undefined);
|
|
1846
|
+
}
|
|
1847
|
+
/**
|
|
1848
|
+
* Wires the authored Load More button of an appending list.
|
|
1849
|
+
*
|
|
1850
|
+
* Disabled — not hidden — when there is nothing left to load, so the author's
|
|
1851
|
+
* styling of the finished state is theirs to decide, and so the control does
|
|
1852
|
+
* not vanish from under the visitor's cursor mid-click.
|
|
1853
|
+
*/
|
|
1854
|
+
function wireLoadMoreButton(paginationNode, usage, vars, hasLoadingState) {
|
|
1855
|
+
if (!usage.infiniteScrollLoadMore) {
|
|
1856
|
+
return;
|
|
1857
|
+
}
|
|
1858
|
+
var button = (0, pagination_controls_1.findPaginationControl)(paginationNode, 'load-more');
|
|
1859
|
+
if (!button) {
|
|
1860
|
+
return;
|
|
1861
|
+
}
|
|
1862
|
+
var infiniteVars = (0, infinite_scroll_1.getInfiniteScrollVars)(usage.index);
|
|
1863
|
+
(0, pagination_controls_1.convertControlToButton)(button);
|
|
1864
|
+
(0, pagination_controls_1.setJSXExpressionAttribute)(button, 'onClick', types.arrowFunctionExpression([],
|
|
1865
|
+
// The advance statement is an expression statement; the handler needs the
|
|
1866
|
+
// expression itself.
|
|
1867
|
+
buildAdvancePageStatement(usage, vars).expression));
|
|
1868
|
+
// The in-flight term is only referenced when the provider declared it —
|
|
1869
|
+
// a mapper with no loading branch never gets `ds_N_isFetching`.
|
|
1870
|
+
var notHasMore = types.unaryExpression('!', types.identifier(infiniteVars.hasMoreVar), true);
|
|
1871
|
+
(0, pagination_controls_1.setJSXExpressionAttribute)(button, 'disabled', hasLoadingState
|
|
1872
|
+
? types.logicalExpression('||', notHasMore, types.identifier((0, loading_state_1.getLoadingStateVars)(usage.index).isFetchingVar))
|
|
1873
|
+
: notHasMore);
|
|
1874
|
+
}
|
|
1875
|
+
/**
|
|
1876
|
+
* Wires one mapper's pagination container according to the mode it is in, and
|
|
1877
|
+
* removes the controls belonging to the other modes.
|
|
1878
|
+
*
|
|
1879
|
+
* The builder never deletes a control when the author switches mode — doing so
|
|
1880
|
+
* would throw away their styling — so the container can hold a superset of what
|
|
1881
|
+
* any one mode needs. Pruning here is what keeps a Previous/Next list from
|
|
1882
|
+
* rendering a dead numbered strip, and an infinite list from rendering page
|
|
1883
|
+
* buttons beside its Load More.
|
|
1884
|
+
*/
|
|
1885
|
+
function wirePaginationWidget(paginationNode, usage, vars, hasLoadingState) {
|
|
1886
|
+
if (usage.infiniteScroll) {
|
|
1887
|
+
// Only the Load More button survives; page controls make no sense for a
|
|
1888
|
+
// list the visitor never leaves.
|
|
1889
|
+
(0, pagination_controls_1.dropInactivePaginationControls)(paginationNode, ['load-more']);
|
|
1890
|
+
wireLoadMoreButton(paginationNode, usage, vars, hasLoadingState);
|
|
1891
|
+
return;
|
|
1892
|
+
}
|
|
1893
|
+
var activeKinds = usage.paginationMode === 'numbered'
|
|
1894
|
+
? ['first', 'previous', 'pages', 'page', 'ellipsis', 'next', 'last']
|
|
1895
|
+
: ['previous', 'next'];
|
|
1896
|
+
(0, pagination_controls_1.dropInactivePaginationControls)(paginationNode, activeKinds);
|
|
1897
|
+
wirePaginationButtons(paginationNode, usage, vars);
|
|
1898
|
+
if (usage.paginationMode === 'numbered') {
|
|
1899
|
+
var _a = getPageAccessors(usage, vars), currentPageExpr = _a.currentPageExpr, buildSetPageStatement = _a.buildSetPageStatement;
|
|
1900
|
+
var numberedVars = {
|
|
1901
|
+
index: usage.index,
|
|
1902
|
+
maxPagesVar: vars.maxPagesStateVar,
|
|
1903
|
+
currentPageExpr: currentPageExpr,
|
|
1904
|
+
buildSetPageStatement: buildSetPageStatement,
|
|
1905
|
+
};
|
|
1906
|
+
(0, numbered_pagination_1.wireNumberedPagination)(paginationNode, numberedVars);
|
|
1907
|
+
}
|
|
1908
|
+
}
|
|
1525
1909
|
function wirePaginationButtons(paginationNode, usage, vars) {
|
|
1526
|
-
//
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
return null;
|
|
1531
|
-
}
|
|
1532
|
-
if (node.type === 'JSXElement') {
|
|
1533
|
-
var classAttr = (_b = (_a = node.openingElement) === null || _a === void 0 ? void 0 : _a.attributes) === null || _b === void 0 ? void 0 : _b.find(function (attr) { return attr.type === 'JSXAttribute' && attr.name.name === 'className'; });
|
|
1534
|
-
var className = ((_c = classAttr === null || classAttr === void 0 ? void 0 : classAttr.value) === null || _c === void 0 ? void 0 : _c.value) || ((_e = (_d = classAttr === null || classAttr === void 0 ? void 0 : classAttr.value) === null || _d === void 0 ? void 0 : _d.expression) === null || _e === void 0 ? void 0 : _e.value) || '';
|
|
1535
|
-
if (className.includes(direction)) {
|
|
1536
|
-
return node;
|
|
1537
|
-
}
|
|
1538
|
-
}
|
|
1539
|
-
if (node.children && Array.isArray(node.children)) {
|
|
1540
|
-
for (var _i = 0, _f = node.children; _i < _f.length; _i++) {
|
|
1541
|
-
var c = _f[_i];
|
|
1542
|
-
var found = findButton(c, direction);
|
|
1543
|
-
if (found) {
|
|
1544
|
-
return found;
|
|
1545
|
-
}
|
|
1546
|
-
}
|
|
1547
|
-
}
|
|
1548
|
-
return null;
|
|
1549
|
-
};
|
|
1550
|
-
var prevButton = findButton(paginationNode, 'previous');
|
|
1551
|
-
var nextButton = findButton(paginationNode, 'next');
|
|
1910
|
+
// Marker attribute first, class-name substring second — projects generated
|
|
1911
|
+
// before the marker existed carry only the class name.
|
|
1912
|
+
var prevButton = (0, pagination_controls_1.findPaginationControl)(paginationNode, 'previous', 'previous');
|
|
1913
|
+
var nextButton = (0, pagination_controls_1.findPaginationControl)(paginationNode, 'next', 'next');
|
|
1552
1914
|
var isCombinedState = usage.category === 'paginated+search';
|
|
1553
1915
|
if (prevButton) {
|
|
1554
|
-
|
|
1555
|
-
prevButton.openingElement.name.name = 'button';
|
|
1556
|
-
if (prevButton.closingElement) {
|
|
1557
|
-
prevButton.closingElement.name.name = 'button';
|
|
1558
|
-
}
|
|
1559
|
-
// Add type="button"
|
|
1560
|
-
var hasType = prevButton.openingElement.attributes.some(function (a) { var _a; return ((_a = a.name) === null || _a === void 0 ? void 0 : _a.name) === 'type'; });
|
|
1561
|
-
if (!hasType) {
|
|
1562
|
-
prevButton.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('type'), types.stringLiteral('button')));
|
|
1563
|
-
}
|
|
1916
|
+
(0, pagination_controls_1.convertControlToButton)(prevButton);
|
|
1564
1917
|
// Add onClick
|
|
1565
1918
|
prevButton.openingElement.attributes = prevButton.openingElement.attributes.filter(function (a) { var _a; return ((_a = a.name) === null || _a === void 0 ? void 0 : _a.name) !== 'onClick'; });
|
|
1566
1919
|
if (isCombinedState) {
|
|
@@ -1589,14 +1942,7 @@ function wirePaginationButtons(paginationNode, usage, vars) {
|
|
|
1589
1942
|
}
|
|
1590
1943
|
}
|
|
1591
1944
|
if (nextButton) {
|
|
1592
|
-
nextButton
|
|
1593
|
-
if (nextButton.closingElement) {
|
|
1594
|
-
nextButton.closingElement.name.name = 'button';
|
|
1595
|
-
}
|
|
1596
|
-
var hasType = nextButton.openingElement.attributes.some(function (a) { var _a; return ((_a = a.name) === null || _a === void 0 ? void 0 : _a.name) === 'type'; });
|
|
1597
|
-
if (!hasType) {
|
|
1598
|
-
nextButton.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('type'), types.stringLiteral('button')));
|
|
1599
|
-
}
|
|
1945
|
+
(0, pagination_controls_1.convertControlToButton)(nextButton);
|
|
1600
1946
|
nextButton.openingElement.attributes = nextButton.openingElement.attributes.filter(function (a) { var _a; return ((_a = a.name) === null || _a === void 0 ? void 0 : _a.name) !== 'onClick'; });
|
|
1601
1947
|
if (isCombinedState) {
|
|
1602
1948
|
nextButton.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('onClick'), types.jsxExpressionContainer(types.arrowFunctionExpression([], types.callExpression(types.identifier(vars.setCombinedStateVar), [
|
|
@@ -1851,8 +2197,7 @@ function updateGetStaticProps(chunks, registry, dependencies, folderPath) {
|
|
|
1851
2197
|
]));
|
|
1852
2198
|
// Add import dependency for the fetcher
|
|
1853
2199
|
if (!dependencies[fetcherImportName]) {
|
|
1854
|
-
var
|
|
1855
|
-
var relativePrefix = '../'.repeat(depth);
|
|
2200
|
+
var relativePrefix = teleport_shared_1.GenericUtils.generatePageToRootPrefix({ folderPath: folderPath });
|
|
1856
2201
|
dependencies[fetcherImportName] = {
|
|
1857
2202
|
type: 'local',
|
|
1858
2203
|
path: "".concat(relativePrefix, "utils/data-sources/").concat(fileName),
|
|
@@ -1966,8 +2311,7 @@ function updateGetStaticProps(chunks, registry, dependencies, folderPath) {
|
|
|
1966
2311
|
}
|
|
1967
2312
|
// Add import dependency for the fetcher
|
|
1968
2313
|
if (!dependencies[fetcherImportName]) {
|
|
1969
|
-
var
|
|
1970
|
-
var relativePrefix = '../'.repeat(depth);
|
|
2314
|
+
var relativePrefix = teleport_shared_1.GenericUtils.generatePageToRootPrefix({ folderPath: folderPath });
|
|
1971
2315
|
dependencies[fetcherImportName] = {
|
|
1972
2316
|
type: 'local',
|
|
1973
2317
|
path: "".concat(relativePrefix, "utils/data-sources/").concat(fileName),
|