@hubspot/ui-extensions 0.9.6 → 0.9.8

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.
@@ -8,7 +8,7 @@ Object.defineProperty(global, 'self', {
8
8
  value: mockSelf,
9
9
  writable: true,
10
10
  });
11
- import { fetchAssociations, pageToOffset, offsetToPage, calculatePaginationFlags, } from '../../../experimental/crm/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: 0,
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, // (page 2 - 1) * pageSize 10 = 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, pageToOffset, calculatePaginationFlags, } from '../crm/fetchAssociations';
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: Math.max(1, state.currentPage - 1),
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 page and pagination utilities
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: pageToOffset(state.currentPage, pageSize),
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
- }, [stableConfig, stableOptions, state.currentPage, pageSize]);
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?: 'center' | 'end' | 'start' | 'around' | 'between';
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?: 'start' | 'center' | 'baseline' | 'end' | 'stretch';
1343
+ align?: FlexAlign;
1342
1344
  /**
1343
1345
  * Overrides Flex's `alignItem` value for this element.
1344
1346
  *
1345
1347
  */
1346
- alignSelf?: 'start' | 'center' | 'baseline' | 'end' | 'stretch';
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
  *
@@ -2539,6 +2539,8 @@ interface Team {
2539
2539
  teammates: number[];
2540
2540
  }
2541
2541
  /** @ignore */
2542
+ export type Permission = 'integrations-management-write';
2543
+ /** @ignore */
2542
2544
  export interface UserContext {
2543
2545
  id: number;
2544
2546
  emails: string[];
@@ -2549,6 +2551,7 @@ export interface UserContext {
2549
2551
  roles: string[];
2550
2552
  teams: Team[];
2551
2553
  locale?: string;
2554
+ permissions: Permission[];
2552
2555
  }
2553
2556
  /** @ignore */
2554
2557
  export interface PortalContext {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hubspot/ui-extensions",
3
- "version": "0.9.6",
3
+ "version": "0.9.8",
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": "1b458008ea50e3fb395db1766239aea3abb6753e"
69
+ "gitHead": "68d176099343d6d202421ec241c131f1d07562a8"
70
70
  }