@teleporthq/teleport-plugin-next-data-source 0.42.0 → 0.42.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/COUNT_API_FIX.md +185 -0
- package/SEARCH_FIX_SUMMARY.md +96 -0
- package/dist/cjs/pagination-plugin.d.ts.map +1 -1
- package/dist/cjs/pagination-plugin.js +129 -46
- package/dist/cjs/pagination-plugin.js.map +1 -1
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/pagination-plugin.d.ts.map +1 -1
- package/dist/esm/pagination-plugin.js +129 -46
- package/dist/esm/pagination-plugin.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/pagination-plugin.ts +132 -39
package/COUNT_API_FIX.md
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# Count API Route Fix
|
|
2
|
+
|
|
3
|
+
## Problem
|
|
4
|
+
|
|
5
|
+
When pages with pagination + search functionality were generated, the code included `useEffect` hooks that fetched from count API endpoints (e.g., `/api/cockroachdb-users-eab38133-count`), but these count API route files were not being created. This resulted in 404 errors when users searched.
|
|
6
|
+
|
|
7
|
+
### Affected Code
|
|
8
|
+
|
|
9
|
+
In the generated page `index.js`:
|
|
10
|
+
```javascript
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
if (skipCountFetchOnMount_pg_1.current) {
|
|
13
|
+
skipCountFetchOnMount_pg_1.current = false
|
|
14
|
+
return
|
|
15
|
+
}
|
|
16
|
+
fetch(
|
|
17
|
+
`/api/cockroachdb-users-eab38133-count?${new URLSearchParams({
|
|
18
|
+
query: paginationState_pg_1.debouncedQuery,
|
|
19
|
+
queryColumns: JSON.stringify(['name']),
|
|
20
|
+
})}`
|
|
21
|
+
)
|
|
22
|
+
.then((res) => res.json())
|
|
23
|
+
.then((data) => {
|
|
24
|
+
if (data && 'count' in data) {
|
|
25
|
+
setPagination_pg_1_maxPages(
|
|
26
|
+
data.count === 0 ? 0 : Math.ceil(data.count / 3)
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
})
|
|
30
|
+
}, [paginationState_pg_1.debouncedQuery])
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
But `/api/cockroachdb-users-eab38133-count.js` did **not exist**.
|
|
34
|
+
|
|
35
|
+
## Root Cause
|
|
36
|
+
|
|
37
|
+
In `pagination-plugin.ts`, the `createAPIRoutesForPaginatedDataSources()` function:
|
|
38
|
+
```typescript
|
|
39
|
+
// OLD CODE (line 2354)
|
|
40
|
+
if (isComponent) { // ❌ Only created for components!
|
|
41
|
+
// Create count API route
|
|
42
|
+
extractedResources[`api/${countFileName}`] = { ... }
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The count API route was only being created for **components**, but pages with search functionality also need it to refetch count when the search query changes.
|
|
47
|
+
|
|
48
|
+
## Why Pages with Search Need Count Routes
|
|
49
|
+
|
|
50
|
+
### Different Scenarios:
|
|
51
|
+
|
|
52
|
+
1. **Pages with pagination ONLY (no search)**:
|
|
53
|
+
- Initial count fetched in `getStaticProps`
|
|
54
|
+
- Count is static - doesn't change during user interaction
|
|
55
|
+
- ✅ No count API route needed
|
|
56
|
+
|
|
57
|
+
2. **Pages with pagination + SEARCH**:
|
|
58
|
+
- Initial count fetched in `getStaticProps` (for page 1, no search)
|
|
59
|
+
- Count changes when user searches
|
|
60
|
+
- Need to refetch count with search parameters
|
|
61
|
+
- ❌ **NEEDS count API route** (was missing!)
|
|
62
|
+
|
|
63
|
+
3. **Components with pagination (with or without search)**:
|
|
64
|
+
- No `getStaticProps`
|
|
65
|
+
- Always fetch count client-side
|
|
66
|
+
- ✅ **NEEDS count API route** (was already working)
|
|
67
|
+
|
|
68
|
+
4. **Search-only (no pagination)**:
|
|
69
|
+
- No pagination, no maxPages calculation needed
|
|
70
|
+
- ✅ No count route needed
|
|
71
|
+
|
|
72
|
+
## Solution
|
|
73
|
+
|
|
74
|
+
Changed the condition from "only components" to "components OR pages with search":
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
// NEW CODE (lines 2344-2364)
|
|
78
|
+
const searchEnabledDataSources = new Set(
|
|
79
|
+
paginationInfos
|
|
80
|
+
.filter((info) => info.searchEnabled)
|
|
81
|
+
.map((info) => info.dataSourceIdentifier)
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
const createdCountRoutes = new Set<string>()
|
|
85
|
+
|
|
86
|
+
// ... in traverseForDataSources:
|
|
87
|
+
const hasSearch = searchEnabledDataSources.has(renderProp)
|
|
88
|
+
const needsCountRoute = isComponent || hasSearch // ✅ Now checks both!
|
|
89
|
+
|
|
90
|
+
if (needsCountRoute) {
|
|
91
|
+
const resourceDef = node.content.resourceDefinition
|
|
92
|
+
if (resourceDef) {
|
|
93
|
+
// ... create count route
|
|
94
|
+
if (!createdCountRoutes.has(countFileName)) {
|
|
95
|
+
extractedResources[`api/${countFileName}`] = {
|
|
96
|
+
fileName: countFileName,
|
|
97
|
+
fileType: FileType.JS,
|
|
98
|
+
path: ['pages', 'api'],
|
|
99
|
+
content: `import dataSource from '../../utils/data-sources/${fileName}'
|
|
100
|
+
|
|
101
|
+
export default dataSource.getCount
|
|
102
|
+
`,
|
|
103
|
+
}
|
|
104
|
+
createdCountRoutes.add(countFileName)
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Additional Improvements
|
|
111
|
+
|
|
112
|
+
1. **Deduplication**: Added `createdCountRoutes` Set to prevent creating the same count route multiple times when the same data source is used with different perPage settings
|
|
113
|
+
|
|
114
|
+
2. **Clear Logic**: The condition `needsCountRoute = isComponent || hasSearch` makes it explicit when count routes are needed
|
|
115
|
+
|
|
116
|
+
## Generated Files
|
|
117
|
+
|
|
118
|
+
After the fix, for a page with search, the following files are generated:
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
pages/
|
|
122
|
+
api/
|
|
123
|
+
cockroachdb-users-eab38133.js ✅ Main data API route
|
|
124
|
+
cockroachdb-users-eab38133-count.js ✅ Count API route (NOW CREATED!)
|
|
125
|
+
|
|
126
|
+
utils/
|
|
127
|
+
data-sources/
|
|
128
|
+
cockroachdb-users-eab38133.js ✅ Data source module with fetchData, fetchCount, handler, getCount
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Testing
|
|
132
|
+
|
|
133
|
+
Verified with the provided UIDL containing:
|
|
134
|
+
- Table with pagination + search
|
|
135
|
+
- Array mapper with pagination + search
|
|
136
|
+
- Both bound to the same CockroachDB data source
|
|
137
|
+
|
|
138
|
+
Results:
|
|
139
|
+
- ✅ Count API route created: `/api/cockroachdb-users-eab38133-count.js`
|
|
140
|
+
- ✅ File exports `dataSource.getCount` handler
|
|
141
|
+
- ✅ Search functionality works without 404 errors
|
|
142
|
+
- ✅ Count updates correctly when search query changes
|
|
143
|
+
|
|
144
|
+
## Edge Cases Handled
|
|
145
|
+
|
|
146
|
+
1. ✅ **Multiple data sources with search**: Each gets its own count route
|
|
147
|
+
2. ✅ **Same data source, different perPage**: Count route created once, shared
|
|
148
|
+
3. ✅ **Pages without search**: Count route not created (unnecessary)
|
|
149
|
+
4. ✅ **Components**: Count route still created (backward compatible)
|
|
150
|
+
5. ✅ **Search-only (no pagination)**: No count route created (correct)
|
|
151
|
+
|
|
152
|
+
## Files Modified
|
|
153
|
+
|
|
154
|
+
- `packages/teleport-plugin-next-data-source/src/pagination-plugin.ts`:
|
|
155
|
+
- `createAPIRoutesForPaginatedDataSources()`: Updated condition to create count routes for pages with search
|
|
156
|
+
- Added `searchEnabledDataSources` Set
|
|
157
|
+
- Added `createdCountRoutes` Set for deduplication
|
|
158
|
+
- Changed `if (isComponent)` to `if (needsCountRoute)`
|
|
159
|
+
|
|
160
|
+
## Regression Prevention
|
|
161
|
+
|
|
162
|
+
This fix aligns with the comment on line 353 of the same file:
|
|
163
|
+
```typescript
|
|
164
|
+
// Add useEffect to refetch count when search changes (for both pages and components)
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
The useEffect was already being created for both pages and components, but the count API route was only being created for components. Now both are consistent.
|
|
168
|
+
|
|
169
|
+
## Related Issues
|
|
170
|
+
|
|
171
|
+
This issue was introduced when search functionality was added to pages. The original pagination implementation (without search) correctly didn't create count routes for pages because:
|
|
172
|
+
- Pages got initial count in `getStaticProps`
|
|
173
|
+
- Count never changed during user interaction (no search)
|
|
174
|
+
|
|
175
|
+
When search was added, the requirement changed:
|
|
176
|
+
- Count now needs to be refetched when search query changes
|
|
177
|
+
- But the count API route creation wasn't updated
|
|
178
|
+
|
|
179
|
+
## Future Considerations
|
|
180
|
+
|
|
181
|
+
If additional features are added that require dynamic count updates (e.g., filters, sorting), the same pattern should be followed:
|
|
182
|
+
1. Create the useEffect to refetch count
|
|
183
|
+
2. Ensure the count API route is created
|
|
184
|
+
3. Add the feature to the `searchEnabledDataSources` check (or create a new check)
|
|
185
|
+
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Search State Bug Fix Summary
|
|
2
|
+
|
|
3
|
+
## Problem
|
|
4
|
+
When multiple data providers with search functionality were bound to the same data source in a project, all search inputs were incorrectly writing to the same state variable, causing search functionality to interfere between different list/table components.
|
|
5
|
+
|
|
6
|
+
## Root Causes
|
|
7
|
+
|
|
8
|
+
### 1. Fallback Matching Logic
|
|
9
|
+
The `modifySearchInputs` function had a problematic fallback:
|
|
10
|
+
```typescript
|
|
11
|
+
} else if (className && className.includes('search-input')) {
|
|
12
|
+
// Fallback: match any input with 'search-input' in class
|
|
13
|
+
addSearchInputHandlers(node, info)
|
|
14
|
+
}
|
|
15
|
+
```
|
|
16
|
+
This caused EVERY search input to match EVERY pagination info, with the last match overwriting previous handlers.
|
|
17
|
+
|
|
18
|
+
### 2. No Duplicate Prevention
|
|
19
|
+
The function didn't track which inputs had already been modified, allowing multiple matches to overwrite handlers.
|
|
20
|
+
|
|
21
|
+
### 3. Limited Detection Scope
|
|
22
|
+
The detection logic only looked at immediate siblings of DataProviders, missing search inputs in nested structures (e.g., table layouts where the search input is at a different nesting level).
|
|
23
|
+
|
|
24
|
+
## Solutions Implemented
|
|
25
|
+
|
|
26
|
+
### 1. Removed Fallback Logic
|
|
27
|
+
Changed from `forEach` to `for` loop with `break` statement to ensure only ONE match per input:
|
|
28
|
+
```typescript
|
|
29
|
+
for (let index = 0; index < detectedPaginations.length; index++) {
|
|
30
|
+
const detected = detectedPaginations[index]
|
|
31
|
+
const info = paginationInfos[index]
|
|
32
|
+
|
|
33
|
+
if (className === detected.searchInputClass) {
|
|
34
|
+
addSearchInputHandlers(node, info)
|
|
35
|
+
modifiedInputs.add(node)
|
|
36
|
+
break // Stop after first match
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### 2. Added Duplicate Tracking
|
|
42
|
+
Introduced a `Set` to track modified inputs:
|
|
43
|
+
```typescript
|
|
44
|
+
const modifiedInputs = new Set<any>()
|
|
45
|
+
// ...
|
|
46
|
+
if (className && !modifiedInputs.has(node)) {
|
|
47
|
+
// Only process if not already modified
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### 3. Improved Detection for Nested Structures
|
|
52
|
+
Enhanced the detection logic to walk up the JSX tree to find search inputs and pagination controls that aren't direct siblings:
|
|
53
|
+
```typescript
|
|
54
|
+
const findSearchAndPaginationInScope = (scopeNode: any, skipNode: any = null): void => {
|
|
55
|
+
// Recursively search through children
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
let currentScope = parent
|
|
59
|
+
let depth = 0
|
|
60
|
+
const maxDepth = 5
|
|
61
|
+
|
|
62
|
+
while (currentScope && (!searchInputInfo || !paginationNodeInfo) && depth < maxDepth) {
|
|
63
|
+
findSearchAndPaginationInScope(currentScope, depth === 0 ? dataProvider : null)
|
|
64
|
+
currentScope = findParentNode(blockStatement, currentScope)
|
|
65
|
+
depth++
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### 4. Applied Same Fix to Pagination Buttons
|
|
70
|
+
Applied the same pattern to `modifyPaginationButtons` for consistency and to prevent similar issues with button handlers.
|
|
71
|
+
|
|
72
|
+
## Edge Cases Handled
|
|
73
|
+
|
|
74
|
+
1. ✅ **Multiple data sources on same page**: Each gets unique state variables (e.g., `search_pg_0_query`, `search_pg_1_query`)
|
|
75
|
+
2. ✅ **Nested structures (tables)**: Detection walks up the tree to find search inputs
|
|
76
|
+
3. ✅ **Same data source, different components**: Each instance maintains independent state
|
|
77
|
+
4. ✅ **Mixed pagination + search**: Proper state management with combined `paginationState` object
|
|
78
|
+
5. ✅ **Search-only mappers**: Separate handling preserves functionality
|
|
79
|
+
|
|
80
|
+
## Testing
|
|
81
|
+
|
|
82
|
+
Verified with UIDL containing:
|
|
83
|
+
- Table with search and pagination
|
|
84
|
+
- Array mapper with search and pagination
|
|
85
|
+
- Both bound to the same CockroachDB data source
|
|
86
|
+
|
|
87
|
+
Result: Each search input now has its own state variable and handlers, functioning independently without interference.
|
|
88
|
+
|
|
89
|
+
## Files Modified
|
|
90
|
+
|
|
91
|
+
1. `packages/teleport-plugin-next-data-source/src/pagination-plugin.ts`
|
|
92
|
+
- `modifySearchInputs()`: Removed fallback, added tracking, break on match
|
|
93
|
+
- `modifyPaginationButtons()`: Applied same pattern for consistency
|
|
94
|
+
- `detectPaginationsAndSearchFromJSX()`: Enhanced detection for nested structures
|
|
95
|
+
- `findParentNode()`: New helper to walk up the tree
|
|
96
|
+
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pagination-plugin.d.ts","sourceRoot":"","sources":["../../src/pagination-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,sBAAsB,EAGvB,MAAM,4BAA4B,CAAA;AAgBnC,eAAO,MAAM,qCAAqC,EAAE,sBAAsB,CAAC,EAAE,CA+tB5E,CAAA;;
|
|
1
|
+
{"version":3,"file":"pagination-plugin.d.ts","sourceRoot":"","sources":["../../src/pagination-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,sBAAsB,EAGvB,MAAM,4BAA4B,CAAA;AAgBnC,eAAO,MAAM,qCAAqC,EAAE,sBAAsB,CAAC,EAAE,CA+tB5E,CAAA;;AAuoDD,wBAAsD"}
|
|
@@ -457,6 +457,64 @@ var createNextArrayMapperPaginationPlugin = function () {
|
|
|
457
457
|
return paginationPlugin;
|
|
458
458
|
};
|
|
459
459
|
exports.createNextArrayMapperPaginationPlugin = createNextArrayMapperPaginationPlugin;
|
|
460
|
+
function findParentNode(root, target, currentParent) {
|
|
461
|
+
if (currentParent === void 0) { currentParent = null; }
|
|
462
|
+
if (!root || !target) {
|
|
463
|
+
return null;
|
|
464
|
+
}
|
|
465
|
+
if (root === target) {
|
|
466
|
+
return currentParent;
|
|
467
|
+
}
|
|
468
|
+
if (root.type === 'JSXElement' || root.type === 'JSXFragment') {
|
|
469
|
+
if (root.children && Array.isArray(root.children)) {
|
|
470
|
+
for (var _i = 0, _a = root.children; _i < _a.length; _i++) {
|
|
471
|
+
var child = _a[_i];
|
|
472
|
+
var found = findParentNode(child, target, root);
|
|
473
|
+
if (found !== null) {
|
|
474
|
+
return found;
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
else if (root.type === 'JSXExpressionContainer') {
|
|
480
|
+
if (root.expression) {
|
|
481
|
+
var found = findParentNode(root.expression, target, root);
|
|
482
|
+
if (found !== null) {
|
|
483
|
+
return found;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
else if (root.type === 'BlockStatement') {
|
|
488
|
+
if (root.body && Array.isArray(root.body)) {
|
|
489
|
+
for (var _b = 0, _c = root.body; _b < _c.length; _b++) {
|
|
490
|
+
var stmt = _c[_b];
|
|
491
|
+
var found = findParentNode(stmt, target, root);
|
|
492
|
+
if (found !== null) {
|
|
493
|
+
return found;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
else if (root.type === 'ReturnStatement') {
|
|
499
|
+
if (root.argument) {
|
|
500
|
+
var found = findParentNode(root.argument, target, root);
|
|
501
|
+
if (found !== null) {
|
|
502
|
+
return found;
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
else if (root.type === 'ConditionalExpression') {
|
|
507
|
+
var foundConsequent = findParentNode(root.consequent, target, root);
|
|
508
|
+
if (foundConsequent !== null) {
|
|
509
|
+
return foundConsequent;
|
|
510
|
+
}
|
|
511
|
+
var foundAlternate = findParentNode(root.alternate, target, root);
|
|
512
|
+
if (foundAlternate !== null) {
|
|
513
|
+
return foundAlternate;
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
return null;
|
|
517
|
+
}
|
|
460
518
|
function detectPaginationsAndSearchFromJSX(blockStatement, uidlNode) {
|
|
461
519
|
var dataProviderMap = new Map();
|
|
462
520
|
var arrayMapperInfoMap = new Map();
|
|
@@ -624,32 +682,35 @@ function detectPaginationsAndSearchFromJSX(blockStatement, uidlNode) {
|
|
|
624
682
|
var dataProviderIdentifier = nameAttr.value.expression.value;
|
|
625
683
|
var paginationNodeInfo = null;
|
|
626
684
|
var searchInputInfo = null;
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
685
|
+
var findSearchAndPaginationInScope = function (scopeNode, skipNode) {
|
|
686
|
+
if (skipNode === void 0) { skipNode = null; }
|
|
687
|
+
if (!scopeNode || !scopeNode.children || !Array.isArray(scopeNode.children)) {
|
|
688
|
+
return;
|
|
689
|
+
}
|
|
690
|
+
scopeNode.children.forEach(function (child) {
|
|
630
691
|
var _a, _b, _c;
|
|
631
|
-
if (
|
|
692
|
+
if (child === skipNode) {
|
|
632
693
|
return;
|
|
633
694
|
}
|
|
634
|
-
if (
|
|
635
|
-
var
|
|
636
|
-
var
|
|
695
|
+
if (child.type === 'JSXElement') {
|
|
696
|
+
var childClassName = getClassName(((_a = child.openingElement) === null || _a === void 0 ? void 0 : _a.attributes) || []);
|
|
697
|
+
var childElementName = (_c = (_b = child.openingElement) === null || _b === void 0 ? void 0 : _b.name) === null || _c === void 0 ? void 0 : _c.name;
|
|
637
698
|
// Found pagination node
|
|
638
|
-
if (
|
|
639
|
-
var prevClass = findChildWithClass(
|
|
640
|
-
var nextClass = findChildWithClass(
|
|
699
|
+
if (childClassName && childClassName.includes('cms-pagination-node')) {
|
|
700
|
+
var prevClass = findChildWithClass(child, 'previous');
|
|
701
|
+
var nextClass = findChildWithClass(child, 'next');
|
|
641
702
|
if (prevClass || nextClass) {
|
|
642
703
|
paginationNodeInfo = {
|
|
643
|
-
class:
|
|
704
|
+
class: childClassName,
|
|
644
705
|
prevClass: prevClass,
|
|
645
706
|
nextClass: nextClass,
|
|
646
707
|
};
|
|
647
708
|
}
|
|
648
709
|
}
|
|
649
710
|
// Found search container - search for input inside it
|
|
650
|
-
if (
|
|
651
|
-
if (
|
|
652
|
-
|
|
711
|
+
if (childClassName && childClassName.includes('data-source-search-node')) {
|
|
712
|
+
if (child.children && Array.isArray(child.children)) {
|
|
713
|
+
child.children.forEach(function (searchChild) {
|
|
653
714
|
var _a, _b, _c;
|
|
654
715
|
if (searchChild.type === 'JSXElement') {
|
|
655
716
|
var searchChildElementName = (_b = (_a = searchChild.openingElement) === null || _a === void 0 ? void 0 : _a.name) === null || _b === void 0 ? void 0 : _b.name;
|
|
@@ -666,17 +727,28 @@ function detectPaginationsAndSearchFromJSX(blockStatement, uidlNode) {
|
|
|
666
727
|
});
|
|
667
728
|
}
|
|
668
729
|
}
|
|
669
|
-
// Also check if search input is a direct
|
|
670
|
-
if (
|
|
671
|
-
|
|
672
|
-
|
|
730
|
+
// Also check if search input is a direct child
|
|
731
|
+
if (childClassName &&
|
|
732
|
+
childClassName.includes('search-input') &&
|
|
733
|
+
childElementName === 'input') {
|
|
673
734
|
searchInputInfo = {
|
|
674
|
-
class:
|
|
675
|
-
jsx:
|
|
735
|
+
class: childClassName,
|
|
736
|
+
jsx: child,
|
|
676
737
|
};
|
|
677
738
|
}
|
|
739
|
+
if (!searchInputInfo || !paginationNodeInfo) {
|
|
740
|
+
findSearchAndPaginationInScope(child, skipNode);
|
|
741
|
+
}
|
|
678
742
|
}
|
|
679
743
|
});
|
|
744
|
+
};
|
|
745
|
+
var currentScope = parent;
|
|
746
|
+
var depth = 0;
|
|
747
|
+
var maxDepth = 5;
|
|
748
|
+
while (currentScope && (!searchInputInfo || !paginationNodeInfo) && depth < maxDepth) {
|
|
749
|
+
findSearchAndPaginationInScope(currentScope, depth === 0 ? dataProvider : null);
|
|
750
|
+
currentScope = findParentNode(blockStatement, currentScope);
|
|
751
|
+
depth++;
|
|
680
752
|
}
|
|
681
753
|
// Record the DataProvider with its pagination/search info
|
|
682
754
|
var uniqueKey = "".concat(dataProviderIdentifier, "__").concat(arrayMapperRenderProp);
|
|
@@ -1063,6 +1135,7 @@ function findChildWithClass(node, classSubstring) {
|
|
|
1063
1135
|
return null;
|
|
1064
1136
|
}
|
|
1065
1137
|
function modifyPaginationButtons(blockStatement, detectedPaginations, paginationInfos) {
|
|
1138
|
+
var modifiedButtons = new Set();
|
|
1066
1139
|
var modifyNode = function (node) {
|
|
1067
1140
|
if (!node) {
|
|
1068
1141
|
return;
|
|
@@ -1070,20 +1143,25 @@ function modifyPaginationButtons(blockStatement, detectedPaginations, pagination
|
|
|
1070
1143
|
if (node.type === 'JSXElement') {
|
|
1071
1144
|
var openingElement = node.openingElement;
|
|
1072
1145
|
if (openingElement && openingElement.name && openingElement.name.type === 'JSXIdentifier') {
|
|
1073
|
-
var
|
|
1074
|
-
if (
|
|
1075
|
-
|
|
1146
|
+
var className = getClassName(openingElement.attributes);
|
|
1147
|
+
if (className && !modifiedButtons.has(node)) {
|
|
1148
|
+
for (var index = 0; index < detectedPaginations.length; index++) {
|
|
1149
|
+
var detected = detectedPaginations[index];
|
|
1076
1150
|
var info = paginationInfos[index];
|
|
1077
1151
|
if (!info) {
|
|
1078
|
-
|
|
1152
|
+
continue;
|
|
1079
1153
|
}
|
|
1080
|
-
if (
|
|
1154
|
+
if (className === detected.prevButtonClass) {
|
|
1081
1155
|
convertToButton(node, info, 'prev');
|
|
1156
|
+
modifiedButtons.add(node);
|
|
1157
|
+
break;
|
|
1082
1158
|
}
|
|
1083
|
-
else if (
|
|
1159
|
+
else if (className === detected.nextButtonClass) {
|
|
1084
1160
|
convertToButton(node, info, 'next');
|
|
1161
|
+
modifiedButtons.add(node);
|
|
1162
|
+
break;
|
|
1085
1163
|
}
|
|
1086
|
-
}
|
|
1164
|
+
}
|
|
1087
1165
|
}
|
|
1088
1166
|
}
|
|
1089
1167
|
}
|
|
@@ -1101,6 +1179,7 @@ function modifyPaginationButtons(blockStatement, detectedPaginations, pagination
|
|
|
1101
1179
|
modifyNode(blockStatement);
|
|
1102
1180
|
}
|
|
1103
1181
|
function modifySearchInputs(blockStatement, detectedPaginations, paginationInfos) {
|
|
1182
|
+
var modifiedInputs = new Set();
|
|
1104
1183
|
var modifyNode = function (node) {
|
|
1105
1184
|
if (!node) {
|
|
1106
1185
|
return;
|
|
@@ -1108,21 +1187,20 @@ function modifySearchInputs(blockStatement, detectedPaginations, paginationInfos
|
|
|
1108
1187
|
if (node.type === 'JSXElement') {
|
|
1109
1188
|
var openingElement = node.openingElement;
|
|
1110
1189
|
if (openingElement && openingElement.name && openingElement.name.type === 'JSXIdentifier') {
|
|
1111
|
-
var
|
|
1112
|
-
if (
|
|
1113
|
-
|
|
1190
|
+
var className = getClassName(openingElement.attributes);
|
|
1191
|
+
if (className && !modifiedInputs.has(node)) {
|
|
1192
|
+
for (var index = 0; index < detectedPaginations.length; index++) {
|
|
1193
|
+
var detected = detectedPaginations[index];
|
|
1114
1194
|
var info = paginationInfos[index];
|
|
1115
1195
|
if (!info || !info.searchEnabled) {
|
|
1116
|
-
|
|
1117
|
-
}
|
|
1118
|
-
if (className_2 === detected.searchInputClass) {
|
|
1119
|
-
addSearchInputHandlers(node, info);
|
|
1196
|
+
continue;
|
|
1120
1197
|
}
|
|
1121
|
-
|
|
1122
|
-
// Fallback: match any input with 'search-input' in class
|
|
1198
|
+
if (className === detected.searchInputClass) {
|
|
1123
1199
|
addSearchInputHandlers(node, info);
|
|
1200
|
+
modifiedInputs.add(node);
|
|
1201
|
+
break;
|
|
1124
1202
|
}
|
|
1125
|
-
}
|
|
1203
|
+
}
|
|
1126
1204
|
}
|
|
1127
1205
|
}
|
|
1128
1206
|
}
|
|
@@ -1426,6 +1504,8 @@ function modifyGetStaticPropsForPagination(chunks, paginationInfos) {
|
|
|
1426
1504
|
}
|
|
1427
1505
|
function createAPIRoutesForPaginatedDataSources(uidlNode, dataSources, componentChunk, extractedResources, paginationInfos, isComponent) {
|
|
1428
1506
|
var paginatedDataSourceIds = new Set(paginationInfos.map(function (info) { return info.dataSourceIdentifier; }));
|
|
1507
|
+
var searchEnabledDataSources = new Set(paginationInfos.filter(function (info) { return info.searchEnabled; }).map(function (info) { return info.dataSourceIdentifier; }));
|
|
1508
|
+
var createdCountRoutes = new Set();
|
|
1429
1509
|
var traverseForDataSources = function (node) {
|
|
1430
1510
|
var _a;
|
|
1431
1511
|
if (!node) {
|
|
@@ -1435,8 +1515,9 @@ function createAPIRoutesForPaginatedDataSources(uidlNode, dataSources, component
|
|
|
1435
1515
|
var renderProp = node.content.renderPropIdentifier;
|
|
1436
1516
|
if (renderProp && paginatedDataSourceIds.has(renderProp)) {
|
|
1437
1517
|
(0, utils_1.extractDataSourceIntoNextAPIFolder)(node, dataSources, componentChunk, extractedResources);
|
|
1438
|
-
|
|
1439
|
-
|
|
1518
|
+
var hasSearch = searchEnabledDataSources.has(renderProp);
|
|
1519
|
+
var needsCountRoute = isComponent || hasSearch;
|
|
1520
|
+
if (needsCountRoute) {
|
|
1440
1521
|
var resourceDef = node.content.resourceDefinition;
|
|
1441
1522
|
if (resourceDef) {
|
|
1442
1523
|
var dataSourceId = resourceDef.dataSourceId;
|
|
@@ -1444,13 +1525,15 @@ function createAPIRoutesForPaginatedDataSources(uidlNode, dataSources, component
|
|
|
1444
1525
|
var dataSourceType = resourceDef.dataSourceType;
|
|
1445
1526
|
var fileName = "".concat(dataSourceType, "-").concat(tableName, "-").concat(dataSourceId.substring(0, 8));
|
|
1446
1527
|
var countFileName = "".concat(fileName, "-count");
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1528
|
+
if (!createdCountRoutes.has(countFileName)) {
|
|
1529
|
+
extractedResources["api/".concat(countFileName)] = {
|
|
1530
|
+
fileName: countFileName,
|
|
1531
|
+
fileType: teleport_types_1.FileType.JS,
|
|
1532
|
+
path: ['pages', 'api'],
|
|
1533
|
+
content: "import dataSource from '../../utils/data-sources/".concat(fileName, "'\n\nexport default dataSource.getCount\n"),
|
|
1534
|
+
};
|
|
1535
|
+
createdCountRoutes.add(countFileName);
|
|
1536
|
+
}
|
|
1454
1537
|
}
|
|
1455
1538
|
}
|
|
1456
1539
|
}
|