@axinom/mosaic-ui 0.53.0-rc.2 → 0.53.0-rc.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axinom/mosaic-ui",
3
- "version": "0.53.0-rc.2",
3
+ "version": "0.53.0-rc.3",
4
4
  "description": "UI components for building Axinom Mosaic applications",
5
5
  "author": "Axinom",
6
6
  "license": "PROPRIETARY",
@@ -32,7 +32,7 @@
32
32
  "build-storybook": "storybook build"
33
33
  },
34
34
  "dependencies": {
35
- "@axinom/mosaic-core": "^0.4.26-rc.2",
35
+ "@axinom/mosaic-core": "^0.4.26-rc.3",
36
36
  "@faker-js/faker": "^7.4.0",
37
37
  "@geoffcox/react-splitter": "^2.1.2",
38
38
  "@popperjs/core": "^2.11.8",
@@ -106,5 +106,5 @@
106
106
  "publishConfig": {
107
107
  "access": "public"
108
108
  },
109
- "gitHead": "d17a51ac5480846ee3f20e8f6a55f7cb346a0712"
109
+ "gitHead": "cf0e508e30ba905682e1952986d4acf5d17fb052"
110
110
  }
@@ -280,7 +280,8 @@ export const Explorer = React.forwardRef(function Explorer<T extends Data>(
280
280
  const {
281
281
  isQuickEditMode,
282
282
  quickEditAction,
283
- QuickEditComponent,
283
+ QuickEditContextProvider,
284
+ quickEditStation,
284
285
  changeSelectedItem,
285
286
  } = useQuickEdit({
286
287
  listRef,
@@ -352,24 +353,27 @@ export const Explorer = React.forwardRef(function Explorer<T extends Data>(
352
353
 
353
354
  const errAction = 'An error occurred when trying to execute the operation.';
354
355
 
355
- const inlineMenuActionsHandler = (data: T): ActionData[] =>
356
- (inlineMenuActions?.(data) ?? []).map((action) =>
357
- isContextAction(action)
358
- ? {
359
- ...action,
360
- onActionSelected: async () => {
361
- try {
362
- const result = await action.onActionSelected();
363
- if (result) {
364
- setStationMessage(errMsg(result));
356
+ const inlineMenuActionsHandler = useCallback(
357
+ (data: T): ActionData[] =>
358
+ (inlineMenuActions?.(data) ?? []).map((action) =>
359
+ isContextAction(action)
360
+ ? {
361
+ ...action,
362
+ onActionSelected: async () => {
363
+ try {
364
+ const result = await action.onActionSelected();
365
+ if (result) {
366
+ setStationMessage(errMsg(result));
367
+ }
368
+ } catch (error) {
369
+ setStationMessage(errMsg(error, errAction));
365
370
  }
366
- } catch (error) {
367
- setStationMessage(errMsg(error, errAction));
368
- }
369
- },
370
- }
371
- : action,
372
- );
371
+ },
372
+ }
373
+ : action,
374
+ ),
375
+ [inlineMenuActions, setStationMessage],
376
+ );
373
377
 
374
378
  const { actions: pageHeaderActions } = useActions<T>({
375
379
  actions,
@@ -453,7 +457,9 @@ export const Explorer = React.forwardRef(function Explorer<T extends Data>(
453
457
  />
454
458
  </div>
455
459
  </div>
456
- {QuickEditComponent}
460
+ {isQuickEditMode && (
461
+ <QuickEditContextProvider>{quickEditStation}</QuickEditContextProvider>
462
+ )}
457
463
  </ConditionalSplit>
458
464
  );
459
465
  });
@@ -143,9 +143,7 @@ describe('useQuickEdit', () => {
143
143
 
144
144
  wrapper.update();
145
145
 
146
- expect(ref.current.QuickEditComponent.props.children).toBe(
147
- mockRegistrations[0].component,
148
- );
146
+ expect(ref.current.quickEditStation).toBe(mockRegistrations[0].component);
149
147
  });
150
148
 
151
149
  it('should update the registration when a registration action is clicked', async () => {
@@ -165,9 +163,7 @@ describe('useQuickEdit', () => {
165
163
  ref.current.quickEditAction.actions[1].onClick?.();
166
164
  });
167
165
 
168
- expect(ref.current.QuickEditComponent.props.children).toBe(
169
- mockRegistrations[1].component,
170
- );
166
+ expect(ref.current.quickEditStation).toBe(mockRegistrations[1].component);
171
167
  });
172
168
 
173
169
  it('should disable the quickEditAction when there is no data', () => {
@@ -220,18 +216,8 @@ describe('useQuickEdit', () => {
220
216
  });
221
217
 
222
218
  describe('QuickEditContextProvider', () => {
223
- const { ContextConsumer, ref: contextRef } = getContextConsumer();
224
-
225
- const props: useQuickEditProps<any> = {
226
- ...defaultProps,
227
- registrations: mockRegistrations.map((registration) => ({
228
- ...registration,
229
- component: <ContextConsumer contextRef={contextRef} />,
230
- })),
231
- };
232
-
233
219
  it('should select the default item when quick edit is opened', async () => {
234
- const { TestWrapper, ref } = getTestWrapper(props);
220
+ const { TestWrapper, ref } = getTestWrapper(defaultProps);
235
221
 
236
222
  const wrapper = mount(<TestWrapper quickEditValuesRef={ref} />);
237
223
 
@@ -242,7 +228,12 @@ describe('useQuickEdit', () => {
242
228
 
243
229
  wrapper.update();
244
230
 
245
- mount(<>{ref.current.QuickEditComponent}</>);
231
+ const { ContextConsumer, ref: contextRef } = getContextConsumer();
232
+ mount(
233
+ <ref.current.QuickEditContextProvider>
234
+ <ContextConsumer contextRef={contextRef} />
235
+ </ref.current.QuickEditContextProvider>,
236
+ );
246
237
 
247
238
  expect(contextRef.current.isQuickEditMode).toBe(true);
248
239
  expect(contextRef.current.selectedItem).toEqual({ id: 0 });
@@ -250,7 +241,7 @@ describe('useQuickEdit', () => {
250
241
  });
251
242
 
252
243
  it('should provide the correct context values', async () => {
253
- const { TestWrapper, ref } = getTestWrapper(props);
244
+ const { TestWrapper, ref } = getTestWrapper(defaultProps);
254
245
 
255
246
  const wrapper = mount(<TestWrapper quickEditValuesRef={ref} />);
256
247
 
@@ -262,7 +253,12 @@ describe('useQuickEdit', () => {
262
253
 
263
254
  wrapper.update();
264
255
 
265
- mount(<>{ref.current.QuickEditComponent}</>);
256
+ const { ContextConsumer, ref: contextRef } = getContextConsumer();
257
+ mount(
258
+ <ref.current.QuickEditContextProvider>
259
+ <ContextConsumer contextRef={contextRef} />
260
+ </ref.current.QuickEditContextProvider>,
261
+ );
266
262
 
267
263
  expect(contextRef.current.isQuickEditMode).toBe(true);
268
264
  expect(contextRef.current.selectedItem).toEqual({ id: 1 });
@@ -270,7 +266,7 @@ describe('useQuickEdit', () => {
270
266
  });
271
267
 
272
268
  it('should call the save callback when changeSelectedItem is called', async () => {
273
- const { TestWrapper, ref } = getTestWrapper(props);
269
+ const { TestWrapper, ref } = getTestWrapper(defaultProps);
274
270
 
275
271
  const wrapper = mount(<TestWrapper quickEditValuesRef={ref} />);
276
272
 
@@ -282,7 +278,12 @@ describe('useQuickEdit', () => {
282
278
 
283
279
  wrapper.update();
284
280
 
285
- mount(<>{ref.current.QuickEditComponent}</>);
281
+ const { ContextConsumer, ref: contextRef } = getContextConsumer();
282
+ mount(
283
+ <ref.current.QuickEditContextProvider>
284
+ <ContextConsumer contextRef={contextRef} />
285
+ </ref.current.QuickEditContextProvider>,
286
+ );
286
287
 
287
288
  const saveCallbackSpy = jest.fn();
288
289
 
@@ -295,18 +296,24 @@ describe('useQuickEdit', () => {
295
296
  });
296
297
 
297
298
  it('should call the save callback when refresh is called', async () => {
298
- const { TestWrapper, ref } = getTestWrapper(props);
299
+ const { TestWrapper, ref } = getTestWrapper(defaultProps);
299
300
 
300
301
  const wrapper = mount(<TestWrapper quickEditValuesRef={ref} />);
301
302
 
302
303
  await act(async () => {
303
304
  ref.current.quickEditAction?.kind === 'group' &&
304
305
  (await ref.current.quickEditAction?.onActionsGroupToggled?.(true));
306
+ ref.current.changeSelectedItem({ id: 1 });
305
307
  });
306
308
 
307
309
  wrapper.update();
308
310
 
309
- mount(<>{ref.current.QuickEditComponent}</>);
311
+ const { ContextConsumer, ref: contextRef } = getContextConsumer();
312
+ mount(
313
+ <ref.current.QuickEditContextProvider>
314
+ <ContextConsumer contextRef={contextRef} />
315
+ </ref.current.QuickEditContextProvider>,
316
+ );
310
317
 
311
318
  const saveCallbackSpy = jest.fn();
312
319
 
@@ -319,7 +326,10 @@ describe('useQuickEdit', () => {
319
326
  });
320
327
 
321
328
  it('should generate the correct details link using registration if provided', async () => {
322
- const { TestWrapper, ref } = getTestWrapper(props);
329
+ const { TestWrapper, ref } = getTestWrapper({
330
+ ...defaultProps,
331
+ registrations: [mockRegistrations[1]],
332
+ });
323
333
 
324
334
  const wrapper = mount(<TestWrapper quickEditValuesRef={ref} />);
325
335
 
@@ -327,22 +337,27 @@ describe('useQuickEdit', () => {
327
337
  ref.current.quickEditAction?.kind === 'group' &&
328
338
  (await ref.current.quickEditAction?.onActionsGroupToggled?.(true));
329
339
 
330
- ref.current.quickEditAction?.kind === 'group' &&
331
- ref.current.quickEditAction.actions[1].onClick?.();
340
+ ref.current.changeSelectedItem({ id: 1 });
332
341
  });
333
342
 
334
- mount(<>{ref.current.QuickEditComponent}</>);
335
-
336
343
  wrapper.update();
337
344
 
338
- expect(contextRef.current.detailsLink).toBe('/test?{"id":0}');
345
+ const { ContextConsumer, ref: contextRef } = getContextConsumer();
346
+ mount(
347
+ <ref.current.QuickEditContextProvider>
348
+ <ContextConsumer contextRef={contextRef} />
349
+ </ref.current.QuickEditContextProvider>,
350
+ );
351
+
352
+ expect(contextRef.current.detailsLink).toBe('/test?{"id":1}');
339
353
  });
340
354
 
341
355
  it('should generate the correct details link using generateItemLink prop if not provided in registration', async () => {
342
356
  const generateDetailsLinkSpy = jest.fn();
343
357
 
344
358
  const { TestWrapper, ref } = getTestWrapper({
345
- ...props,
359
+ ...defaultProps,
360
+ registrations: [mockRegistrations[2]],
346
361
  generateItemLink: generateDetailsLinkSpy,
347
362
  });
348
363
 
@@ -352,23 +367,25 @@ describe('useQuickEdit', () => {
352
367
  ref.current.quickEditAction?.kind === 'group' &&
353
368
  (await ref.current.quickEditAction?.onActionsGroupToggled?.(true));
354
369
 
355
- ref.current.quickEditAction?.kind === 'group' &&
356
- ref.current.quickEditAction.actions[2].onClick?.();
370
+ ref.current.changeSelectedItem({ id: 1 });
357
371
  });
358
372
 
359
- await wrapper.update();
373
+ wrapper.update();
374
+ const { ContextConsumer, ref: contextRef } = getContextConsumer();
360
375
 
361
- mount(<>{ref.current.QuickEditComponent}</>);
376
+ mount(
377
+ <ref.current.QuickEditContextProvider>
378
+ <ContextConsumer contextRef={contextRef} />
379
+ </ref.current.QuickEditContextProvider>,
380
+ );
362
381
 
363
- expect(generateDetailsLinkSpy).toHaveBeenCalledWith({ id: 0 });
382
+ expect(generateDetailsLinkSpy).toHaveBeenCalledWith({ id: 1 });
364
383
  });
365
384
 
366
385
  it('should not generate a details link if generateDetailsLink in registration is false', async () => {
367
- const generateDetailsLinkSpy = jest.fn();
368
-
369
386
  const { TestWrapper, ref } = getTestWrapper({
370
- ...props,
371
- generateItemLink: generateDetailsLinkSpy,
387
+ ...defaultProps,
388
+ registrations: [mockRegistrations[3]],
372
389
  });
373
390
 
374
391
  const wrapper = mount(<TestWrapper quickEditValuesRef={ref} />);
@@ -377,15 +394,18 @@ describe('useQuickEdit', () => {
377
394
  ref.current.quickEditAction?.kind === 'group' &&
378
395
  (await ref.current.quickEditAction?.onActionsGroupToggled?.(true));
379
396
 
380
- ref.current.quickEditAction?.kind === 'group' &&
381
- ref.current.quickEditAction.actions[3].onClick?.();
397
+ ref.current.changeSelectedItem({ id: 1 });
382
398
  });
383
399
 
384
400
  wrapper.update();
385
401
 
386
- mount(<>{ref.current.QuickEditComponent}</>);
402
+ const { ContextConsumer, ref: contextRef } = getContextConsumer();
403
+ mount(
404
+ <ref.current.QuickEditContextProvider>
405
+ <ContextConsumer contextRef={contextRef} />
406
+ </ref.current.QuickEditContextProvider>,
407
+ );
387
408
 
388
- expect(generateDetailsLinkSpy).not.toHaveBeenCalled();
389
409
  expect(contextRef.current.detailsLink).toBeUndefined();
390
410
  });
391
411
  });
@@ -22,7 +22,8 @@ export interface useQuickEditProps<T extends Data> {
22
22
  export interface useQuickEditReturnType<T extends Data> {
23
23
  readonly isQuickEditMode: boolean;
24
24
  readonly quickEditAction?: PageHeaderActionItemProps;
25
- readonly QuickEditComponent: JSX.Element;
25
+ readonly QuickEditContextProvider: React.FC;
26
+ readonly quickEditStation: JSX.Element | undefined;
26
27
  readonly changeSelectedItem: (
27
28
  item: T,
28
29
  detailsLink?: LocationDescriptor<unknown>,
@@ -76,8 +77,8 @@ export const useQuickEdit = <T extends Data>({
76
77
  [],
77
78
  );
78
79
 
79
- const QuickEditComponent: JSX.Element = useMemo(() => {
80
- if (isQuickEditMode) {
80
+ const QuickEditContextProvider: React.FC = useCallback(
81
+ ({ children }) => {
81
82
  return (
82
83
  <QuickEditContext.Provider
83
84
  value={{
@@ -93,19 +94,12 @@ export const useQuickEdit = <T extends Data>({
93
94
  },
94
95
  }}
95
96
  >
96
- {currentRegistration?.component}
97
+ {children}
97
98
  </QuickEditContext.Provider>
98
99
  );
99
- } else {
100
- return <></>;
101
- }
102
- }, [
103
- currentRegistration?.component,
104
- detailsLink,
105
- isQuickEditMode,
106
- registerSaveCallback,
107
- selectedItem,
108
- ]);
100
+ },
101
+ [detailsLink, isQuickEditMode, registerSaveCallback, selectedItem],
102
+ );
109
103
 
110
104
  const quickEditAction: PageHeaderActionItemProps | undefined = useMemo(
111
105
  () =>
@@ -168,7 +162,8 @@ export const useQuickEdit = <T extends Data>({
168
162
  return {
169
163
  isQuickEditMode,
170
164
  quickEditAction,
171
- QuickEditComponent,
165
+ QuickEditContextProvider,
166
+ quickEditStation: currentRegistration?.component,
172
167
  changeSelectedItem,
173
168
  };
174
169
  };