@griddo/ax 11.13.2 → 11.13.3-rc.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/config/jest/setup.js +10 -0
- package/package.json +2 -2
- package/src/GlobalStore.tsx +1 -1
- package/src/__tests__/components/Fields/AsyncCheckGroup/AsyncCheckGroup.test.tsx +276 -66
- package/src/__tests__/components/FloatingMenu/FloatingMenu.test.tsx +300 -99
- package/src/__tests__/modules/Settings/Social/Social.test.tsx +12 -4
- package/src/api/checkgroups.tsx +4 -3
- package/src/api/selects.tsx +12 -5
- package/src/components/ActionMenu/index.tsx +1 -3
- package/src/components/Browser/index.tsx +12 -3
- package/src/components/Browser/style.tsx +7 -0
- package/src/components/ConfigPanel/Form/index.tsx +47 -53
- package/src/components/Fields/AnalyticsField/PageAnalytics/atoms.tsx +9 -13
- package/src/components/Fields/AnalyticsField/PageAnalytics/index.tsx +37 -29
- package/src/components/Fields/AnalyticsField/StructuredDataAnalytics/atoms.tsx +9 -13
- package/src/components/Fields/AnalyticsField/StructuredDataAnalytics/index.tsx +17 -11
- package/src/components/Fields/AnalyticsField/index.tsx +1 -2
- package/src/components/Fields/AnalyticsField/utils.tsx +4 -4
- package/src/components/Fields/AsyncCheckGroup/index.tsx +97 -79
- package/src/components/Fields/AsyncSelect/index.tsx +33 -22
- package/src/components/Fields/DateField/DatePickerInput/index.tsx +2 -2
- package/src/components/Fields/DateField/index.tsx +3 -3
- package/src/components/Fields/IntegrationsField/SideModal/index.tsx +2 -2
- package/src/components/Fields/IntegrationsField/index.tsx +14 -10
- package/src/components/Fields/MultiCheckSelect/index.tsx +6 -6
- package/src/components/Fields/MultiCheckSelectGroup/index.tsx +39 -37
- package/src/components/Fields/MultiCheckSelectGroup/style.tsx +1 -1
- package/src/components/Fields/ReferenceField/ManualPanel/index.tsx +0 -2
- package/src/components/Fields/RichText/index.tsx +15 -7
- package/src/components/Fields/TextArea/index.tsx +9 -6
- package/src/components/FloatingMenu/index.tsx +32 -31
- package/src/components/FloatingMenu/style.tsx +23 -5
- package/src/components/Loader/components/SmallCircle.js +3 -3
- package/src/components/MainWrapper/AppBar/style.tsx +1 -0
- package/src/components/SideModal/index.tsx +1 -1
- package/src/components/TableFilters/CategoryFilter/index.tsx +14 -15
- package/src/containers/App/actions.tsx +7 -1
- package/src/containers/App/constants.tsx +2 -0
- package/src/containers/App/interfaces.tsx +5 -0
- package/src/containers/App/reducer.tsx +11 -2
- package/src/containers/Forms/actions.tsx +5 -7
- package/src/containers/Integrations/actions.tsx +1 -3
- package/src/containers/Navigation/Menu/actions.tsx +2 -2
- package/src/containers/PageEditor/actions.tsx +3 -2
- package/src/containers/Settings/DataPacks/actions.tsx +35 -29
- package/src/containers/Sites/actions.tsx +40 -33
- package/src/containers/StructuredData/actions.tsx +3 -9
- package/src/modules/ActivityLog/LogFilters/DateFilter/index.tsx +5 -4
- package/src/modules/Content/NewContentModal/PageImporter/index.tsx +1 -2
- package/src/modules/Content/index.tsx +8 -3
- package/src/modules/Content/style.tsx +7 -0
- package/src/modules/Navigation/Defaults/DefaultsEditor/index.tsx +58 -45
- package/src/modules/Navigation/Defaults/index.tsx +103 -104
- package/src/modules/PageEditor/index.tsx +9 -1
- package/src/modules/PublicPreview/index.tsx +2 -1
- package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/index.tsx +60 -44
- package/src/modules/Settings/ContentTypes/DataPacks/Config/index.tsx +32 -37
- package/src/modules/Sites/index.tsx +3 -3
- package/src/modules/Users/UserList/index.tsx +1 -1
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useRef } from "react";
|
|
2
2
|
|
|
3
3
|
import { ThemeProvider } from "styled-components";
|
|
4
4
|
import { render, cleanup, screen, fireEvent } from "@testing-library/react";
|
|
5
5
|
import { parseTheme } from "@ax/helpers";
|
|
6
6
|
import "@testing-library/jest-dom";
|
|
7
7
|
|
|
8
|
-
import FloatingMenu, { IFloatingProps } from "@ax/components/FloatingMenu";
|
|
8
|
+
import FloatingMenu, { type IFloatingProps } from "@ax/components/FloatingMenu";
|
|
9
9
|
import globalTheme from "@ax/themes/theme.json";
|
|
10
10
|
|
|
11
|
-
afterEach(cleanup);
|
|
12
|
-
|
|
13
11
|
jest.mock("react", () => {
|
|
14
12
|
const originReact = jest.requireActual("react");
|
|
15
13
|
const mUseRef = jest.fn();
|
|
@@ -21,6 +19,13 @@ jest.mock("react", () => {
|
|
|
21
19
|
|
|
22
20
|
const useMockRef = useRef as jest.MockedFunction<typeof useRef>;
|
|
23
21
|
|
|
22
|
+
afterEach(cleanup);
|
|
23
|
+
beforeEach(() => {
|
|
24
|
+
useMockRef.mockReset();
|
|
25
|
+
// Safe fallback for extra renders (useLayoutEffect, etc.)
|
|
26
|
+
useMockRef.mockImplementation(() => ({ current: null }));
|
|
27
|
+
});
|
|
28
|
+
|
|
24
29
|
describe("FloatingMenu component rendering", () => {
|
|
25
30
|
it("should render the component", () => {
|
|
26
31
|
const buttonContent = () => (
|
|
@@ -35,7 +40,6 @@ describe("FloatingMenu component rendering", () => {
|
|
|
35
40
|
isInAppBar: true,
|
|
36
41
|
position: "left",
|
|
37
42
|
closeOnSelect: false,
|
|
38
|
-
isCheckGroup: true,
|
|
39
43
|
reactiveToHover: true,
|
|
40
44
|
offset: 10,
|
|
41
45
|
};
|
|
@@ -47,7 +51,7 @@ describe("FloatingMenu component rendering", () => {
|
|
|
47
51
|
);
|
|
48
52
|
|
|
49
53
|
const floatingMenu = screen.getByTestId("floating-menu");
|
|
50
|
-
expect(floatingMenu).
|
|
54
|
+
expect(floatingMenu).toBeInTheDocument();
|
|
51
55
|
});
|
|
52
56
|
|
|
53
57
|
it("should show the floating div when click", () => {
|
|
@@ -61,7 +65,6 @@ describe("FloatingMenu component rendering", () => {
|
|
|
61
65
|
children: <div>hola</div>,
|
|
62
66
|
Button: buttonContent,
|
|
63
67
|
isInAppBar: true,
|
|
64
|
-
isCheckGroup: true,
|
|
65
68
|
reactiveToHover: true,
|
|
66
69
|
offset: 10,
|
|
67
70
|
};
|
|
@@ -113,11 +116,11 @@ describe("FloatingMenu component rendering", () => {
|
|
|
113
116
|
);
|
|
114
117
|
|
|
115
118
|
const floatingMenu = screen.getByTestId("floating-menu");
|
|
116
|
-
expect(floatingMenu).
|
|
119
|
+
expect(floatingMenu).toBeInTheDocument();
|
|
117
120
|
|
|
118
121
|
fireEvent.click(floatingMenu);
|
|
119
122
|
|
|
120
|
-
expect(screen.getByTestId("floating-menu-wrapper")).
|
|
123
|
+
expect(screen.getByTestId("floating-menu-wrapper")).toBeInTheDocument();
|
|
121
124
|
|
|
122
125
|
useMockRef.mockReturnValueOnce(wrapperRef);
|
|
123
126
|
|
|
@@ -127,7 +130,7 @@ describe("FloatingMenu component rendering", () => {
|
|
|
127
130
|
</ThemeProvider>,
|
|
128
131
|
);
|
|
129
132
|
fireEvent.mouseDown(document);
|
|
130
|
-
expect(screen.getByTestId("floating-menu-wrapper")).
|
|
133
|
+
expect(screen.getByTestId("floating-menu-wrapper")).toBeInTheDocument();
|
|
131
134
|
});
|
|
132
135
|
|
|
133
136
|
it("should close the floating div when click", () => {
|
|
@@ -141,7 +144,6 @@ describe("FloatingMenu component rendering", () => {
|
|
|
141
144
|
children: <div>hola</div>,
|
|
142
145
|
Button: buttonContent,
|
|
143
146
|
isInAppBar: true,
|
|
144
|
-
isCheckGroup: true,
|
|
145
147
|
reactiveToHover: true,
|
|
146
148
|
offset: 10,
|
|
147
149
|
};
|
|
@@ -194,11 +196,11 @@ describe("FloatingMenu component rendering", () => {
|
|
|
194
196
|
</ThemeProvider>,
|
|
195
197
|
);
|
|
196
198
|
const floatingMenu = screen.getByTestId("floating-menu");
|
|
197
|
-
expect(floatingMenu).
|
|
199
|
+
expect(floatingMenu).toBeInTheDocument();
|
|
198
200
|
|
|
199
201
|
fireEvent.click(floatingMenu);
|
|
200
202
|
|
|
201
|
-
expect(screen.getByTestId("floating-menu-wrapper")).
|
|
203
|
+
expect(screen.getByTestId("floating-menu-wrapper")).toBeInTheDocument();
|
|
202
204
|
|
|
203
205
|
Object.defineProperty(wrapperRef, "current", {
|
|
204
206
|
set(_current) {
|
|
@@ -221,14 +223,14 @@ describe("FloatingMenu component rendering", () => {
|
|
|
221
223
|
|
|
222
224
|
fireEvent.mouseDown(document);
|
|
223
225
|
|
|
224
|
-
expect(screen.queryByTestId("floating-menu-wrapper")).not.
|
|
226
|
+
expect(screen.queryByTestId("floating-menu-wrapper")).not.toBeInTheDocument();
|
|
225
227
|
});
|
|
226
228
|
|
|
227
|
-
it("should close the floating div when
|
|
228
|
-
const buttonContent = () => <
|
|
229
|
+
it("should close the floating div when checking a checkbox (isCheckGroup)", () => {
|
|
230
|
+
const buttonContent = () => <button type="button">menu</button>;
|
|
229
231
|
|
|
230
232
|
const defaultProps: IFloatingProps = {
|
|
231
|
-
children: <
|
|
233
|
+
children: <input type="checkbox" data-testid="menu-children" />,
|
|
232
234
|
Button: buttonContent,
|
|
233
235
|
isInAppBar: true,
|
|
234
236
|
isCheckGroup: true,
|
|
@@ -284,11 +286,11 @@ describe("FloatingMenu component rendering", () => {
|
|
|
284
286
|
</ThemeProvider>,
|
|
285
287
|
);
|
|
286
288
|
const floatingMenu = screen.getByTestId("floating-menu");
|
|
287
|
-
expect(floatingMenu).
|
|
289
|
+
expect(floatingMenu).toBeInTheDocument();
|
|
288
290
|
|
|
289
291
|
fireEvent.click(floatingMenu);
|
|
290
292
|
|
|
291
|
-
expect(screen.getByTestId("floating-menu-wrapper")).
|
|
293
|
+
expect(screen.getByTestId("floating-menu-wrapper")).toBeInTheDocument();
|
|
292
294
|
|
|
293
295
|
Object.defineProperty(wrapperRef, "current", {
|
|
294
296
|
set(_current) {
|
|
@@ -336,17 +338,42 @@ describe("FloatingMenu component rendering", () => {
|
|
|
336
338
|
const menuChildren = screen.getByTestId("menu-children");
|
|
337
339
|
fireEvent.click(menuChildren);
|
|
338
340
|
|
|
339
|
-
expect(screen.queryByTestId("floating-menu-wrapper")).not.
|
|
341
|
+
expect(screen.queryByTestId("floating-menu-wrapper")).not.toBeInTheDocument();
|
|
340
342
|
});
|
|
341
343
|
|
|
342
|
-
it("should
|
|
344
|
+
it("should stay open when isCheckGroup and checkbox is unchecked", () => {
|
|
345
|
+
const buttonContent = () => <span>trigger</span>;
|
|
346
|
+
|
|
347
|
+
const defaultProps: IFloatingProps = {
|
|
348
|
+
children: <input type="checkbox" defaultChecked data-testid="menu-checkbox" />,
|
|
349
|
+
Button: buttonContent,
|
|
350
|
+
isCheckGroup: true,
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
render(
|
|
354
|
+
<ThemeProvider theme={parseTheme(globalTheme)}>
|
|
355
|
+
<FloatingMenu {...defaultProps} />
|
|
356
|
+
</ThemeProvider>,
|
|
357
|
+
);
|
|
358
|
+
|
|
359
|
+
const buttonWrapper = screen.getByTestId("floating-menu-button");
|
|
360
|
+
fireEvent.click(buttonWrapper);
|
|
361
|
+
expect(screen.getByTestId("floating-menu-wrapper")).toBeInTheDocument();
|
|
362
|
+
|
|
363
|
+
// Click an already-checked checkbox → becomes unchecked → menu must stay open
|
|
364
|
+
const checkbox = screen.getByTestId("menu-checkbox");
|
|
365
|
+
fireEvent.click(checkbox);
|
|
366
|
+
|
|
367
|
+
expect(screen.queryByTestId("floating-menu-wrapper")).toBeInTheDocument();
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
it("should close the floating div when select option (closeOnSelect=true)", () => {
|
|
343
371
|
const buttonContent = () => <span data-testid="menu-children">texto</span>;
|
|
344
372
|
|
|
345
373
|
const defaultProps: IFloatingProps = {
|
|
346
374
|
children: <div>hola</div>,
|
|
347
375
|
Button: buttonContent,
|
|
348
376
|
isInAppBar: true,
|
|
349
|
-
isCheckGroup: false,
|
|
350
377
|
reactiveToHover: true,
|
|
351
378
|
offset: 10,
|
|
352
379
|
};
|
|
@@ -399,11 +426,11 @@ describe("FloatingMenu component rendering", () => {
|
|
|
399
426
|
</ThemeProvider>,
|
|
400
427
|
);
|
|
401
428
|
const floatingMenu = screen.getByTestId("floating-menu");
|
|
402
|
-
expect(floatingMenu).
|
|
429
|
+
expect(floatingMenu).toBeInTheDocument();
|
|
403
430
|
|
|
404
431
|
fireEvent.click(floatingMenu);
|
|
405
432
|
|
|
406
|
-
expect(screen.getByTestId("floating-menu-wrapper")).
|
|
433
|
+
expect(screen.getByTestId("floating-menu-wrapper")).toBeInTheDocument();
|
|
407
434
|
|
|
408
435
|
Object.defineProperty(wrapperRef, "current", {
|
|
409
436
|
set(_current) {
|
|
@@ -451,17 +478,48 @@ describe("FloatingMenu component rendering", () => {
|
|
|
451
478
|
const menuChildren = screen.getByTestId("menu-children");
|
|
452
479
|
fireEvent.click(menuChildren);
|
|
453
480
|
|
|
454
|
-
expect(screen.queryByTestId("floating-menu-wrapper")).not.
|
|
481
|
+
expect(screen.queryByTestId("floating-menu-wrapper")).not.toBeInTheDocument();
|
|
455
482
|
});
|
|
456
483
|
|
|
457
484
|
it("shouldn't close the floating div when select option", () => {
|
|
485
|
+
// menu-children lives inside children (the options area), not inside Button,
|
|
486
|
+
// so clicking it is treated as an option selection, not a button click.
|
|
487
|
+
const buttonContent = () => <span>trigger</span>;
|
|
488
|
+
|
|
489
|
+
const defaultProps: IFloatingProps = {
|
|
490
|
+
children: <span data-testid="menu-children">option text</span>,
|
|
491
|
+
Button: buttonContent,
|
|
492
|
+
isInAppBar: true,
|
|
493
|
+
reactiveToHover: true,
|
|
494
|
+
offset: 10,
|
|
495
|
+
closeOnSelect: false,
|
|
496
|
+
};
|
|
497
|
+
|
|
498
|
+
render(
|
|
499
|
+
<ThemeProvider theme={parseTheme(globalTheme)}>
|
|
500
|
+
<FloatingMenu {...defaultProps} />
|
|
501
|
+
</ThemeProvider>,
|
|
502
|
+
);
|
|
503
|
+
|
|
504
|
+
// Open the menu by clicking the button wrapper
|
|
505
|
+
const buttonWrapper = screen.getByTestId("floating-menu-button");
|
|
506
|
+
fireEvent.click(buttonWrapper);
|
|
507
|
+
expect(screen.getByTestId("floating-menu-wrapper")).toBeInTheDocument();
|
|
508
|
+
|
|
509
|
+
// Click on a menu option — with closeOnSelect=false the menu must stay open
|
|
510
|
+
const menuChildren = screen.getByTestId("menu-children");
|
|
511
|
+
fireEvent.click(menuChildren);
|
|
512
|
+
|
|
513
|
+
expect(screen.queryByTestId("floating-menu-wrapper")).toBeInTheDocument();
|
|
514
|
+
});
|
|
515
|
+
|
|
516
|
+
it("should open the floating menu when handle over", () => {
|
|
458
517
|
const buttonContent = () => <span data-testid="menu-children">texto</span>;
|
|
459
518
|
|
|
460
519
|
const defaultProps: IFloatingProps = {
|
|
461
520
|
children: <div>hola</div>,
|
|
462
521
|
Button: buttonContent,
|
|
463
522
|
isInAppBar: true,
|
|
464
|
-
isCheckGroup: false,
|
|
465
523
|
reactiveToHover: true,
|
|
466
524
|
offset: 10,
|
|
467
525
|
closeOnSelect: false,
|
|
@@ -509,75 +567,28 @@ describe("FloatingMenu component rendering", () => {
|
|
|
509
567
|
useMockRef.mockReturnValueOnce(buttonRef);
|
|
510
568
|
useMockRef.mockReturnValueOnce(menuOptionsRef);
|
|
511
569
|
|
|
512
|
-
|
|
570
|
+
render(
|
|
513
571
|
<ThemeProvider theme={parseTheme(globalTheme)}>
|
|
514
572
|
<FloatingMenu {...defaultProps} />
|
|
515
573
|
</ThemeProvider>,
|
|
516
574
|
);
|
|
517
575
|
const floatingMenu = screen.getByTestId("floating-menu");
|
|
518
|
-
expect(floatingMenu).
|
|
519
|
-
|
|
520
|
-
fireEvent.click(floatingMenu);
|
|
521
|
-
|
|
522
|
-
expect(screen.getByTestId("floating-menu-wrapper")).toBeTruthy();
|
|
576
|
+
expect(floatingMenu).toBeInTheDocument();
|
|
523
577
|
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
this._current = _current;
|
|
530
|
-
},
|
|
531
|
-
get() {
|
|
532
|
-
return this._current;
|
|
533
|
-
},
|
|
534
|
-
});
|
|
535
|
-
Object.defineProperty(buttonRef, "current", {
|
|
536
|
-
set(_current) {
|
|
537
|
-
if (_current) {
|
|
538
|
-
jest.spyOn(_current, "contains").mockReturnValueOnce(false);
|
|
539
|
-
}
|
|
540
|
-
this._current = _current;
|
|
541
|
-
},
|
|
542
|
-
get() {
|
|
543
|
-
return this._current;
|
|
544
|
-
},
|
|
545
|
-
});
|
|
546
|
-
Object.defineProperty(menuOptionsRef, "current", {
|
|
547
|
-
set(_current) {
|
|
548
|
-
if (_current) {
|
|
549
|
-
jest.spyOn(_current, "contains").mockReturnValueOnce(true);
|
|
550
|
-
}
|
|
551
|
-
this._current = _current;
|
|
552
|
-
},
|
|
553
|
-
get() {
|
|
554
|
-
return this._current;
|
|
555
|
-
},
|
|
556
|
-
});
|
|
557
|
-
|
|
558
|
-
useMockRef.mockReturnValueOnce(wrapperRef);
|
|
559
|
-
useMockRef.mockReturnValueOnce(buttonRef);
|
|
560
|
-
useMockRef.mockReturnValueOnce(menuOptionsRef);
|
|
561
|
-
rerender(
|
|
562
|
-
<ThemeProvider theme={parseTheme(globalTheme)}>
|
|
563
|
-
<FloatingMenu {...defaultProps} />
|
|
564
|
-
</ThemeProvider>,
|
|
565
|
-
);
|
|
566
|
-
|
|
567
|
-
const menuChildren = screen.getByTestId("menu-children");
|
|
568
|
-
fireEvent.click(menuChildren);
|
|
569
|
-
|
|
570
|
-
expect(screen.queryByTestId("floating-menu-wrapper")).toBeTruthy();
|
|
578
|
+
fireEvent.mouseEnter(floatingMenu);
|
|
579
|
+
expect(screen.getByTestId("floating-menu-wrapper")).toBeInTheDocument();
|
|
580
|
+
// If already open, a second mouseEnter must not close it
|
|
581
|
+
fireEvent.mouseEnter(floatingMenu);
|
|
582
|
+
expect(screen.getByTestId("floating-menu-wrapper")).toBeInTheDocument();
|
|
571
583
|
});
|
|
572
584
|
|
|
573
|
-
it("should
|
|
585
|
+
it("should close the floating menu when handle leave", () => {
|
|
574
586
|
const buttonContent = () => <span data-testid="menu-children">texto</span>;
|
|
575
587
|
|
|
576
588
|
const defaultProps: IFloatingProps = {
|
|
577
589
|
children: <div>hola</div>,
|
|
578
590
|
Button: buttonContent,
|
|
579
591
|
isInAppBar: true,
|
|
580
|
-
isCheckGroup: false,
|
|
581
592
|
reactiveToHover: true,
|
|
582
593
|
offset: 10,
|
|
583
594
|
closeOnSelect: false,
|
|
@@ -631,25 +642,29 @@ describe("FloatingMenu component rendering", () => {
|
|
|
631
642
|
</ThemeProvider>,
|
|
632
643
|
);
|
|
633
644
|
const floatingMenu = screen.getByTestId("floating-menu");
|
|
634
|
-
expect(floatingMenu).
|
|
645
|
+
expect(floatingMenu).toBeInTheDocument();
|
|
635
646
|
|
|
636
647
|
fireEvent.mouseEnter(floatingMenu);
|
|
637
|
-
expect(screen.getByTestId("floating-menu-wrapper")).
|
|
638
|
-
|
|
639
|
-
fireEvent.
|
|
640
|
-
expect(screen.
|
|
648
|
+
expect(screen.getByTestId("floating-menu-wrapper")).toBeInTheDocument();
|
|
649
|
+
|
|
650
|
+
fireEvent.mouseLeave(floatingMenu);
|
|
651
|
+
expect(screen.queryByTestId("floating-menu-wrapper")).not.toBeInTheDocument();
|
|
641
652
|
});
|
|
642
653
|
|
|
643
|
-
it("should close the floating
|
|
644
|
-
const buttonContent = () =>
|
|
654
|
+
it("should close the floating div when clicking an element with data-close-menu", () => {
|
|
655
|
+
const buttonContent = () => (
|
|
656
|
+
<div>
|
|
657
|
+
<span>trigger</span>
|
|
658
|
+
</div>
|
|
659
|
+
);
|
|
645
660
|
|
|
646
661
|
const defaultProps: IFloatingProps = {
|
|
647
|
-
children:
|
|
662
|
+
children: (
|
|
663
|
+
<span data-testid="menu-children" data-close-menu="true">
|
|
664
|
+
Close
|
|
665
|
+
</span>
|
|
666
|
+
),
|
|
648
667
|
Button: buttonContent,
|
|
649
|
-
isInAppBar: true,
|
|
650
|
-
isCheckGroup: false,
|
|
651
|
-
reactiveToHover: true,
|
|
652
|
-
offset: 10,
|
|
653
668
|
closeOnSelect: false,
|
|
654
669
|
};
|
|
655
670
|
|
|
@@ -671,7 +686,8 @@ describe("FloatingMenu component rendering", () => {
|
|
|
671
686
|
Object.defineProperty(buttonRef, "current", {
|
|
672
687
|
set(_current) {
|
|
673
688
|
if (_current) {
|
|
674
|
-
|
|
689
|
+
// true for button click (open), false for option click
|
|
690
|
+
jest.spyOn(_current, "contains").mockReturnValueOnce(true).mockReturnValueOnce(false);
|
|
675
691
|
}
|
|
676
692
|
this._current = _current;
|
|
677
693
|
},
|
|
@@ -682,7 +698,8 @@ describe("FloatingMenu component rendering", () => {
|
|
|
682
698
|
Object.defineProperty(menuOptionsRef, "current", {
|
|
683
699
|
set(_current) {
|
|
684
700
|
if (_current) {
|
|
685
|
-
|
|
701
|
+
// true when clicking menu-children (optionWasSelected)
|
|
702
|
+
jest.spyOn(_current, "contains").mockReturnValueOnce(true);
|
|
686
703
|
}
|
|
687
704
|
this._current = _current;
|
|
688
705
|
},
|
|
@@ -695,18 +712,202 @@ describe("FloatingMenu component rendering", () => {
|
|
|
695
712
|
useMockRef.mockReturnValueOnce(buttonRef);
|
|
696
713
|
useMockRef.mockReturnValueOnce(menuOptionsRef);
|
|
697
714
|
|
|
698
|
-
render(
|
|
715
|
+
const { rerender } = render(
|
|
699
716
|
<ThemeProvider theme={parseTheme(globalTheme)}>
|
|
700
717
|
<FloatingMenu {...defaultProps} />
|
|
701
718
|
</ThemeProvider>,
|
|
702
719
|
);
|
|
720
|
+
|
|
703
721
|
const floatingMenu = screen.getByTestId("floating-menu");
|
|
704
|
-
|
|
722
|
+
fireEvent.click(floatingMenu);
|
|
723
|
+
expect(screen.getByTestId("floating-menu-wrapper")).toBeInTheDocument();
|
|
724
|
+
|
|
725
|
+
rerender(
|
|
726
|
+
<ThemeProvider theme={parseTheme(globalTheme)}>
|
|
727
|
+
<FloatingMenu {...defaultProps} />
|
|
728
|
+
</ThemeProvider>,
|
|
729
|
+
);
|
|
730
|
+
|
|
731
|
+
const menuChildren = screen.getByTestId("menu-children");
|
|
732
|
+
fireEvent.click(menuChildren);
|
|
733
|
+
|
|
734
|
+
expect(screen.queryByTestId("floating-menu-wrapper")).not.toBeInTheDocument();
|
|
735
|
+
});
|
|
736
|
+
|
|
737
|
+
it("should not open when disabled", () => {
|
|
738
|
+
const buttonContent = () => <span>trigger</span>;
|
|
739
|
+
|
|
740
|
+
const defaultProps: IFloatingProps = {
|
|
741
|
+
children: <div>content</div>,
|
|
742
|
+
Button: buttonContent,
|
|
743
|
+
disabled: true,
|
|
744
|
+
};
|
|
745
|
+
|
|
746
|
+
render(
|
|
747
|
+
<ThemeProvider theme={parseTheme(globalTheme)}>
|
|
748
|
+
<FloatingMenu {...defaultProps} />
|
|
749
|
+
</ThemeProvider>,
|
|
750
|
+
);
|
|
751
|
+
|
|
752
|
+
const buttonWrapper = screen.getByTestId("floating-menu-button");
|
|
753
|
+
fireEvent.click(buttonWrapper);
|
|
754
|
+
|
|
755
|
+
expect(screen.queryByTestId("floating-menu-wrapper")).not.toBeInTheDocument();
|
|
756
|
+
});
|
|
757
|
+
|
|
758
|
+
it("should not open on mouse enter when disabled", () => {
|
|
759
|
+
const buttonContent = () => <span>trigger</span>;
|
|
760
|
+
|
|
761
|
+
const defaultProps: IFloatingProps = {
|
|
762
|
+
children: <div>content</div>,
|
|
763
|
+
Button: buttonContent,
|
|
764
|
+
reactiveToHover: true,
|
|
765
|
+
disabled: true,
|
|
766
|
+
};
|
|
767
|
+
|
|
768
|
+
render(
|
|
769
|
+
<ThemeProvider theme={parseTheme(globalTheme)}>
|
|
770
|
+
<FloatingMenu {...defaultProps} />
|
|
771
|
+
</ThemeProvider>,
|
|
772
|
+
);
|
|
705
773
|
|
|
774
|
+
const floatingMenu = screen.getByTestId("floating-menu");
|
|
706
775
|
fireEvent.mouseEnter(floatingMenu);
|
|
707
|
-
expect(screen.getByTestId("floating-menu-wrapper")).toBeTruthy();
|
|
708
776
|
|
|
777
|
+
expect(screen.queryByTestId("floating-menu-wrapper")).not.toBeInTheDocument();
|
|
778
|
+
});
|
|
779
|
+
|
|
780
|
+
it("should call actionOnClose when clicking outside", () => {
|
|
781
|
+
const actionOnClose = jest.fn();
|
|
782
|
+
const buttonContent = () => <span>trigger</span>;
|
|
783
|
+
|
|
784
|
+
const defaultProps: IFloatingProps = {
|
|
785
|
+
children: <div>content</div>,
|
|
786
|
+
Button: buttonContent,
|
|
787
|
+
actionOnClose,
|
|
788
|
+
};
|
|
789
|
+
|
|
790
|
+
render(
|
|
791
|
+
<ThemeProvider theme={parseTheme(globalTheme)}>
|
|
792
|
+
<FloatingMenu {...defaultProps} />
|
|
793
|
+
</ThemeProvider>,
|
|
794
|
+
);
|
|
795
|
+
|
|
796
|
+
// Open the menu
|
|
797
|
+
const buttonWrapper = screen.getByTestId("floating-menu-button");
|
|
798
|
+
fireEvent.click(buttonWrapper);
|
|
799
|
+
expect(screen.getByTestId("floating-menu-wrapper")).toBeInTheDocument();
|
|
800
|
+
|
|
801
|
+
// Click outside — document is not inside wrapper
|
|
802
|
+
fireEvent.mouseDown(document);
|
|
803
|
+
|
|
804
|
+
expect(actionOnClose).toHaveBeenCalledTimes(1);
|
|
805
|
+
expect(screen.queryByTestId("floating-menu-wrapper")).not.toBeInTheDocument();
|
|
806
|
+
});
|
|
807
|
+
|
|
808
|
+
it("should call actionOnClose when closing via button toggle", () => {
|
|
809
|
+
const actionOnClose = jest.fn();
|
|
810
|
+
const buttonContent = () => <span>trigger</span>;
|
|
811
|
+
|
|
812
|
+
const defaultProps: IFloatingProps = {
|
|
813
|
+
children: <div>content</div>,
|
|
814
|
+
Button: buttonContent,
|
|
815
|
+
actionOnClose,
|
|
816
|
+
};
|
|
817
|
+
|
|
818
|
+
render(
|
|
819
|
+
<ThemeProvider theme={parseTheme(globalTheme)}>
|
|
820
|
+
<FloatingMenu {...defaultProps} />
|
|
821
|
+
</ThemeProvider>,
|
|
822
|
+
);
|
|
823
|
+
|
|
824
|
+
const buttonWrapper = screen.getByTestId("floating-menu-button");
|
|
825
|
+
|
|
826
|
+
fireEvent.click(buttonWrapper);
|
|
827
|
+
expect(screen.getByTestId("floating-menu-wrapper")).toBeInTheDocument();
|
|
828
|
+
|
|
829
|
+
fireEvent.click(buttonWrapper);
|
|
830
|
+
|
|
831
|
+
expect(actionOnClose).toHaveBeenCalledTimes(1);
|
|
832
|
+
expect(screen.queryByTestId("floating-menu-wrapper")).not.toBeInTheDocument();
|
|
833
|
+
});
|
|
834
|
+
|
|
835
|
+
it("should call actionOnClose when closing via mouseLeave", () => {
|
|
836
|
+
const actionOnClose = jest.fn();
|
|
837
|
+
const buttonContent = () => <span>trigger</span>;
|
|
838
|
+
|
|
839
|
+
const defaultProps: IFloatingProps = {
|
|
840
|
+
children: <div>content</div>,
|
|
841
|
+
Button: buttonContent,
|
|
842
|
+
reactiveToHover: true,
|
|
843
|
+
actionOnClose,
|
|
844
|
+
};
|
|
845
|
+
|
|
846
|
+
render(
|
|
847
|
+
<ThemeProvider theme={parseTheme(globalTheme)}>
|
|
848
|
+
<FloatingMenu {...defaultProps} />
|
|
849
|
+
</ThemeProvider>,
|
|
850
|
+
);
|
|
851
|
+
|
|
852
|
+
const buttonWrapper = screen.getByTestId("floating-menu-button");
|
|
853
|
+
fireEvent.click(buttonWrapper);
|
|
854
|
+
expect(screen.getByTestId("floating-menu-wrapper")).toBeInTheDocument();
|
|
855
|
+
|
|
856
|
+
const floatingMenu = screen.getByTestId("floating-menu");
|
|
857
|
+
fireEvent.mouseLeave(floatingMenu);
|
|
858
|
+
|
|
859
|
+
expect(actionOnClose).toHaveBeenCalledTimes(1);
|
|
860
|
+
expect(screen.queryByTestId("floating-menu-wrapper")).not.toBeInTheDocument();
|
|
861
|
+
});
|
|
862
|
+
|
|
863
|
+
it("should close the menu when clicking the button while open (toggle)", () => {
|
|
864
|
+
const buttonContent = () => <span>trigger</span>;
|
|
865
|
+
|
|
866
|
+
const defaultProps: IFloatingProps = {
|
|
867
|
+
children: <span data-testid="menu-option">option</span>,
|
|
868
|
+
Button: buttonContent,
|
|
869
|
+
};
|
|
870
|
+
|
|
871
|
+
render(
|
|
872
|
+
<ThemeProvider theme={parseTheme(globalTheme)}>
|
|
873
|
+
<FloatingMenu {...defaultProps} />
|
|
874
|
+
</ThemeProvider>,
|
|
875
|
+
);
|
|
876
|
+
|
|
877
|
+
const buttonWrapper = screen.getByTestId("floating-menu-button");
|
|
878
|
+
|
|
879
|
+
// First click: open
|
|
880
|
+
fireEvent.click(buttonWrapper);
|
|
881
|
+
expect(screen.getByTestId("floating-menu-wrapper")).toBeInTheDocument();
|
|
882
|
+
|
|
883
|
+
// Second click on button: close
|
|
884
|
+
fireEvent.click(buttonWrapper);
|
|
885
|
+
expect(screen.queryByTestId("floating-menu-wrapper")).not.toBeInTheDocument();
|
|
886
|
+
});
|
|
887
|
+
|
|
888
|
+
it("should not close on mouse leave when reactiveToHover is false", () => {
|
|
889
|
+
const buttonContent = () => <span>trigger</span>;
|
|
890
|
+
|
|
891
|
+
const defaultProps: IFloatingProps = {
|
|
892
|
+
children: <div>content</div>,
|
|
893
|
+
Button: buttonContent,
|
|
894
|
+
reactiveToHover: false,
|
|
895
|
+
};
|
|
896
|
+
|
|
897
|
+
render(
|
|
898
|
+
<ThemeProvider theme={parseTheme(globalTheme)}>
|
|
899
|
+
<FloatingMenu {...defaultProps} />
|
|
900
|
+
</ThemeProvider>,
|
|
901
|
+
);
|
|
902
|
+
|
|
903
|
+
const buttonWrapper = screen.getByTestId("floating-menu-button");
|
|
904
|
+
fireEvent.click(buttonWrapper);
|
|
905
|
+
expect(screen.getByTestId("floating-menu-wrapper")).toBeInTheDocument();
|
|
906
|
+
|
|
907
|
+
const floatingMenu = screen.getByTestId("floating-menu");
|
|
709
908
|
fireEvent.mouseLeave(floatingMenu);
|
|
710
|
-
|
|
909
|
+
|
|
910
|
+
// Still open — mouseLeave only works when reactiveToHover=true
|
|
911
|
+
expect(screen.queryByTestId("floating-menu-wrapper")).toBeInTheDocument();
|
|
711
912
|
});
|
|
712
913
|
});
|
|
@@ -1,16 +1,24 @@
|
|
|
1
|
+
import axios from "axios";
|
|
1
2
|
import { Router } from "react-router-dom";
|
|
2
3
|
|
|
4
|
+
import configureStore from "redux-mock-store";
|
|
5
|
+
import thunk from "redux-thunk";
|
|
6
|
+
import { ThemeProvider } from "styled-components";
|
|
7
|
+
|
|
3
8
|
import { parseTheme } from "@ax/helpers";
|
|
4
9
|
import Social from "@ax/modules/Settings/Social";
|
|
5
10
|
import history from "@ax/routes/history";
|
|
6
11
|
import globalTheme from "@ax/themes/theme.json";
|
|
7
12
|
|
|
8
|
-
import configureStore from "redux-mock-store";
|
|
9
|
-
import thunk from "redux-thunk";
|
|
10
|
-
import { ThemeProvider } from "styled-components";
|
|
11
|
-
|
|
12
13
|
import { act, cleanup, render, screen } from "../../../../../config/jest/test-utils";
|
|
13
14
|
|
|
15
|
+
jest.mock("axios");
|
|
16
|
+
const mockedAxios = axios as jest.MockedFunction<typeof axios>;
|
|
17
|
+
|
|
18
|
+
beforeEach(() => {
|
|
19
|
+
mockedAxios.mockResolvedValue({ status: 200, data: {}, statusText: "OK", headers: {}, config: {} as any });
|
|
20
|
+
});
|
|
21
|
+
|
|
14
22
|
afterEach(cleanup);
|
|
15
23
|
|
|
16
24
|
const mockComponent = () => null;
|
package/src/api/checkgroups.tsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { AxiosResponse } from "axios";
|
|
1
|
+
import type { AxiosResponse } from "axios";
|
|
2
|
+
|
|
2
3
|
import { template } from "./config";
|
|
3
|
-
import {
|
|
4
|
+
import { type IServiceConfig, sendRequest } from "./utils";
|
|
4
5
|
|
|
5
6
|
const SERVICES: { [key: string]: IServiceConfig } = {
|
|
6
7
|
GET_STRUCTURED_DATA: {
|
|
@@ -32,7 +33,7 @@ const getCheckGroupItems = async (
|
|
|
32
33
|
} = SERVICES.GET_STRUCTURED_DATA;
|
|
33
34
|
|
|
34
35
|
const allLanguagesQuery = allLanguages ? "&allLanguages=true" : "";
|
|
35
|
-
const languagesIdsQuery = languagesIds
|
|
36
|
+
const languagesIdsQuery = languagesIds?.length ? `&languagesIds=${languagesIds}` : "";
|
|
36
37
|
|
|
37
38
|
SERVICES.GET_STRUCTURED_DATA.dynamicUrl = `${host}${prefix}${siteId}${infix}${source}${suffix}?groupingCategories=on&order=title-ASC${allLanguagesQuery}${languagesIdsQuery}`;
|
|
38
39
|
|
package/src/api/selects.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { template } from "./config";
|
|
2
|
-
import { IServiceConfig, sendRequest } from "./utils";
|
|
2
|
+
import { type IServiceConfig, sendRequest } from "./utils";
|
|
3
3
|
|
|
4
4
|
const SERVICES: { [key: string]: IServiceConfig } = {
|
|
5
5
|
GET_SITE_ITEMS: {
|
|
@@ -19,22 +19,29 @@ const SERVICES: { [key: string]: IServiceConfig } = {
|
|
|
19
19
|
},
|
|
20
20
|
};
|
|
21
21
|
|
|
22
|
-
const getSelectSiteItems = async (
|
|
22
|
+
const getSelectSiteItems = async (
|
|
23
|
+
siteId: number,
|
|
24
|
+
entity: string,
|
|
25
|
+
params?: Record<string, any>,
|
|
26
|
+
pageID?: number,
|
|
27
|
+
forceLanguage?: number,
|
|
28
|
+
) => {
|
|
23
29
|
const { host, endpoint } = SERVICES.GET_SITE_ITEMS;
|
|
24
30
|
|
|
25
31
|
let urlParams = "";
|
|
26
32
|
if (params) {
|
|
27
33
|
for (const prop in params) {
|
|
28
|
-
urlParams =
|
|
34
|
+
urlParams = `${urlParams}${prop}=${params[prop]}&`;
|
|
29
35
|
}
|
|
30
|
-
urlParams = urlParams.length ?
|
|
36
|
+
urlParams = urlParams.length ? `?${urlParams.slice(0, -1)}` : "";
|
|
31
37
|
}
|
|
32
38
|
|
|
33
39
|
SERVICES.GET_SITE_ITEMS.dynamicUrl = pageID
|
|
34
40
|
? `${host}${endpoint}${siteId}/${entity}/${pageID}${urlParams}`
|
|
35
41
|
: `${host}${endpoint}${siteId}/${entity}${urlParams}`;
|
|
36
42
|
|
|
37
|
-
|
|
43
|
+
const headers = forceLanguage ? { lang: forceLanguage } : undefined;
|
|
44
|
+
return sendRequest(SERVICES.GET_SITE_ITEMS, undefined, headers);
|
|
38
45
|
};
|
|
39
46
|
|
|
40
47
|
const getSelectItems = async (entity: string, entityId?: number | string, lang?: number) => {
|