@uxf/cms 13.0.3 → 14.0.0
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/README.md +1 -1
- package/lib/layout/sidebar.js +18 -26
- package/lib/menu/ui/menu-item.js +5 -2
- package/package.json +20 -20
- package/pages/content-builder/content-header-behaviour.spec.d.ts +1 -0
- package/pages/content-builder/content-header-behaviour.spec.js +22 -0
- package/pages/content-builder/content-header.js +1 -1
- package/pages/content-builder/context/details-visibility-context.js +3 -3
- package/pages/grid-page/grid-page.js +2 -2
- package/pages/grid-page/history-pathname.d.ts +6 -0
- package/pages/grid-page/history-pathname.js +11 -0
- package/pages/grid-page/history-pathname.test.d.ts +1 -0
- package/pages/grid-page/history-pathname.test.js +11 -0
- package/pages/translations.d.ts +3 -0
- package/pages/translations.js +3 -0
- package/security/restricted-page.js +1 -1
- package/translations/cs.json +2 -1
- package/translations/translations.d.ts +3 -0
- package/utils/use-viewport-height.js +7 -19
- package/utils/use-viewport-height.test.d.ts +1 -0
- package/utils/use-viewport-height.test.js +37 -0
- package/utils/use-visual-viewport-height.d.ts +2 -0
- package/utils/use-visual-viewport-height.js +23 -0
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ It is not a general UI kit (`@uxf/ui`), a form library (`@uxf/form`), or a data
|
|
|
16
16
|
yarn add @uxf/cms
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
Peer dependencies: `@uxf/core`, `@uxf/core-react`, `@uxf/data-grid`, `@uxf/form`, `@uxf/router`, `@uxf/styles`, `@uxf/ui`, `@uxf/wysiwyg`, `@dnd-kit/core`, `@dnd-kit/sortable`, `@dnd-kit/utilities`, `@floating-ui/react`, `axios`, `axios-hooks`, `swr`, `react-hook-form`, `next` (>=
|
|
19
|
+
Peer dependencies: `@uxf/core`, `@uxf/core-react`, `@uxf/data-grid`, `@uxf/form`, `@uxf/router`, `@uxf/styles`, `@uxf/ui`, `@uxf/wysiwyg`, `@dnd-kit/core`, `@dnd-kit/sortable`, `@dnd-kit/utilities`, `@floating-ui/react`, `axios`, `axios-hooks`, `swr`, `react-hook-form`, `next` (>=16.0.0), `react` (^19.3.0), `react-dom` (^19.3.0).
|
|
20
20
|
|
|
21
21
|
Because it builds on `@uxf/ui`, `@uxf/form` and `@uxf/data-grid`, complete their setup as well (see [`@uxf/ui`](../ui/README.md) and [`@uxf/form`](../form/README.md)) — the `UiContextProvider`, the token layer, and the component CSS they require.
|
|
22
22
|
|
package/lib/layout/sidebar.js
CHANGED
|
@@ -34,9 +34,11 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.Sidebar = void 0;
|
|
37
|
+
const use_media_query_1 = require("@uxf/core-react/hooks/use-media-query");
|
|
37
38
|
const rem_1 = require("@uxf/styles/units/rem");
|
|
38
39
|
const react_1 = __importStar(require("react"));
|
|
39
40
|
const tw_screens_1 = require("../../ui/tw-tokens/tw-screens");
|
|
41
|
+
const use_visual_viewport_height_1 = require("../../utils/use-visual-viewport-height");
|
|
40
42
|
const menu_1 = require("../menu");
|
|
41
43
|
const mobile_bar_1 = require("../menu/mobile-bar");
|
|
42
44
|
const user_menu_1 = require("../menu/ui/user-menu");
|
|
@@ -45,39 +47,29 @@ const uxfLogo = (react_1.default.createElement("svg", { height: "30", viewBox: "
|
|
|
45
47
|
react_1.default.createElement("path", { clipRule: "evenodd", d: "M33.563 12.874a9.103 9.103 0 0 0 0-12.874L20.69 12.874l.107.105a9.103 9.103 0 0 0 12.766-.105Zm-20.69-6.437a9.103 9.103 0 0 1 .106 12.766l-.105.107L0 6.437a9.103 9.103 0 0 1 12.874 0ZM40 33.563 27.127 20.69l-.106.107a9.103 9.103 0 0 0 12.98 12.766Zm-20.69-6.437-.107-.105A9.103 9.103 0 0 0 6.437 40l12.874-12.874Z", fill: "#FFF", fillRule: "evenodd" }),
|
|
46
48
|
react_1.default.createElement("path", { clipRule: "evenodd", d: "m84.325 7.295 5.133 8.675h.199l5.158-8.675h6.078l-7.768 12.727 7.942 12.727h-6.19l-5.22-8.687h-.199l-5.22 8.687h-6.165l7.967-12.727-7.818-12.727h6.103Zm-24.194 0v16.07c0 .97.214 1.832.64 2.586a4.58 4.58 0 0 0 1.809 1.777c.779.431 1.686.647 2.722.647 1.044 0 1.953-.216 2.728-.647a4.591 4.591 0 0 0 1.802-1.777c.427-.754.64-1.616.64-2.585V7.296h5.382v16.53c0 1.856-.441 3.48-1.324 4.872-.882 1.392-2.115 2.475-3.697 3.25-1.583.775-3.426 1.162-5.531 1.162-2.113 0-3.96-.387-5.543-1.162-1.583-.775-2.813-1.858-3.692-3.25-.878-1.392-1.317-3.016-1.317-4.872V7.296h5.381ZM170.25 13.41c2.411 0 4.311.51 5.698 1.529 1.388 1.019 2.198 2.407 2.43 4.164l-4.847.298a2.555 2.555 0 0 0-.534-1.125 2.942 2.942 0 0 0-1.075-.808c-.444-.203-.972-.304-1.585-.304-.821 0-1.512.172-2.076.515-.563.344-.845.802-.845 1.374 0 .456.182.84.547 1.156.364.315.99.567 1.877.758l3.455.696c1.856.381 3.24.994 4.151 1.84.912.845 1.367 1.955 1.367 3.33 0 1.252-.366 2.35-1.1 3.294-.733.945-1.736 1.68-3.007 2.206-1.272.526-2.737.79-4.394.79-2.527 0-4.539-.529-6.034-1.585-1.496-1.057-2.372-2.496-2.629-4.32l5.208-.273c.157.77.538 1.357 1.143 1.759.605.402 1.38.603 2.324.603.928 0 1.676-.18 2.244-.54.567-.361.855-.827.864-1.4-.009-.48-.212-.875-.609-1.186-.398-.31-1.011-.55-1.84-.715l-3.306-.659c-1.864-.372-3.25-1.019-4.157-1.938-.908-.92-1.361-2.093-1.361-3.518 0-1.226.333-2.283 1-3.17.667-.886 1.608-1.57 2.821-2.05 1.214-.48 2.637-.72 4.27-.72Zm-36.686.373a12.285 12.285 0 0 0-3.051-.373c-1.525 0-2.865.23-4.021.69-1.156.46-2.098 1.114-2.827 1.964-.73.849-1.219 1.854-1.467 3.014l4.897.397c.182-.63.555-1.153 1.119-1.572.563-.418 1.321-.627 2.274-.627.903 0 1.601.215 2.094.646.493.43.74 1.04.74 1.827v.075c0 .405-.153.712-.46.92-.307.206-.8.362-1.479.465-.68.104-1.574.214-2.685.33-.944.09-1.845.248-2.703.472a7.698 7.698 0 0 0-2.293.994 4.727 4.727 0 0 0-1.591 1.74c-.39.721-.584 1.612-.584 2.673 0 1.259.275 2.31.826 3.15a5.147 5.147 0 0 0 2.256 1.902c.953.427 2.038.64 3.257.64.944 0 1.777-.126 2.498-.38a5.55 5.55 0 0 0 1.852-1.055 5.31 5.31 0 0 0 1.23-1.573h.149v2.648h5.022V19.873c0-1.135-.22-2.11-.659-2.927a5.655 5.655 0 0 0-1.796-2.007 8.039 8.039 0 0 0-2.598-1.156Zm-13.424-2.05V7.294h-16.853v25.454h5.381V22.235h10.354v-4.438h-10.354v-6.065h11.472Zm32.603 1.677c1.326 0 2.482.29 3.468.87.986.58 1.753 1.407 2.3 2.48.546 1.073.82 2.35.82 3.834V32.75h-5.295V21.539c.008-1.169-.29-2.082-.895-2.74-.605-.66-1.437-.989-2.498-.989-.713 0-1.34.153-1.883.46a3.166 3.166 0 0 0-1.268 1.336c-.302.584-.458 1.286-.466 2.107V32.75h-5.295V13.659h5.047v3.368H147a5.358 5.358 0 0 1 2.126-2.641c.994-.65 2.2-.976 3.616-.976Zm-20.061 10.782c.286-.087.512-.184.678-.292v2.026c0 .671-.17 1.272-.51 1.802-.34.53-.808.951-1.404 1.262-.597.31-1.285.466-2.064.466-.812 0-1.481-.189-2.007-.566-.526-.377-.789-.925-.789-1.646 0-.497.128-.914.385-1.25.257-.335.617-.602 1.082-.801a6.547 6.547 0 0 1 1.628-.435l.969-.143a24.15 24.15 0 0 0 1.069-.186c.356-.071.677-.15.963-.237Z", fill: "#FFF", fillRule: "evenodd" })));
|
|
47
49
|
const Sidebar = (props) => {
|
|
48
|
-
var _a, _b, _c;
|
|
49
|
-
const
|
|
50
|
+
var _a, _b, _c, _d;
|
|
51
|
+
const deviceHeight = (_a = (0, use_visual_viewport_height_1.useVisualViewportHeight)()) !== null && _a !== void 0 ? _a : 0;
|
|
50
52
|
const [isMenuOpen, setIsMenuOpen] = (0, react_1.useState)(false);
|
|
51
53
|
const toggleMenu = () => setIsMenuOpen((prev) => !prev);
|
|
54
|
+
// The open menu covers the page below the md breakpoint, so the page must not scroll under it.
|
|
55
|
+
const isDesktop = (0, use_media_query_1.useMediaQuery)(`(min-width: ${tw_screens_1.twScreens.md})`);
|
|
56
|
+
const isPageLocked = isMenuOpen && !isDesktop;
|
|
52
57
|
(0, react_1.useEffect)(() => {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
58
|
+
if (!isPageLocked) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
// Restored rather than cleared, so a lock someone else holds survives the menu closing.
|
|
62
|
+
const previousOverflow = document.body.style.overflow;
|
|
63
|
+
document.body.style.overflow = "hidden";
|
|
56
64
|
return () => {
|
|
57
|
-
|
|
65
|
+
document.body.style.overflow = previousOverflow;
|
|
58
66
|
};
|
|
59
|
-
}, []);
|
|
60
|
-
(0
|
|
61
|
-
const handler = () => {
|
|
62
|
-
if (!window.matchMedia(`(min-width: ${tw_screens_1.twScreens.md})`).matches && isMenuOpen) {
|
|
63
|
-
document.body.style.overflow = "hidden";
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
document.body.style.overflow = "";
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
handler();
|
|
70
|
-
window.addEventListener("resize", handler);
|
|
71
|
-
return () => {
|
|
72
|
-
document.body.style.overflow = "";
|
|
73
|
-
window.removeEventListener("resize", handler);
|
|
74
|
-
};
|
|
75
|
-
}, [isMenuOpen]);
|
|
76
|
-
return ((_a = props.CustomSidebar) !== null && _a !== void 0 ? _a : (react_1.default.createElement("div", { className: "uxf-cms-sidebar", style: { "--drawer-width": (0, rem_1.rem)(styles_1.drawerWidth) } },
|
|
67
|
+
}, [isPageLocked]);
|
|
68
|
+
return ((_b = props.CustomSidebar) !== null && _b !== void 0 ? _b : (react_1.default.createElement("div", { className: "uxf-cms-sidebar", style: { "--drawer-width": (0, rem_1.rem)(styles_1.drawerWidth) } },
|
|
77
69
|
react_1.default.createElement("div", { className: `uxf-cms-sidebar__content ${isMenuOpen ? "uxf-cms-sidebar__content--open" : "uxf-cms-sidebar__content--closed"}`, style: { "--device-height": (0, rem_1.rem)(deviceHeight) } },
|
|
78
|
-
react_1.default.createElement("div", { className: "uxf-cms-sidebar__logo" }, (
|
|
70
|
+
react_1.default.createElement("div", { className: "uxf-cms-sidebar__logo" }, (_c = props.Logo) !== null && _c !== void 0 ? _c : uxfLogo),
|
|
79
71
|
props.menuConfiguration && props.menuConfiguration.length > 0 && (react_1.default.createElement(react_1.default.Fragment, null,
|
|
80
|
-
react_1.default.createElement("div", { className: `uxf-cms-sidebar__nav ${((
|
|
72
|
+
react_1.default.createElement("div", { className: `uxf-cms-sidebar__nav ${((_d = props.menuConfiguration.at(0)) === null || _d === void 0 ? void 0 : _d.type) === "super-section"
|
|
81
73
|
? "uxf-cms-sidebar__nav--super-section"
|
|
82
74
|
: ""}` },
|
|
83
75
|
react_1.default.createElement(menu_1.Menu, { menu: props.menuConfiguration })),
|
package/lib/menu/ui/menu-item.js
CHANGED
|
@@ -50,9 +50,12 @@ const MenuItem = (props) => {
|
|
|
50
50
|
const firstVisibleChild = visibleChildren.at(0);
|
|
51
51
|
const isInitiallyOpen = (isActive || hasActiveChildren) && props.item.children.length > 0;
|
|
52
52
|
const [isSubmenuOpen, setIsSubmenuOpen] = (0, react_1.useState)(isInitiallyOpen);
|
|
53
|
-
|
|
53
|
+
// Follow the route during render instead of in an effect, which first rendered one commit with the old value.
|
|
54
|
+
const [previousIsInitiallyOpen, setPreviousIsInitiallyOpen] = (0, react_1.useState)(isInitiallyOpen);
|
|
55
|
+
if (isInitiallyOpen !== previousIsInitiallyOpen) {
|
|
56
|
+
setPreviousIsInitiallyOpen(isInitiallyOpen);
|
|
54
57
|
setIsSubmenuOpen(isInitiallyOpen);
|
|
55
|
-
}
|
|
58
|
+
}
|
|
56
59
|
const toggle = () => setIsSubmenuOpen((prev) => !prev);
|
|
57
60
|
if (!props.item.isVisible(loggedUser) ||
|
|
58
61
|
(props.item.children.length !== 0 && !props.item.hasVisibleChildren(loggedUser))) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uxf/cms",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "14.0.0",
|
|
4
4
|
"description": "UXF Cms",
|
|
5
5
|
"author": "UXFans <dev@uxf.cz>",
|
|
6
6
|
"homepage": "https://gitlab.com/uxf-npm/cms#readme",
|
|
@@ -29,18 +29,18 @@
|
|
|
29
29
|
},
|
|
30
30
|
"peerDependencies": {
|
|
31
31
|
"@floating-ui/react": "^0.27.20",
|
|
32
|
-
"@uxf/core": "
|
|
33
|
-
"@uxf/core-react": "
|
|
34
|
-
"@uxf/data-grid": "
|
|
35
|
-
"@uxf/dnd": "
|
|
36
|
-
"@uxf/form": "
|
|
37
|
-
"@uxf/router": "
|
|
38
|
-
"@uxf/styles": "
|
|
39
|
-
"@uxf/ui": "
|
|
40
|
-
"@uxf/wysiwyg": "
|
|
32
|
+
"@uxf/core": "14.0.0",
|
|
33
|
+
"@uxf/core-react": "14.0.0",
|
|
34
|
+
"@uxf/data-grid": "14.0.0",
|
|
35
|
+
"@uxf/dnd": "14.0.0",
|
|
36
|
+
"@uxf/form": "14.0.0",
|
|
37
|
+
"@uxf/router": "14.0.0",
|
|
38
|
+
"@uxf/styles": "14.0.0",
|
|
39
|
+
"@uxf/ui": "14.0.0",
|
|
40
|
+
"@uxf/wysiwyg": "14.0.0",
|
|
41
41
|
"axios": "^1.20.0",
|
|
42
42
|
"axios-hooks": "^5.1.1",
|
|
43
|
-
"next": ">=
|
|
43
|
+
"next": ">=16.0.0",
|
|
44
44
|
"react": "^19.3.0",
|
|
45
45
|
"react-dom": "^19.3.0",
|
|
46
46
|
"react-hook-form": "^7.89.0",
|
|
@@ -51,15 +51,15 @@
|
|
|
51
51
|
"@types/node": "24",
|
|
52
52
|
"@types/react": "19.3.0",
|
|
53
53
|
"@types/react-dom": "19.3.0",
|
|
54
|
-
"@uxf/core": "
|
|
55
|
-
"@uxf/core-react": "
|
|
56
|
-
"@uxf/data-grid": "
|
|
57
|
-
"@uxf/dnd": "
|
|
58
|
-
"@uxf/form": "
|
|
59
|
-
"@uxf/router": "
|
|
60
|
-
"@uxf/styles": "
|
|
61
|
-
"@uxf/ui": "
|
|
62
|
-
"@uxf/wysiwyg": "
|
|
54
|
+
"@uxf/core": "14.0.0",
|
|
55
|
+
"@uxf/core-react": "14.0.0",
|
|
56
|
+
"@uxf/data-grid": "14.0.0",
|
|
57
|
+
"@uxf/dnd": "14.0.0",
|
|
58
|
+
"@uxf/form": "14.0.0",
|
|
59
|
+
"@uxf/router": "14.0.0",
|
|
60
|
+
"@uxf/styles": "14.0.0",
|
|
61
|
+
"@uxf/ui": "14.0.0",
|
|
62
|
+
"@uxf/wysiwyg": "14.0.0",
|
|
63
63
|
"axios": "^1.20.0",
|
|
64
64
|
"axios-hooks": "^5.1.1",
|
|
65
65
|
"next": "16.3.8",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const react_1 = require("@testing-library/react");
|
|
7
|
+
const translations_1 = require("@uxf/core-react/translations");
|
|
8
|
+
const create_default_t_1 = require("@uxf/core-react/translations/create-default-t");
|
|
9
|
+
const react_2 = __importDefault(require("react"));
|
|
10
|
+
const translations_2 = __importDefault(require("../translations"));
|
|
11
|
+
const content_header_1 = require("./content-header");
|
|
12
|
+
// The real icons need @uxf/ui's provider config. IconButton names the button through the icon's aria-label,
|
|
13
|
+
// so the stand-in keeps it.
|
|
14
|
+
jest.mock("@uxf/ui/icon", () => ({
|
|
15
|
+
Icon: (props) => react_2.default.createElement("svg", { "aria-label": props["aria-label"], role: "img" }),
|
|
16
|
+
}));
|
|
17
|
+
const cs = (0, create_default_t_1.createDefaultT)(JSON.parse(JSON.stringify(translations_2.default, (_key, value) => ((value === null || value === void 0 ? void 0 : value.cs) !== undefined ? value.cs : value))));
|
|
18
|
+
test("names the delete button", () => {
|
|
19
|
+
(0, react_1.render)(react_2.default.createElement(translations_1.TranslationsProvider, { value: cs },
|
|
20
|
+
react_2.default.createElement(content_header_1.ContentHeader, { ...{ id: "1", onRemove: jest.fn(), title: "Section" } })));
|
|
21
|
+
expect(react_1.screen.getByRole("button", { name: "Smazat sekci" })).toBeTruthy();
|
|
22
|
+
});
|
|
@@ -59,7 +59,7 @@ const ContentHeader = (props) => {
|
|
|
59
59
|
return (react_1.default.createElement("div", { ...clickableProps },
|
|
60
60
|
react_1.default.createElement("h3", { className: "uxf-typo-h6" }, props.title),
|
|
61
61
|
react_1.default.createElement("div", { className: "flex items-center space-x-4" },
|
|
62
|
-
react_1.default.createElement(icon_button_1.IconButton, { iconName: "delete", label: "
|
|
62
|
+
react_1.default.createElement(icon_button_1.IconButton, { iconName: "delete", label: t("uxf-cms-pages-content-builder:components.content-header.delete-section"), onClick: removeHandler, size: "sm", variant: "secondary" }),
|
|
63
63
|
react_1.default.createElement(icon_1.Icon, { name: `${visibility ? "chevronUp" : "chevronDown"}`, size: 16 }))));
|
|
64
64
|
};
|
|
65
65
|
exports.ContentHeader = ContentHeader;
|
|
@@ -37,8 +37,8 @@ exports.DetailsVisibilityProvider = exports.useDetailsVisibilityControls = expor
|
|
|
37
37
|
const noop_1 = require("@uxf/core/utils/noop");
|
|
38
38
|
const global_context_1 = require("@uxf/core-react/global-context");
|
|
39
39
|
const react_1 = __importStar(require("react"));
|
|
40
|
-
const
|
|
41
|
-
const useDetailsVisibility = () => (0, react_1.useContext)(
|
|
40
|
+
const DetailsVisibilityContext = (0, global_context_1.createGlobalContext)("cms/content-builder/details-visibility", [[], noop_1.noop, true, noop_1.noop]);
|
|
41
|
+
const useDetailsVisibility = () => (0, react_1.useContext)(DetailsVisibilityContext);
|
|
42
42
|
const useDetailsVisibilityForSection = (sectionId) => {
|
|
43
43
|
var _a;
|
|
44
44
|
const [detailsVisibility, setDetailsVisibility, defaultVisibility] = useDetailsVisibility();
|
|
@@ -64,6 +64,6 @@ exports.useDetailsVisibilityControls = useDetailsVisibilityControls;
|
|
|
64
64
|
const DetailsVisibilityProvider = (props) => {
|
|
65
65
|
const [defaultVisibility, setDefaultVisibility] = (0, react_1.useState)(true);
|
|
66
66
|
const [detailsVisibility, setDetailsVisibility] = (0, react_1.useState)([]);
|
|
67
|
-
return (react_1.default.createElement(
|
|
67
|
+
return (react_1.default.createElement(DetailsVisibilityContext, { value: [detailsVisibility, setDetailsVisibility, defaultVisibility, setDefaultVisibility] }, props.children));
|
|
68
68
|
};
|
|
69
69
|
exports.DetailsVisibilityProvider = DetailsVisibilityProvider;
|
|
@@ -53,10 +53,10 @@ const loader_1 = require("@uxf/ui/loader");
|
|
|
53
53
|
const link_1 = __importDefault(require("next/link"));
|
|
54
54
|
const router_2 = __importStar(require("next/router"));
|
|
55
55
|
const react_1 = __importStar(require("react"));
|
|
56
|
-
const url_1 = require("url");
|
|
57
56
|
const swr_1 = require("../../api/swr");
|
|
58
57
|
const api_1 = require("../../lib/api");
|
|
59
58
|
const restricted_page_1 = require("../../security/restricted-page");
|
|
59
|
+
const history_pathname_1 = require("./history-pathname");
|
|
60
60
|
// TODO use swr
|
|
61
61
|
const { axiosRequest } = (0, api_1.createAxiosInstance)("");
|
|
62
62
|
const dataGridLoader = (gridName, request) => {
|
|
@@ -81,7 +81,7 @@ function GridPageComponent(props) {
|
|
|
81
81
|
// save filter to url
|
|
82
82
|
const newQuery = { ...query, filter: encodedRequest };
|
|
83
83
|
// TODO @vejvis - dodělat vlastní router a tuhle magii smazat!
|
|
84
|
-
router_2.default.replace(`${(0,
|
|
84
|
+
router_2.default.replace(`${(0, history_pathname_1.historyPathname)((_a = window.history.state) === null || _a === void 0 ? void 0 : _a.url)}?${(0, qs_1.stringify)(newQuery)}`, `${(0, history_pathname_1.historyPathname)((_b = window.history.state) === null || _b === void 0 ? void 0 : _b.as)}?${(0, qs_1.stringify)(newQuery)}`, { shallow: true });
|
|
85
85
|
return response;
|
|
86
86
|
}, [query]);
|
|
87
87
|
const { data, isLoading, error, reload } = (0, use_data_grid_fetching_1.useDataGridFetching)({
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The pathname of a URL kept in Next.js's `history.state` (`url` or `as`), resolved against the current page.
|
|
3
|
+
* Node's legacy `url.parse` used to do this: it is deprecated (DEP0169), dragged a `url` polyfill into the
|
|
4
|
+
* browser bundle, and for a missing URL returned `null`, which ended up in the address as "null?…".
|
|
5
|
+
*/
|
|
6
|
+
export declare function historyPathname(url: string | undefined): string;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.historyPathname = historyPathname;
|
|
4
|
+
/**
|
|
5
|
+
* The pathname of a URL kept in Next.js's `history.state` (`url` or `as`), resolved against the current page.
|
|
6
|
+
* Node's legacy `url.parse` used to do this: it is deprecated (DEP0169), dragged a `url` polyfill into the
|
|
7
|
+
* browser bundle, and for a missing URL returned `null`, which ended up in the address as "null?…".
|
|
8
|
+
*/
|
|
9
|
+
function historyPathname(url) {
|
|
10
|
+
return new URL(url !== null && url !== void 0 ? url : "", window.location.href).pathname;
|
|
11
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const history_pathname_1 = require("./history-pathname");
|
|
4
|
+
test("takes the pathname of a history-state URL", () => {
|
|
5
|
+
expect((0, history_pathname_1.historyPathname)("/cms/grid/[entity]?entity=user&filter=abc")).toBe("/cms/grid/[entity]");
|
|
6
|
+
});
|
|
7
|
+
test("falls back to the current page when history state has no URL", () => {
|
|
8
|
+
window.history.replaceState(null, "", "/cms/grid/user?x=1");
|
|
9
|
+
expect((0, history_pathname_1.historyPathname)(undefined)).toBe("/cms/grid/user");
|
|
10
|
+
expect((0, history_pathname_1.historyPathname)("")).toBe("/cms/grid/user");
|
|
11
|
+
});
|
package/pages/translations.d.ts
CHANGED
package/pages/translations.js
CHANGED
|
@@ -16,7 +16,7 @@ function ErrorContent(props) {
|
|
|
16
16
|
if (props.error.code === "UNAUTHORIZED") {
|
|
17
17
|
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
18
18
|
react_1.default.createElement("div", null, t("uxf-cms-restricted-page:login-required")),
|
|
19
|
-
react_1.default.createElement(button_1.Button, { href: `/admin/login
|
|
19
|
+
react_1.default.createElement(button_1.Button, { href: `/admin/login?${new URLSearchParams({ redirect: window.location.href })}` }, t("uxf-cms-restricted-page:login"))));
|
|
20
20
|
}
|
|
21
21
|
return react_1.default.createElement("div", null, t("uxf-cms-restricted-page:unknown-error"));
|
|
22
22
|
}
|
package/translations/cs.json
CHANGED
|
@@ -69,7 +69,8 @@
|
|
|
69
69
|
"uxf-cms-pages-content-builder": {
|
|
70
70
|
"components": {
|
|
71
71
|
"content-header": {
|
|
72
|
-
"confirm-delete-section": "Opravdu chcete smazat tuto sekci?"
|
|
72
|
+
"confirm-delete-section": "Opravdu chcete smazat tuto sekci?",
|
|
73
|
+
"delete-section": "Smazat sekci"
|
|
73
74
|
},
|
|
74
75
|
"header": {
|
|
75
76
|
"save": "Uložit"
|
|
@@ -2,27 +2,15 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.useViewportHeight = useViewportHeight;
|
|
4
4
|
const react_1 = require("react");
|
|
5
|
-
|
|
6
|
-
var _a, _b;
|
|
7
|
-
if (typeof window === "undefined") {
|
|
8
|
-
return "100vh";
|
|
9
|
-
}
|
|
10
|
-
return (_b = (_a = window.visualViewport) === null || _a === void 0 ? void 0 : _a.height) !== null && _b !== void 0 ? _b : "100vh";
|
|
11
|
-
}
|
|
5
|
+
const use_visual_viewport_height_1 = require("./use-visual-viewport-height");
|
|
12
6
|
function useViewportHeight(scrollLock) {
|
|
13
|
-
|
|
7
|
+
var _a;
|
|
14
8
|
(0, react_1.useEffect)(() => {
|
|
15
|
-
if (scrollLock) {
|
|
16
|
-
|
|
9
|
+
if (!scrollLock) {
|
|
10
|
+
return;
|
|
17
11
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
return () => {
|
|
21
|
-
if (scrollLock) {
|
|
22
|
-
document.body.classList.remove("xl:overflow-hidden");
|
|
23
|
-
}
|
|
24
|
-
window.removeEventListener("resize", handler);
|
|
25
|
-
};
|
|
12
|
+
document.body.classList.add("xl:overflow-hidden");
|
|
13
|
+
return () => document.body.classList.remove("xl:overflow-hidden");
|
|
26
14
|
}, [scrollLock]);
|
|
27
|
-
return
|
|
15
|
+
return (_a = (0, use_visual_viewport_height_1.useVisualViewportHeight)()) !== null && _a !== void 0 ? _a : "100vh";
|
|
28
16
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const react_1 = require("@testing-library/react");
|
|
4
|
+
const use_viewport_height_1 = require("./use-viewport-height");
|
|
5
|
+
class FakeVisualViewport extends EventTarget {
|
|
6
|
+
constructor() {
|
|
7
|
+
super(...arguments);
|
|
8
|
+
this.height = 700;
|
|
9
|
+
this.scale = 1;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
let visualViewport;
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
visualViewport = new FakeVisualViewport();
|
|
15
|
+
Object.defineProperty(window, "visualViewport", { configurable: true, value: visualViewport });
|
|
16
|
+
});
|
|
17
|
+
afterEach(() => {
|
|
18
|
+
Object.defineProperty(window, "visualViewport", { configurable: true, value: undefined });
|
|
19
|
+
});
|
|
20
|
+
test("follows the visual viewport, which shrinks when the on-screen keyboard opens", () => {
|
|
21
|
+
const { result } = (0, react_1.renderHook)(() => (0, use_viewport_height_1.useViewportHeight)());
|
|
22
|
+
(0, react_1.act)(() => {
|
|
23
|
+
visualViewport.height = 400;
|
|
24
|
+
// iOS fires this on the visual viewport only; window gets no resize event.
|
|
25
|
+
visualViewport.dispatchEvent(new Event("resize"));
|
|
26
|
+
});
|
|
27
|
+
expect(result.current).toBe(400);
|
|
28
|
+
});
|
|
29
|
+
test("ignores pinch zoom, which shrinks the visual viewport by the zoom scale", () => {
|
|
30
|
+
const { result } = (0, react_1.renderHook)(() => (0, use_viewport_height_1.useViewportHeight)());
|
|
31
|
+
(0, react_1.act)(() => {
|
|
32
|
+
visualViewport.scale = 2;
|
|
33
|
+
visualViewport.height = 350;
|
|
34
|
+
visualViewport.dispatchEvent(new Event("resize"));
|
|
35
|
+
});
|
|
36
|
+
expect(result.current).toBe(700);
|
|
37
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useVisualViewportHeight = useVisualViewportHeight;
|
|
4
|
+
const react_1 = require("react");
|
|
5
|
+
function subscribe(onStoreChange) {
|
|
6
|
+
var _a;
|
|
7
|
+
// The visual viewport has its own resize event: iOS fires it when the on-screen keyboard opens, and the window
|
|
8
|
+
// gets none.
|
|
9
|
+
const target = (_a = window.visualViewport) !== null && _a !== void 0 ? _a : window;
|
|
10
|
+
const controller = new AbortController();
|
|
11
|
+
target.addEventListener("resize", onStoreChange, { signal: controller.signal });
|
|
12
|
+
return () => controller.abort();
|
|
13
|
+
}
|
|
14
|
+
function getSnapshot() {
|
|
15
|
+
const viewport = window.visualViewport;
|
|
16
|
+
// Times the zoom scale: pinch zoom shrinks `height` by the scale, and the layout must not shrink with it. The
|
|
17
|
+
// on-screen keyboard shrinks it at scale 1, which is the change to follow.
|
|
18
|
+
return viewport ? viewport.height * viewport.scale : window.innerHeight;
|
|
19
|
+
}
|
|
20
|
+
/** Height of the visual viewport in px, not counting pinch zoom; `undefined` on the server and while hydrating. */
|
|
21
|
+
function useVisualViewportHeight() {
|
|
22
|
+
return (0, react_1.useSyncExternalStore)(subscribe, getSnapshot, () => undefined);
|
|
23
|
+
}
|