@hubspot/ui-extensions 0.9.6 → 0.9.7
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/dist/__tests__/experimental/crm/fetchAssociations.spec.js +1 -23
- package/dist/__tests__/experimental/hooks/useAssociations.spec.js +2 -2
- package/dist/experimental/crm/fetchAssociations.d.ts +0 -8
- package/dist/experimental/crm/fetchAssociations.js +0 -12
- package/dist/experimental/hooks/useAssociations.js +36 -6
- package/dist/types.d.ts +5 -5
- package/package.json +2 -2
|
@@ -8,7 +8,7 @@ Object.defineProperty(global, 'self', {
|
|
|
8
8
|
value: mockSelf,
|
|
9
9
|
writable: true,
|
|
10
10
|
});
|
|
11
|
-
import { fetchAssociations,
|
|
11
|
+
import { fetchAssociations, calculatePaginationFlags, } from '../../../experimental/crm/fetchAssociations';
|
|
12
12
|
describe('fetchAssociations', () => {
|
|
13
13
|
// Helper functions
|
|
14
14
|
const createMockResponse = (data, overrides = {}) => ({
|
|
@@ -394,28 +394,6 @@ describe('fetchAssociations', () => {
|
|
|
394
394
|
});
|
|
395
395
|
});
|
|
396
396
|
describe('pagination utilities', () => {
|
|
397
|
-
describe('pageToOffset', () => {
|
|
398
|
-
it('should convert page numbers to offsets', () => {
|
|
399
|
-
expect(pageToOffset(1, 10)).toBe(0);
|
|
400
|
-
expect(pageToOffset(3, 10)).toBe(20);
|
|
401
|
-
expect(pageToOffset(2, 25)).toBe(25);
|
|
402
|
-
});
|
|
403
|
-
it('should always return 0 for page 1', () => {
|
|
404
|
-
expect(pageToOffset(1, 10)).toBe(0);
|
|
405
|
-
expect(pageToOffset(1, 50)).toBe(0);
|
|
406
|
-
});
|
|
407
|
-
});
|
|
408
|
-
describe('offsetToPage', () => {
|
|
409
|
-
it('should convert offsets to page numbers', () => {
|
|
410
|
-
expect(offsetToPage(0, 10)).toBe(1);
|
|
411
|
-
expect(offsetToPage(20, 10)).toBe(3);
|
|
412
|
-
expect(offsetToPage(15, 10)).toBe(2); // partial page
|
|
413
|
-
});
|
|
414
|
-
it('should always return 1 for offset 0', () => {
|
|
415
|
-
expect(offsetToPage(0, 10)).toBe(1);
|
|
416
|
-
expect(offsetToPage(0, 25)).toBe(1);
|
|
417
|
-
});
|
|
418
|
-
});
|
|
419
397
|
describe('calculatePaginationFlags', () => {
|
|
420
398
|
it('should calculate pagination flags correctly', () => {
|
|
421
399
|
// Page 1 scenarios
|
|
@@ -118,7 +118,7 @@ describe('useAssociations with Pagination', () => {
|
|
|
118
118
|
toObjectType: '0-1',
|
|
119
119
|
properties: ['firstname', 'lastname'],
|
|
120
120
|
pageLength: 10,
|
|
121
|
-
offset:
|
|
121
|
+
offset: undefined, // First page starts with undefined offset
|
|
122
122
|
}), expect.any(Object));
|
|
123
123
|
});
|
|
124
124
|
it('should handle empty results correctly', async () => {
|
|
@@ -182,7 +182,7 @@ describe('useAssociations with Pagination', () => {
|
|
|
182
182
|
});
|
|
183
183
|
// Verify API was called with correct offset for page 2
|
|
184
184
|
expect(mockFetchAssociations).toHaveBeenLastCalledWith(expect.objectContaining({
|
|
185
|
-
offset: 10, //
|
|
185
|
+
offset: 10, // Uses nextOffset (10) from first page response
|
|
186
186
|
}), expect.any(Object));
|
|
187
187
|
});
|
|
188
188
|
it('should navigate to previous page correctly', async () => {
|
|
@@ -1,13 +1,5 @@
|
|
|
1
1
|
import { FetchCrmPropertiesOptions } from './fetchCrmProperties';
|
|
2
2
|
export declare const DEFAULT_PAGE_SIZE = 10;
|
|
3
|
-
/**
|
|
4
|
-
* Convert page number and page size to offset for API calls
|
|
5
|
-
*/
|
|
6
|
-
export declare function pageToOffset(page: number, pageSize: number): number;
|
|
7
|
-
/**
|
|
8
|
-
* Convert offset and page size to page number
|
|
9
|
-
*/
|
|
10
|
-
export declare function offsetToPage(offset: number, pageSize: number): number;
|
|
11
3
|
/**
|
|
12
4
|
* Calculate pagination flags based on current page and API hasMore flag
|
|
13
5
|
*/
|
|
@@ -1,16 +1,4 @@
|
|
|
1
1
|
export const DEFAULT_PAGE_SIZE = 10;
|
|
2
|
-
/**
|
|
3
|
-
* Convert page number and page size to offset for API calls
|
|
4
|
-
*/
|
|
5
|
-
export function pageToOffset(page, pageSize) {
|
|
6
|
-
return (page - 1) * pageSize;
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* Convert offset and page size to page number
|
|
10
|
-
*/
|
|
11
|
-
export function offsetToPage(offset, pageSize) {
|
|
12
|
-
return Math.floor(offset / pageSize) + 1;
|
|
13
|
-
}
|
|
14
2
|
/**
|
|
15
3
|
* Calculate pagination flags based on current page and API hasMore flag
|
|
16
4
|
*/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useEffect, useReducer, useMemo, useRef, useCallback } from 'react';
|
|
2
2
|
import { logger } from '../../logger';
|
|
3
|
-
import { fetchAssociations, DEFAULT_PAGE_SIZE,
|
|
3
|
+
import { fetchAssociations, DEFAULT_PAGE_SIZE, calculatePaginationFlags, } from '../crm/fetchAssociations';
|
|
4
4
|
function createInitialState(pageSize) {
|
|
5
5
|
return {
|
|
6
6
|
results: [],
|
|
@@ -9,6 +9,9 @@ function createInitialState(pageSize) {
|
|
|
9
9
|
currentPage: 1,
|
|
10
10
|
pageSize,
|
|
11
11
|
hasMore: false,
|
|
12
|
+
currentOffset: undefined,
|
|
13
|
+
nextOffset: undefined,
|
|
14
|
+
offsetHistory: [],
|
|
12
15
|
};
|
|
13
16
|
}
|
|
14
17
|
function associationsReducer(state, action) {
|
|
@@ -25,6 +28,8 @@ function associationsReducer(state, action) {
|
|
|
25
28
|
isLoading: false,
|
|
26
29
|
results: action.payload.results,
|
|
27
30
|
hasMore: action.payload.hasMore,
|
|
31
|
+
currentOffset: action.payload.currentOffset,
|
|
32
|
+
nextOffset: action.payload.nextOffset,
|
|
28
33
|
error: null,
|
|
29
34
|
};
|
|
30
35
|
case 'FETCH_ERROR':
|
|
@@ -34,17 +39,31 @@ function associationsReducer(state, action) {
|
|
|
34
39
|
error: action.payload,
|
|
35
40
|
results: [],
|
|
36
41
|
hasMore: false,
|
|
42
|
+
currentOffset: undefined,
|
|
43
|
+
nextOffset: undefined,
|
|
37
44
|
};
|
|
38
45
|
case 'NEXT_PAGE':
|
|
39
46
|
return {
|
|
40
47
|
...state,
|
|
41
48
|
currentPage: state.currentPage + 1,
|
|
49
|
+
offsetHistory: state.currentOffset !== undefined
|
|
50
|
+
? [...state.offsetHistory, state.currentOffset]
|
|
51
|
+
: state.offsetHistory,
|
|
52
|
+
currentOffset: state.nextOffset,
|
|
53
|
+
nextOffset: undefined,
|
|
42
54
|
};
|
|
43
|
-
case 'PREVIOUS_PAGE':
|
|
55
|
+
case 'PREVIOUS_PAGE': {
|
|
56
|
+
const newPage = Math.max(1, state.currentPage - 1);
|
|
57
|
+
const newHistory = [...state.offsetHistory];
|
|
58
|
+
const previousOffset = newHistory.pop();
|
|
44
59
|
return {
|
|
45
60
|
...state,
|
|
46
|
-
currentPage:
|
|
61
|
+
currentPage: newPage,
|
|
62
|
+
offsetHistory: newHistory,
|
|
63
|
+
currentOffset: previousOffset,
|
|
64
|
+
nextOffset: undefined,
|
|
47
65
|
};
|
|
66
|
+
}
|
|
48
67
|
case 'RESET':
|
|
49
68
|
return {
|
|
50
69
|
...state,
|
|
@@ -52,6 +71,9 @@ function associationsReducer(state, action) {
|
|
|
52
71
|
results: [],
|
|
53
72
|
hasMore: false,
|
|
54
73
|
error: null,
|
|
74
|
+
currentOffset: undefined,
|
|
75
|
+
nextOffset: undefined,
|
|
76
|
+
offsetHistory: [],
|
|
55
77
|
};
|
|
56
78
|
default:
|
|
57
79
|
return state;
|
|
@@ -117,12 +139,12 @@ export function useAssociations(config, options = DEFAULT_OPTIONS) {
|
|
|
117
139
|
const fetchData = async () => {
|
|
118
140
|
try {
|
|
119
141
|
dispatch({ type: 'FETCH_START' });
|
|
120
|
-
// Build request using current
|
|
142
|
+
// Build request using current offset token
|
|
121
143
|
const request = {
|
|
122
144
|
toObjectType: stableConfig.toObjectType,
|
|
123
145
|
properties: stableConfig.properties,
|
|
124
146
|
pageLength: pageSize,
|
|
125
|
-
offset:
|
|
147
|
+
offset: state.currentOffset,
|
|
126
148
|
};
|
|
127
149
|
const result = await fetchAssociations(request, {
|
|
128
150
|
propertiesToFormat: stableOptions.propertiesToFormat,
|
|
@@ -134,6 +156,8 @@ export function useAssociations(config, options = DEFAULT_OPTIONS) {
|
|
|
134
156
|
payload: {
|
|
135
157
|
results: result.data.results,
|
|
136
158
|
hasMore: result.data.hasMore,
|
|
159
|
+
nextOffset: result.data.nextOffset,
|
|
160
|
+
currentOffset: state.currentOffset,
|
|
137
161
|
},
|
|
138
162
|
});
|
|
139
163
|
cleanup = result.cleanup;
|
|
@@ -156,7 +180,13 @@ export function useAssociations(config, options = DEFAULT_OPTIONS) {
|
|
|
156
180
|
cleanup();
|
|
157
181
|
}
|
|
158
182
|
};
|
|
159
|
-
}, [
|
|
183
|
+
}, [
|
|
184
|
+
stableConfig,
|
|
185
|
+
stableOptions,
|
|
186
|
+
state.currentPage,
|
|
187
|
+
state.currentOffset,
|
|
188
|
+
pageSize,
|
|
189
|
+
]);
|
|
160
190
|
// Calculate pagination flags
|
|
161
191
|
const paginationFlags = calculatePaginationFlags(state.currentPage, state.hasMore);
|
|
162
192
|
return {
|
package/dist/types.d.ts
CHANGED
|
@@ -1304,6 +1304,8 @@ export interface StackProps {
|
|
|
1304
1304
|
*/
|
|
1305
1305
|
width?: 'auto' | '100%';
|
|
1306
1306
|
}
|
|
1307
|
+
export type FlexJustify = 'center' | 'end' | 'start' | 'around' | 'between';
|
|
1308
|
+
export type FlexAlign = 'start' | 'center' | 'baseline' | 'end' | 'stretch';
|
|
1307
1309
|
/**
|
|
1308
1310
|
* The props type for {@link !components.Flex}.
|
|
1309
1311
|
*
|
|
@@ -1332,18 +1334,18 @@ export interface FlexProps {
|
|
|
1332
1334
|
*
|
|
1333
1335
|
* @defaultValue `"start"`
|
|
1334
1336
|
*/
|
|
1335
|
-
justify?:
|
|
1337
|
+
justify?: FlexJustify;
|
|
1336
1338
|
/**
|
|
1337
1339
|
* Distributes components along the cross-axis using the available free space.
|
|
1338
1340
|
*
|
|
1339
1341
|
* @defaultValue `"stretch"`
|
|
1340
1342
|
*/
|
|
1341
|
-
align?:
|
|
1343
|
+
align?: FlexAlign;
|
|
1342
1344
|
/**
|
|
1343
1345
|
* Overrides Flex's `alignItem` value for this element.
|
|
1344
1346
|
*
|
|
1345
1347
|
*/
|
|
1346
|
-
alignSelf?:
|
|
1348
|
+
alignSelf?: FlexAlign;
|
|
1347
1349
|
/**
|
|
1348
1350
|
* Whether components will wrap instead of trying to fit on one line.
|
|
1349
1351
|
*
|
|
@@ -1381,8 +1383,6 @@ export interface BoxProps {
|
|
|
1381
1383
|
*/
|
|
1382
1384
|
flex?: 'initial' | 'auto' | 'none' | number;
|
|
1383
1385
|
}
|
|
1384
|
-
export type FlexJustify = 'center' | 'end' | 'start' | 'around' | 'between';
|
|
1385
|
-
export type FlexAlign = 'start' | 'center' | 'baseline' | 'end' | 'stretch';
|
|
1386
1386
|
/**
|
|
1387
1387
|
* The props type for {@link !components.Inline}.
|
|
1388
1388
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hubspot/ui-extensions",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.7",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -66,5 +66,5 @@
|
|
|
66
66
|
"ts-jest": "^29.1.1",
|
|
67
67
|
"typescript": "5.0.4"
|
|
68
68
|
},
|
|
69
|
-
"gitHead": "
|
|
69
|
+
"gitHead": "b9a6650baca7fd7326e7de6ffeacc8d5c097e126"
|
|
70
70
|
}
|