@gravity-ui/blog-constructor 5.14.0 → 5.16.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.
Files changed (36) hide show
  1. package/README.md +2 -2
  2. package/build/cjs/blocks/Feed/Feed.js +1 -1
  3. package/build/cjs/blocks/Header/Header.js +4 -1
  4. package/build/cjs/blocks/Meta/Meta.js +4 -1
  5. package/build/cjs/components/FeedHeader/components/Controls/Controls.css +4 -0
  6. package/build/cjs/components/FeedHeader/components/Controls/Controls.js +4 -2
  7. package/build/cjs/components/Paginator/Paginator.d.ts +1 -1
  8. package/build/cjs/components/Paginator/Paginator.js +13 -2
  9. package/build/cjs/components/Paginator/components/PaginatorItem.d.ts +1 -1
  10. package/build/cjs/components/Paginator/components/PaginatorItem.js +9 -5
  11. package/build/cjs/components/Paginator/types.d.ts +4 -1
  12. package/build/cjs/components/Paginator/utils.d.ts +1 -1
  13. package/build/cjs/components/Paginator/utils.js +2 -1
  14. package/build/cjs/components/Posts/Posts.d.ts +3 -2
  15. package/build/cjs/components/Posts/Posts.js +2 -2
  16. package/build/cjs/contexts/SettingsContext.d.ts +1 -0
  17. package/build/cjs/utils/common.d.ts +3 -4
  18. package/build/cjs/utils/common.js +9 -14
  19. package/build/esm/blocks/Feed/Feed.js +1 -1
  20. package/build/esm/blocks/Header/Header.js +5 -2
  21. package/build/esm/blocks/Meta/Meta.js +5 -2
  22. package/build/esm/components/FeedHeader/components/Controls/Controls.css +4 -0
  23. package/build/esm/components/FeedHeader/components/Controls/Controls.js +4 -2
  24. package/build/esm/components/Paginator/Paginator.d.ts +1 -1
  25. package/build/esm/components/Paginator/Paginator.js +13 -2
  26. package/build/esm/components/Paginator/components/PaginatorItem.d.ts +1 -1
  27. package/build/esm/components/Paginator/components/PaginatorItem.js +10 -6
  28. package/build/esm/components/Paginator/types.d.ts +4 -1
  29. package/build/esm/components/Paginator/utils.d.ts +1 -1
  30. package/build/esm/components/Paginator/utils.js +2 -1
  31. package/build/esm/components/Posts/Posts.d.ts +3 -2
  32. package/build/esm/components/Posts/Posts.js +2 -2
  33. package/build/esm/contexts/SettingsContext.d.ts +1 -0
  34. package/build/esm/utils/common.d.ts +3 -4
  35. package/build/esm/utils/common.js +8 -12
  36. package/package.json +2 -2
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # @gravity-ui/blog-constructor · [![npm package](https://img.shields.io/npm/v/@gravity-ui/blog-constructor)](https://www.npmjs.com/package/@gravity-ui/blog-constructor) [![CI](https://img.shields.io/github/actions/workflow/status/gravity-ui/blog-constructor/ci.yml?branch=main&label=CI)](https://github.com/gravity-ui/blog-constructor/actions/workflows/ci.yml?query=branch:main) [![CI](https://img.shields.io/github/actions/workflow/status/gravity-ui/blog-constructor/release.yml?branch=main&label=Release)](https://github.com/gravity-ui/blog-constructor/actions/workflows/release.yml?query=branch:main) [![storybook](https://img.shields.io/badge/Storybook-deployed-ff4685)](https://preview.yandexcloud.dev/blog-constructor/)
1
+ # @gravity-ui/blog-constructor · [![npm package](https://img.shields.io/npm/v/@gravity-ui/blog-constructor)](https://www.npmjs.com/package/@gravity-ui/blog-constructor) [![CI](https://img.shields.io/github/actions/workflow/status/gravity-ui/blog-constructor/ci.yml?branch=main&label=CI)](https://github.com/gravity-ui/blog-constructor/actions/workflows/ci.yml?query=branch:main) [![CI](https://img.shields.io/github/actions/workflow/status/gravity-ui/blog-constructor/release.yml?branch=main&label=Release)](https://github.com/gravity-ui/blog-constructor/actions/workflows/release.yml?query=branch:main) [![storybook](https://img.shields.io/badge/Storybook-deployed-ff4685)](https://preview.gravity-ui.com/blog-constructor/)
2
2
 
3
3
  ## Install
4
4
 
@@ -10,7 +10,7 @@ npm install @gravity-ui/blog-constructor
10
10
 
11
11
  `Blog-constructor` is a library based on the [Page-constructor](https://github.com/gravity-ui/page-constructor) library for creating blog format web pages. Blog-constructor uses the [`custom`](https://github.com/gravity-ui/page-constructor#custom-blocks) prop from page-constructor to add the components needed for the blog.
12
12
 
13
- ### Documentation - [storybook](https://preview.yandexcloud.dev/blog-constructor/)
13
+ ### Documentation - [storybook](https://preview.gravity-ui.com/blog-constructor/)
14
14
 
15
15
  ### Getting started
16
16
 
@@ -164,6 +164,6 @@ const Feed = ({ image }) => {
164
164
  url: image,
165
165
  disableCompress: true,
166
166
  } }),
167
- errorLoad ? (react_1.default.createElement(PostsError_1.PostsError, { onButtonClick: handleOnErrorReload })) : (react_1.default.createElement(Posts_1.Posts, { containerId: CONTAINER_ID, currentPage: currentPage, isShowMoreVisible: isShowMoreVisible, errorShowMore: errorShowMore, postCountOnPage: postCountOnPage, perPageInQuery: perPageInQuery, handleShowMore: handleShowMore, handlePageChange: handlePageChange, postsOnPage: postsOnPage, pinnedPostOnPage: pinnedPostOnPage, isFetching: isFetching, pageCountForShowSupportButtons: pageCountForShowSupportButtons }))));
167
+ errorLoad ? (react_1.default.createElement(PostsError_1.PostsError, { onButtonClick: handleOnErrorReload })) : (react_1.default.createElement(Posts_1.Posts, { containerId: CONTAINER_ID, currentPage: currentPage, isShowMoreVisible: isShowMoreVisible, errorShowMore: errorShowMore, postCountOnPage: postCountOnPage, perPageInQuery: perPageInQuery, handleShowMore: handleShowMore, handlePageChange: handlePageChange, postsOnPage: postsOnPage, pinnedPostOnPage: pinnedPostOnPage, isFetching: isFetching, queryParams: queryParams, pageCountForShowSupportButtons: pageCountForShowSupportButtons }))));
168
168
  };
169
169
  exports.Feed = Feed;
@@ -11,6 +11,7 @@ const LocaleContext_1 = require("../../contexts/LocaleContext");
11
11
  const PostPageContext_1 = require("../../contexts/PostPageContext");
12
12
  const paddings_1 = require("../../models/paddings");
13
13
  const common_1 = require("../../utils/common");
14
+ const SettingsContext_1 = require("../../contexts/SettingsContext");
14
15
  /**
15
16
  * @deprecated Metrika will be deleted after launch of analyticsEvents
16
17
  */
@@ -28,8 +29,10 @@ const Header = (props) => {
28
29
  const { theme, paddingTop, paddingBottom } = props;
29
30
  const { post } = (0, react_1.useContext)(PostPageContext_1.PostPageContext);
30
31
  const { locale } = (0, react_1.useContext)(LocaleContext_1.LocaleContext);
32
+ const { getBlogPath = common_1.getBlogPath } = (0, react_1.useContext)(SettingsContext_1.SettingsContext);
33
+ const blogPath = getBlogPath(locale.pathPrefix || '');
31
34
  const { description, title, id, date, readingTime, tags } = post;
32
- const breadcrumbs = (0, common_1.getBreadcrumbs)({ tags, pathPrefix: (locale === null || locale === void 0 ? void 0 : locale.pathPrefix) || '' });
35
+ const breadcrumbs = (0, common_1.getBreadcrumbs)({ tags, blogPath });
33
36
  if (theme === 'dark' && breadcrumbs) {
34
37
  breadcrumbs.theme = 'dark';
35
38
  }
@@ -8,6 +8,7 @@ const PostInfo_1 = require("../../components/PostInfo/PostInfo");
8
8
  const Wrapper_1 = require("../../components/Wrapper/Wrapper");
9
9
  const constants_1 = require("../../constants");
10
10
  const LocaleContext_1 = require("../../contexts/LocaleContext");
11
+ const SettingsContext_1 = require("../../contexts/SettingsContext");
11
12
  const PostPageContext_1 = require("../../contexts/PostPageContext");
12
13
  const paddings_1 = require("../../models/paddings");
13
14
  const cn_1 = require("../../utils/cn");
@@ -31,8 +32,10 @@ const Meta = (props) => {
31
32
  const { post } = (0, react_1.useContext)(PostPageContext_1.PostPageContext);
32
33
  const { locale } = (0, react_1.useContext)(LocaleContext_1.LocaleContext);
33
34
  const qaAttributes = (0, common_1.getQaAttributes)(qa, 'post-info');
35
+ const { getBlogPath = common_1.getBlogPath } = (0, react_1.useContext)(SettingsContext_1.SettingsContext);
36
+ const blogPath = getBlogPath(locale.pathPrefix || '');
34
37
  const { title, id, date, readingTime, tags } = post;
35
- const breadcrumbs = (0, common_1.getBreadcrumbs)({ tags, pathPrefix: (locale === null || locale === void 0 ? void 0 : locale.pathPrefix) || '' });
38
+ const breadcrumbs = (0, common_1.getBreadcrumbs)({ tags, blogPath });
36
39
  breadcrumbs.metrikaGoals = breadcrumbsGoals;
37
40
  return (react_1.default.createElement(Wrapper_1.Wrapper, { paddings: {
38
41
  [paddings_1.PaddingsDirections.top]: paddingTop,
@@ -44,6 +44,10 @@ unpredictable css rules order in build */
44
44
  border-radius: 8px;
45
45
  }
46
46
 
47
+ .bc-feed-controls__popup_isMobile.bc-feed-controls__popup_isMobile {
48
+ max-height: inherit;
49
+ }
50
+
47
51
  .bc-feed-controls__popup-filter {
48
52
  font-size: var(--g-text-body-2-font-size);
49
53
  line-height: var(--g-text-body-2-line-height);
@@ -10,6 +10,7 @@ const uikit_1 = require("@gravity-ui/uikit");
10
10
  */
11
11
  const constants_1 = require("../../../../constants");
12
12
  const LikesContext_1 = require("../../../../contexts/LikesContext");
13
+ const MobileContext_1 = require("../../../../contexts/MobileContext");
13
14
  const metrika_1 = tslib_1.__importDefault(require("../../../../counters/metrika"));
14
15
  const utils_1 = require("../../../../counters/utils");
15
16
  const i18n_1 = require("../../../../i18n");
@@ -30,6 +31,7 @@ const Controls = ({ handleLoadData, tags = [], services = [], queryParams, }) =>
30
31
  const { savedOnly: savedOnlyInitial, search: searchInitial, tags: tagInitial, services: servicesInitial, } = queryParams || {};
31
32
  const [savedOnly, setSavedOnly] = (0, react_1.useState)(savedOnlyInitial === 'true');
32
33
  const [search, setSearch] = (0, react_1.useState)(searchInitial);
34
+ const isMobile = (0, react_1.useContext)(MobileContext_1.MobileContext);
33
35
  const handleSavedOnly = () => {
34
36
  handleAnalyticsSaveOnly();
35
37
  setSavedOnly(!savedOnly);
@@ -98,13 +100,13 @@ const Controls = ({ handleLoadData, tags = [], services = [], queryParams, }) =>
98
100
  react_1.default.createElement("div", { className: b('filter-item') },
99
101
  react_1.default.createElement(Search_1.Search, { className: b('search'), placeholder: (0, i18n_1.i18)(i18n_1.Keyset.Search), initialValue: search && typeof search === 'string' ? search : '', onSubmit: handleSearch })),
100
102
  react_1.default.createElement("div", { className: b('filter-item') },
101
- react_1.default.createElement(uikit_1.Select, { className: b('select'), size: "xl", options: tagsItems, defaultValue: [tagInitial], onUpdate: handleTagSelect, placeholder: (0, i18n_1.i18)(i18n_1.Keyset.AllTags), popupClassName: b('popup'), renderControl: (0, customRenders_1.renderSwitcher)({
103
+ react_1.default.createElement(uikit_1.Select, { className: b('select'), size: "xl", options: tagsItems, defaultValue: [tagInitial], onUpdate: handleTagSelect, placeholder: (0, i18n_1.i18)(i18n_1.Keyset.AllTags), popupClassName: b('popup', { isMobile }), renderControl: (0, customRenders_1.renderSwitcher)({
102
104
  initial: [tagInitial],
103
105
  list: tagsItems,
104
106
  defaultLabel: (0, i18n_1.i18)(i18n_1.Keyset.AllTags),
105
107
  }), disablePortal: true, virtualizationThreshold: VIRTUALIZATION_THRESHOLD, renderOption: customRenders_1.renderOption })),
106
108
  services.length > 0 ? (react_1.default.createElement("div", { className: b('filter-item') },
107
- react_1.default.createElement(uikit_1.Select, { className: b('select'), size: "xl", multiple: true, filterable: true, hasClear: true, disablePortal: true, options: services, defaultValue: servicesItems, popupClassName: b('popup'), onUpdate: handleServicesSelect, placeholder: (0, i18n_1.i18)(i18n_1.Keyset.AllServices), renderControl: (0, customRenders_1.renderSwitcher)({
109
+ react_1.default.createElement(uikit_1.Select, { className: b('select'), size: "xl", multiple: true, filterable: true, hasClear: true, disablePortal: true, options: services, defaultValue: servicesItems, popupClassName: b('popup', { isMobile }), onUpdate: handleServicesSelect, placeholder: (0, i18n_1.i18)(i18n_1.Keyset.AllServices), renderControl: (0, customRenders_1.renderSwitcher)({
108
110
  initial: servicesItems,
109
111
  list: services,
110
112
  defaultLabel: (0, i18n_1.i18)(i18n_1.Keyset.AllServices),
@@ -1,3 +1,3 @@
1
1
  import React from 'react';
2
2
  import { PaginatorProps } from './types';
3
- export declare const Paginator: ({ itemsPerPage, totalItems, maxPages, page, className, onPageChange, pageCountForShowSupportButtons, }: PaginatorProps) => React.JSX.Element | null;
3
+ export declare const Paginator: ({ itemsPerPage, totalItems, maxPages, page, className, onPageChange, queryParams, pageCountForShowSupportButtons, }: PaginatorProps) => React.JSX.Element | null;
@@ -16,10 +16,14 @@ const NavigationButton_1 = require("./components/NavigationButton");
16
16
  const PaginatorItem_1 = require("./components/PaginatorItem");
17
17
  const types_1 = require("./types");
18
18
  const utils_2 = require("./utils");
19
+ const lodash_1 = tslib_1.__importDefault(require("lodash"));
19
20
  const b = (0, cn_1.block)('paginator');
20
21
  const DEFAULT_PAGE_COUNT_FOR_SHOW_SUPPORT_BUTTONS = 6;
21
- const Paginator = ({ itemsPerPage, totalItems, maxPages, page, className, onPageChange, pageCountForShowSupportButtons = DEFAULT_PAGE_COUNT_FOR_SHOW_SUPPORT_BUTTONS, }) => {
22
+ const Paginator = ({ itemsPerPage, totalItems, maxPages, page, className, onPageChange, queryParams, pageCountForShowSupportButtons = DEFAULT_PAGE_COUNT_FOR_SHOW_SUPPORT_BUTTONS, }) => {
22
23
  const [pagesCount, setPagesCount] = (0, react_1.useState)((0, utils_2.getPagesCount)({ itemsPerPage, totalItems, maxPages }));
24
+ const nonPagedQuery = (0, react_1.useMemo)(() => {
25
+ return lodash_1.default.omit(queryParams, ['page']);
26
+ }, [queryParams]);
23
27
  (0, react_1.useEffect)(() => {
24
28
  const count = (0, utils_2.getPagesCount)({ itemsPerPage, totalItems, maxPages });
25
29
  setPagesCount(count);
@@ -64,11 +68,17 @@ const Paginator = ({ itemsPerPage, totalItems, maxPages, page, className, onPage
64
68
  handlePageChange(index);
65
69
  }
66
70
  };
67
- const paginatorItems = (0, utils_2.getPageConfigs)({ page, pagesCount, handlePageClick });
71
+ const paginatorItems = (0, utils_2.getPageConfigs)({
72
+ page,
73
+ pagesCount,
74
+ queryParams: nonPagedQuery,
75
+ handlePageClick,
76
+ });
68
77
  if (page > 1 && isShowSupportButtons) {
69
78
  paginatorItems.unshift({
70
79
  key: types_1.ArrowType.Prev,
71
80
  dataKey: types_1.ArrowType.Prev,
81
+ queryParams: nonPagedQuery,
72
82
  mods: { type: types_1.ArrowType.Prev },
73
83
  onClick: handleArrowClick,
74
84
  index: 0,
@@ -78,6 +88,7 @@ const Paginator = ({ itemsPerPage, totalItems, maxPages, page, className, onPage
78
88
  if (page < pagesCount && isShowSupportButtons) {
79
89
  paginatorItems.push({
80
90
  key: types_1.ArrowType.Next,
91
+ queryParams: nonPagedQuery,
81
92
  dataKey: types_1.ArrowType.Next,
82
93
  mods: { type: types_1.ArrowType.Next },
83
94
  index: page + 1,
@@ -1,3 +1,3 @@
1
1
  import React from 'react';
2
2
  import { PaginatorItemProps } from '../types';
3
- export declare const PaginatorItem: ({ dataKey, mods, content, onClick, loading, index, }: PaginatorItemProps) => React.JSX.Element;
3
+ export declare const PaginatorItem: ({ dataKey, mods, content, queryParams, onClick, loading, index, }: PaginatorItemProps) => React.JSX.Element;
@@ -9,13 +9,17 @@ const SettingsContext_1 = require("../../../contexts/SettingsContext");
9
9
  const cn_1 = require("../../../utils/cn");
10
10
  const common_1 = require("../../../utils/common");
11
11
  const b = (0, cn_1.block)('paginator');
12
- const PaginatorItem = ({ dataKey, mods, content, onClick, loading = false, index, }) => {
12
+ const PaginatorItem = ({ dataKey, mods, content, queryParams, onClick, loading = false, index, }) => {
13
13
  const { locale } = (0, react_1.useContext)(LocaleContext_1.LocaleContext);
14
- const { addNavigationLinkForPages } = (0, react_1.useContext)(SettingsContext_1.SettingsContext);
15
- const urlPath = (0, common_1.getBlogPath)((locale === null || locale === void 0 ? void 0 : locale.pathPrefix) || '');
14
+ const { addNavigationLinkForPages, getBlogPath = common_1.getBlogPath } = (0, react_1.useContext)(SettingsContext_1.SettingsContext);
15
+ const urlPath = getBlogPath((locale === null || locale === void 0 ? void 0 : locale.pathPrefix) || '');
16
16
  const itemKey = Number(dataKey) > 0 ? Number(dataKey) : dataKey;
17
- const navTag = index > 1 ? `?page=${index}` : '';
18
- const navigationLink = `${urlPath || ''}${navTag}`;
17
+ const navigationLink = (0, react_1.useMemo)(() => {
18
+ const queryString = Object.entries(Object.assign(Object.assign({}, (index > 1 ? { page: index } : undefined)), queryParams))
19
+ .map(([param, value]) => `${param}=${value}`)
20
+ .join('&');
21
+ return queryString ? `${urlPath}?${queryString}` : urlPath;
22
+ }, [queryParams, index, urlPath]);
19
23
  const renderButton = (react_1.default.createElement(uikit_1.Button, { view: "flat", size: "xl", className: b('item', mods), onClick: () => onClick === null || onClick === void 0 ? void 0 : onClick(itemKey), loading: loading && Boolean(mods.active) }, content));
20
24
  return (react_1.default.createElement(react_1.Fragment, null, addNavigationLinkForPages ? (react_1.default.createElement("a", { href: navigationLink, className: b('link'), onClick: (event) => event.preventDefault() }, renderButton)) : (react_1.default.createElement(react_1.Fragment, null, renderButton))));
21
25
  };
@@ -1,11 +1,12 @@
1
1
  import type { ReactNode } from 'react';
2
2
  import type { NoStrictEntityMods } from '@bem-react/classname';
3
- import type { ClassNameProps } from '../../models/common';
3
+ import type { ClassNameProps, Query } from '../../models/common';
4
4
  export interface PaginatorItemProps {
5
5
  key: string | ArrowType;
6
6
  dataKey: string | ArrowType;
7
7
  mods: NoStrictEntityMods;
8
8
  content: ReactNode;
9
+ queryParams: Query;
9
10
  onClick?: (key: number | ArrowType) => void;
10
11
  loading?: boolean;
11
12
  index: number;
@@ -17,6 +18,7 @@ export type PaginatorProps = {
17
18
  maxPages: number;
18
19
  onPageChange: (page: number) => void;
19
20
  pageCountForShowSupportButtons?: number;
21
+ queryParams: Query;
20
22
  } & ClassNameProps;
21
23
  export declare enum ArrowType {
22
24
  Prev = "prev",
@@ -25,5 +27,6 @@ export declare enum ArrowType {
25
27
  export type GetPageConfigParams = {
26
28
  page: number;
27
29
  pagesCount: number;
30
+ queryParams: Query;
28
31
  handlePageClick: (key: number | ArrowType) => void;
29
32
  };
@@ -1,3 +1,3 @@
1
1
  import { GetPageConfigParams, PaginatorItemProps, PaginatorProps } from './types';
2
- export declare const getPageConfigs: ({ page, pagesCount, handlePageClick }: GetPageConfigParams) => PaginatorItemProps[];
2
+ export declare const getPageConfigs: ({ page, queryParams, pagesCount, handlePageClick, }: GetPageConfigParams) => PaginatorItemProps[];
3
3
  export declare const getPagesCount: (props: Pick<PaginatorProps, 'totalItems' | 'itemsPerPage' | 'maxPages'>) => number;
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getPagesCount = exports.getPageConfigs = void 0;
4
4
  const MAX_VISIBLE_PAGES = 5;
5
- const getPageConfigs = ({ page, pagesCount, handlePageClick }) => {
5
+ const getPageConfigs = ({ page, queryParams, pagesCount, handlePageClick, }) => {
6
6
  const paginatorItems = [];
7
7
  // it is calculating the middle of visible pages below
8
8
  const pageOffset = (MAX_VISIBLE_PAGES - 1) / 2;
@@ -19,6 +19,7 @@ const getPageConfigs = ({ page, pagesCount, handlePageClick }) => {
19
19
  dataKey: String(i),
20
20
  index: i,
21
21
  mods: { type: 'page', active: page === i },
22
+ queryParams,
22
23
  onClick: handlePageClick,
23
24
  content: i,
24
25
  });
@@ -1,5 +1,5 @@
1
1
  import React, { MouseEvent } from 'react';
2
- import { PostData } from '../../models/common';
2
+ import { PostData, Query } from '../../models/common';
3
3
  type PostCardProps = {
4
4
  containerId: string;
5
5
  currentPage: number;
@@ -13,6 +13,7 @@ type PostCardProps = {
13
13
  postsOnPage?: PostData[];
14
14
  pinnedPostOnPage?: PostData;
15
15
  pageCountForShowSupportButtons?: number;
16
+ queryParams: Query;
16
17
  };
17
- export declare const Posts: ({ containerId, pinnedPostOnPage, currentPage, postsOnPage, isShowMoreVisible, errorShowMore, postCountOnPage, perPageInQuery, isFetching, handleShowMore, handlePageChange, pageCountForShowSupportButtons, }: PostCardProps) => React.JSX.Element;
18
+ export declare const Posts: ({ containerId, pinnedPostOnPage, currentPage, postsOnPage, isShowMoreVisible, errorShowMore, postCountOnPage, perPageInQuery, isFetching, handleShowMore, handlePageChange, pageCountForShowSupportButtons, queryParams, }: PostCardProps) => React.JSX.Element;
18
19
  export {};
@@ -12,7 +12,7 @@ const Paginator_1 = require("../Paginator/Paginator");
12
12
  const PostCard_1 = require("../PostCard/PostCard");
13
13
  const PostsEmpty_1 = require("../PostsEmpty/PostsEmpty");
14
14
  const b = (0, cn_1.block)('posts');
15
- const Posts = ({ containerId, pinnedPostOnPage, currentPage, postsOnPage, isShowMoreVisible, errorShowMore, postCountOnPage, perPageInQuery, isFetching, handleShowMore, handlePageChange, pageCountForShowSupportButtons, }) => (react_1.default.createElement("div", { className: b() },
15
+ const Posts = ({ containerId, pinnedPostOnPage, currentPage, postsOnPage, isShowMoreVisible, errorShowMore, postCountOnPage, perPageInQuery, isFetching, handleShowMore, handlePageChange, pageCountForShowSupportButtons, queryParams, }) => (react_1.default.createElement("div", { className: b() },
16
16
  isFetching && react_1.default.createElement("div", { className: b('loaderContainer') }),
17
17
  react_1.default.createElement("div", { id: containerId, className: b('cards-container', { isLoading: isFetching }) },
18
18
  pinnedPostOnPage && currentPage === 1 && (react_1.default.createElement("div", { className: b('pinned-container') },
@@ -30,5 +30,5 @@ const Posts = ({ containerId, pinnedPostOnPage, currentPage, postsOnPage, isShow
30
30
  react_1.default.createElement("div", null, (0, i18n_1.i18)(i18n_1.Keyset.ErrorTitle)),
31
31
  react_1.default.createElement("div", null, (0, i18n_1.i18)(i18n_1.Keyset.PostLoadError)))),
32
32
  Boolean(currentPage && postCountOnPage) && (react_1.default.createElement("div", { className: b('paginator') },
33
- react_1.default.createElement(Paginator_1.Paginator, { onPageChange: handlePageChange, page: currentPage, totalItems: postCountOnPage, itemsPerPage: perPageInQuery, maxPages: Infinity, pageCountForShowSupportButtons: pageCountForShowSupportButtons }))))));
33
+ react_1.default.createElement(Paginator_1.Paginator, { onPageChange: handlePageChange, page: currentPage, totalItems: postCountOnPage, itemsPerPage: perPageInQuery, maxPages: Infinity, pageCountForShowSupportButtons: pageCountForShowSupportButtons, queryParams: queryParams }))))));
34
34
  exports.Posts = Posts;
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  export interface SettingsContextProps {
3
3
  addNavigationLinkForPages?: boolean;
4
+ getBlogPath?: (pathPrefix: string) => string;
4
5
  }
5
6
  export declare const SettingsContext: React.Context<SettingsContextProps>;
@@ -13,9 +13,8 @@ export declare function getAbsolutePath(router: RouterContextProps, url?: string
13
13
  export declare const getPageSearchParams: (query?: Query) => URLSearchParams;
14
14
  export declare const scrollToHash: (hash: string, browser?: string) => void;
15
15
  type CloudListTagStub = {};
16
- export declare const getTags: ((tags: Tag[], prefix?: string) => CloudListTagStub[]) & import("lodash").MemoizedFunction;
16
+ export declare const getTags: ((tags: Tag[], blogPath: string) => CloudListTagStub[]) & import("lodash").MemoizedFunction;
17
17
  export declare const postLikeStatus: import("lodash").DebouncedFunc<(postId: number, hasUserLike: boolean) => void>;
18
- export declare const getTagFilterUrl: (tagId: string | number, prefix: string) => string;
19
18
  export declare const updateContentSizes: ({ size, colSizes, theme, ...contentData }: ContentBlockProps) => {
20
19
  size: import("@gravity-ui/page-constructor").ContentSize;
21
20
  colSizes: {
@@ -35,10 +34,10 @@ export declare const updateContentSizes: ({ size, colSizes, theme, ...contentDat
35
34
  };
36
35
  type GetBreadcrumbsProps = {
37
36
  tags?: Tag[];
38
- pathPrefix?: string;
37
+ blogPath: string;
39
38
  };
40
39
  export declare const getBlogPath: (pathPrefix: string) => string;
41
- export declare const getBreadcrumbs: ({ tags, pathPrefix }: GetBreadcrumbsProps) => HeaderBreadCrumbsProps;
40
+ export declare const getBreadcrumbs: ({ tags, blogPath }: GetBreadcrumbsProps) => HeaderBreadCrumbsProps;
42
41
  export declare const isMetrikaExist: (goal: NewMetrikaGoal, existGoals: NewMetrikaGoal[]) => boolean;
43
42
  export declare const getBlogElementMetrika: (blogCustomGoal: NewMetrikaGoal, existingGoals?: MetrikaGoal) => string | string[] | NewMetrikaGoal[];
44
43
  export declare const getFeedQueryParams: (queryString: Query, pageNumber?: number) => GetPostsRequest;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getQaAttributes = exports.scrollOnPageChange = exports.getFeedQueryParams = exports.getBlogElementMetrika = exports.isMetrikaExist = exports.getBreadcrumbs = exports.getBlogPath = exports.updateContentSizes = exports.getTagFilterUrl = exports.postLikeStatus = exports.getTags = exports.scrollToHash = exports.getPageSearchParams = exports.getAbsolutePath = void 0;
3
+ exports.getQaAttributes = exports.scrollOnPageChange = exports.getFeedQueryParams = exports.getBlogElementMetrika = exports.isMetrikaExist = exports.getBreadcrumbs = exports.getBlogPath = exports.updateContentSizes = exports.postLikeStatus = exports.getTags = exports.scrollToHash = exports.getPageSearchParams = exports.getAbsolutePath = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const url_1 = require("url");
6
6
  const page_constructor_1 = require("@gravity-ui/page-constructor");
@@ -38,43 +38,38 @@ const scrollToHash = (hash, browser) => {
38
38
  setTimeout(() => element.scrollIntoView({ behavior: browser === 'Yandex' ? 'auto' : 'smooth' }), 0);
39
39
  };
40
40
  exports.scrollToHash = scrollToHash;
41
- exports.getTags = (0, memoize_1.default)((tags, prefix) => {
41
+ exports.getTags = (0, memoize_1.default)((tags, blogPath) => {
42
42
  return tags.map((_a) => {
43
43
  var { slug } = _a, tag = tslib_1.__rest(_a, ["slug"]);
44
44
  const queryParams = new URLSearchParams();
45
45
  queryParams.set('tags', slug);
46
- return Object.assign(Object.assign({}, tag), { id: slug, url: `${prefix}blog?${queryParams}` });
46
+ return Object.assign(Object.assign({}, tag), { id: slug, url: `${blogPath}?${queryParams}` });
47
47
  });
48
48
  });
49
49
  const stub = (postId) => postId;
50
50
  exports.postLikeStatus = (0, debounce_1.default)((postId, hasUserLike) => {
51
51
  (hasUserLike ? stub : stub)(postId);
52
52
  }, 300);
53
- const getTagFilterUrl = (tagId, prefix) => {
54
- return `${prefix}blog?tags=` + tagId;
55
- };
56
- exports.getTagFilterUrl = getTagFilterUrl;
57
53
  const updateContentSizes = (_a) => {
58
54
  var { size, colSizes, theme } = _a, contentData = tslib_1.__rest(_a, ["size", "colSizes", "theme"]);
59
55
  return (Object.assign(Object.assign({}, contentData), { size: size || constants_1.CONTENT_DEFAULT_SIZE, colSizes: colSizes || constants_1.CONTENT_DEFAULT_COL_SIZES, theme: theme || constants_1.CONTENT_DEFAULT_THEME }));
60
56
  };
61
57
  exports.updateContentSizes = updateContentSizes;
62
58
  const getBlogPath = (pathPrefix) => {
63
- const prefix = pathPrefix ? `/${pathPrefix}/` : '/';
64
- return `${prefix}blog`;
59
+ const prefix = pathPrefix ? `/${pathPrefix}` : '';
60
+ return `${prefix}/blog`;
65
61
  };
66
62
  exports.getBlogPath = getBlogPath;
67
- const getBreadcrumbs = ({ tags, pathPrefix }) => {
68
- const prefix = pathPrefix ? `/${pathPrefix}/` : '/';
63
+ const getBreadcrumbs = ({ tags, blogPath }) => {
69
64
  const breadcrumbs = {
70
- items: [{ text: (0, i18n_1.i18)(i18n_1.Keyset.TitleBreadcrumbs), url: `${prefix}blog` }],
65
+ items: [{ text: (0, i18n_1.i18)(i18n_1.Keyset.TitleBreadcrumbs), url: blogPath }],
71
66
  theme: 'light',
72
67
  };
73
68
  if (tags === null || tags === void 0 ? void 0 : tags.length) {
74
- const localizedTags = (0, exports.getTags)(tags, prefix);
69
+ const localizedTags = (0, exports.getTags)(tags, blogPath);
75
70
  const tag = localizedTags[0];
76
71
  // @ts-ignore todo fix
77
- breadcrumbs.items.push({ text: tag.name, url: (0, exports.getTagFilterUrl)(tag.id, prefix) });
72
+ breadcrumbs.items.push({ text: tag.name, url: tag.url });
78
73
  }
79
74
  return breadcrumbs;
80
75
  };
@@ -160,5 +160,5 @@ export const Feed = ({ image }) => {
160
160
  url: image,
161
161
  disableCompress: true,
162
162
  } }),
163
- errorLoad ? (React.createElement(PostsError, { onButtonClick: handleOnErrorReload })) : (React.createElement(Posts, { containerId: CONTAINER_ID, currentPage: currentPage, isShowMoreVisible: isShowMoreVisible, errorShowMore: errorShowMore, postCountOnPage: postCountOnPage, perPageInQuery: perPageInQuery, handleShowMore: handleShowMore, handlePageChange: handlePageChange, postsOnPage: postsOnPage, pinnedPostOnPage: pinnedPostOnPage, isFetching: isFetching, pageCountForShowSupportButtons: pageCountForShowSupportButtons }))));
163
+ errorLoad ? (React.createElement(PostsError, { onButtonClick: handleOnErrorReload })) : (React.createElement(Posts, { containerId: CONTAINER_ID, currentPage: currentPage, isShowMoreVisible: isShowMoreVisible, errorShowMore: errorShowMore, postCountOnPage: postCountOnPage, perPageInQuery: perPageInQuery, handleShowMore: handleShowMore, handlePageChange: handlePageChange, postsOnPage: postsOnPage, pinnedPostOnPage: pinnedPostOnPage, isFetching: isFetching, queryParams: queryParams, pageCountForShowSupportButtons: pageCountForShowSupportButtons }))));
164
164
  };
@@ -6,7 +6,8 @@ import { BlogMetrikaGoalIds } from '../../constants';
6
6
  import { LocaleContext } from '../../contexts/LocaleContext';
7
7
  import { PostPageContext } from '../../contexts/PostPageContext';
8
8
  import { PaddingsDirections } from '../../models/paddings';
9
- import { getBreadcrumbs } from '../../utils/common';
9
+ import { getBreadcrumbs, getBlogPath as getDefaultBlogPath } from '../../utils/common';
10
+ import { SettingsContext } from '../../contexts/SettingsContext';
10
11
  /**
11
12
  * @deprecated Metrika will be deleted after launch of analyticsEvents
12
13
  */
@@ -24,8 +25,10 @@ export const Header = (props) => {
24
25
  const { theme, paddingTop, paddingBottom } = props;
25
26
  const { post } = useContext(PostPageContext);
26
27
  const { locale } = useContext(LocaleContext);
28
+ const { getBlogPath = getDefaultBlogPath } = useContext(SettingsContext);
29
+ const blogPath = getBlogPath(locale.pathPrefix || '');
27
30
  const { description, title, id, date, readingTime, tags } = post;
28
- const breadcrumbs = getBreadcrumbs({ tags, pathPrefix: (locale === null || locale === void 0 ? void 0 : locale.pathPrefix) || '' });
31
+ const breadcrumbs = getBreadcrumbs({ tags, blogPath });
29
32
  if (theme === 'dark' && breadcrumbs) {
30
33
  breadcrumbs.theme = 'dark';
31
34
  }
@@ -4,10 +4,11 @@ import { PostInfo } from '../../components/PostInfo/PostInfo';
4
4
  import { Wrapper } from '../../components/Wrapper/Wrapper';
5
5
  import { BlogMetrikaGoalIds } from '../../constants';
6
6
  import { LocaleContext } from '../../contexts/LocaleContext';
7
+ import { SettingsContext } from '../../contexts/SettingsContext';
7
8
  import { PostPageContext } from '../../contexts/PostPageContext';
8
9
  import { PaddingsDirections } from '../../models/paddings';
9
10
  import { block } from '../../utils/cn';
10
- import { getBreadcrumbs, getQaAttributes } from '../../utils/common';
11
+ import { getBreadcrumbs, getBlogPath as getDefaultBlogPath, getQaAttributes, } from '../../utils/common';
11
12
  import './Meta.css';
12
13
  const b = block('meta');
13
14
  /**
@@ -28,8 +29,10 @@ export const Meta = (props) => {
28
29
  const { post } = useContext(PostPageContext);
29
30
  const { locale } = useContext(LocaleContext);
30
31
  const qaAttributes = getQaAttributes(qa, 'post-info');
32
+ const { getBlogPath = getDefaultBlogPath } = useContext(SettingsContext);
33
+ const blogPath = getBlogPath(locale.pathPrefix || '');
31
34
  const { title, id, date, readingTime, tags } = post;
32
- const breadcrumbs = getBreadcrumbs({ tags, pathPrefix: (locale === null || locale === void 0 ? void 0 : locale.pathPrefix) || '' });
35
+ const breadcrumbs = getBreadcrumbs({ tags, blogPath });
33
36
  breadcrumbs.metrikaGoals = breadcrumbsGoals;
34
37
  return (React.createElement(Wrapper, { paddings: {
35
38
  [PaddingsDirections.top]: paddingTop,
@@ -44,6 +44,10 @@ unpredictable css rules order in build */
44
44
  border-radius: 8px;
45
45
  }
46
46
 
47
+ .bc-feed-controls__popup_isMobile.bc-feed-controls__popup_isMobile {
48
+ max-height: inherit;
49
+ }
50
+
47
51
  .bc-feed-controls__popup-filter {
48
52
  font-size: var(--g-text-body-2-font-size);
49
53
  line-height: var(--g-text-body-2-line-height);
@@ -6,6 +6,7 @@ import { Button, Icon, Select } from '@gravity-ui/uikit';
6
6
  */
7
7
  import { BlogMetrikaGoalIds } from '../../../../constants';
8
8
  import { LikesContext } from '../../../../contexts/LikesContext';
9
+ import { MobileContext } from '../../../../contexts/MobileContext';
9
10
  import metrika from '../../../../counters/metrika';
10
11
  import { MetrikaCounter } from '../../../../counters/utils';
11
12
  import { Keyset, i18 } from '../../../../i18n';
@@ -27,6 +28,7 @@ export const Controls = ({ handleLoadData, tags = [], services = [], queryParams
27
28
  const { savedOnly: savedOnlyInitial, search: searchInitial, tags: tagInitial, services: servicesInitial, } = queryParams || {};
28
29
  const [savedOnly, setSavedOnly] = useState(savedOnlyInitial === 'true');
29
30
  const [search, setSearch] = useState(searchInitial);
31
+ const isMobile = useContext(MobileContext);
30
32
  const handleSavedOnly = () => {
31
33
  handleAnalyticsSaveOnly();
32
34
  setSavedOnly(!savedOnly);
@@ -95,13 +97,13 @@ export const Controls = ({ handleLoadData, tags = [], services = [], queryParams
95
97
  React.createElement("div", { className: b('filter-item') },
96
98
  React.createElement(Search, { className: b('search'), placeholder: i18(Keyset.Search), initialValue: search && typeof search === 'string' ? search : '', onSubmit: handleSearch })),
97
99
  React.createElement("div", { className: b('filter-item') },
98
- React.createElement(Select, { className: b('select'), size: "xl", options: tagsItems, defaultValue: [tagInitial], onUpdate: handleTagSelect, placeholder: i18(Keyset.AllTags), popupClassName: b('popup'), renderControl: renderSwitcher({
100
+ React.createElement(Select, { className: b('select'), size: "xl", options: tagsItems, defaultValue: [tagInitial], onUpdate: handleTagSelect, placeholder: i18(Keyset.AllTags), popupClassName: b('popup', { isMobile }), renderControl: renderSwitcher({
99
101
  initial: [tagInitial],
100
102
  list: tagsItems,
101
103
  defaultLabel: i18(Keyset.AllTags),
102
104
  }), disablePortal: true, virtualizationThreshold: VIRTUALIZATION_THRESHOLD, renderOption: renderOption })),
103
105
  services.length > 0 ? (React.createElement("div", { className: b('filter-item') },
104
- React.createElement(Select, { className: b('select'), size: "xl", multiple: true, filterable: true, hasClear: true, disablePortal: true, options: services, defaultValue: servicesItems, popupClassName: b('popup'), onUpdate: handleServicesSelect, placeholder: i18(Keyset.AllServices), renderControl: renderSwitcher({
106
+ React.createElement(Select, { className: b('select'), size: "xl", multiple: true, filterable: true, hasClear: true, disablePortal: true, options: services, defaultValue: servicesItems, popupClassName: b('popup', { isMobile }), onUpdate: handleServicesSelect, placeholder: i18(Keyset.AllServices), renderControl: renderSwitcher({
105
107
  initial: servicesItems,
106
108
  list: services,
107
109
  defaultLabel: i18(Keyset.AllServices),
@@ -1,4 +1,4 @@
1
1
  import React from 'react';
2
2
  import { PaginatorProps } from './types';
3
3
  import './Paginator.css';
4
- export declare const Paginator: ({ itemsPerPage, totalItems, maxPages, page, className, onPageChange, pageCountForShowSupportButtons, }: PaginatorProps) => React.JSX.Element | null;
4
+ export declare const Paginator: ({ itemsPerPage, totalItems, maxPages, page, className, onPageChange, queryParams, pageCountForShowSupportButtons, }: PaginatorProps) => React.JSX.Element | null;
@@ -13,11 +13,15 @@ import { NavigationButton } from './components/NavigationButton';
13
13
  import { PaginatorItem } from './components/PaginatorItem';
14
14
  import { ArrowType } from './types';
15
15
  import { getPageConfigs, getPagesCount } from './utils';
16
+ import _ from 'lodash';
16
17
  import './Paginator.css';
17
18
  const b = block('paginator');
18
19
  const DEFAULT_PAGE_COUNT_FOR_SHOW_SUPPORT_BUTTONS = 6;
19
- export const Paginator = ({ itemsPerPage, totalItems, maxPages, page, className, onPageChange, pageCountForShowSupportButtons = DEFAULT_PAGE_COUNT_FOR_SHOW_SUPPORT_BUTTONS, }) => {
20
+ export const Paginator = ({ itemsPerPage, totalItems, maxPages, page, className, onPageChange, queryParams, pageCountForShowSupportButtons = DEFAULT_PAGE_COUNT_FOR_SHOW_SUPPORT_BUTTONS, }) => {
20
21
  const [pagesCount, setPagesCount] = useState(getPagesCount({ itemsPerPage, totalItems, maxPages }));
22
+ const nonPagedQuery = useMemo(() => {
23
+ return _.omit(queryParams, ['page']);
24
+ }, [queryParams]);
21
25
  useEffect(() => {
22
26
  const count = getPagesCount({ itemsPerPage, totalItems, maxPages });
23
27
  setPagesCount(count);
@@ -62,11 +66,17 @@ export const Paginator = ({ itemsPerPage, totalItems, maxPages, page, className,
62
66
  handlePageChange(index);
63
67
  }
64
68
  };
65
- const paginatorItems = getPageConfigs({ page, pagesCount, handlePageClick });
69
+ const paginatorItems = getPageConfigs({
70
+ page,
71
+ pagesCount,
72
+ queryParams: nonPagedQuery,
73
+ handlePageClick,
74
+ });
66
75
  if (page > 1 && isShowSupportButtons) {
67
76
  paginatorItems.unshift({
68
77
  key: ArrowType.Prev,
69
78
  dataKey: ArrowType.Prev,
79
+ queryParams: nonPagedQuery,
70
80
  mods: { type: ArrowType.Prev },
71
81
  onClick: handleArrowClick,
72
82
  index: 0,
@@ -76,6 +86,7 @@ export const Paginator = ({ itemsPerPage, totalItems, maxPages, page, className,
76
86
  if (page < pagesCount && isShowSupportButtons) {
77
87
  paginatorItems.push({
78
88
  key: ArrowType.Next,
89
+ queryParams: nonPagedQuery,
79
90
  dataKey: ArrowType.Next,
80
91
  mods: { type: ArrowType.Next },
81
92
  index: page + 1,
@@ -1,4 +1,4 @@
1
1
  import React from 'react';
2
2
  import { PaginatorItemProps } from '../types';
3
3
  import '../Paginator.css';
4
- export declare const PaginatorItem: ({ dataKey, mods, content, onClick, loading, index, }: PaginatorItemProps) => React.JSX.Element;
4
+ export declare const PaginatorItem: ({ dataKey, mods, content, queryParams, onClick, loading, index, }: PaginatorItemProps) => React.JSX.Element;
@@ -1,18 +1,22 @@
1
- import React, { Fragment, useContext } from 'react';
1
+ import React, { Fragment, useContext, useMemo } from 'react';
2
2
  import { Button } from '@gravity-ui/uikit';
3
3
  import { LocaleContext } from '../../../contexts/LocaleContext';
4
4
  import { SettingsContext } from '../../../contexts/SettingsContext';
5
5
  import { block } from '../../../utils/cn';
6
- import { getBlogPath } from '../../../utils/common';
6
+ import { getBlogPath as getDefaultBlogPath } from '../../../utils/common';
7
7
  import '../Paginator.css';
8
8
  const b = block('paginator');
9
- export const PaginatorItem = ({ dataKey, mods, content, onClick, loading = false, index, }) => {
9
+ export const PaginatorItem = ({ dataKey, mods, content, queryParams, onClick, loading = false, index, }) => {
10
10
  const { locale } = useContext(LocaleContext);
11
- const { addNavigationLinkForPages } = useContext(SettingsContext);
11
+ const { addNavigationLinkForPages, getBlogPath = getDefaultBlogPath } = useContext(SettingsContext);
12
12
  const urlPath = getBlogPath((locale === null || locale === void 0 ? void 0 : locale.pathPrefix) || '');
13
13
  const itemKey = Number(dataKey) > 0 ? Number(dataKey) : dataKey;
14
- const navTag = index > 1 ? `?page=${index}` : '';
15
- const navigationLink = `${urlPath || ''}${navTag}`;
14
+ const navigationLink = useMemo(() => {
15
+ const queryString = Object.entries(Object.assign(Object.assign({}, (index > 1 ? { page: index } : undefined)), queryParams))
16
+ .map(([param, value]) => `${param}=${value}`)
17
+ .join('&');
18
+ return queryString ? `${urlPath}?${queryString}` : urlPath;
19
+ }, [queryParams, index, urlPath]);
16
20
  const renderButton = (React.createElement(Button, { view: "flat", size: "xl", className: b('item', mods), onClick: () => onClick === null || onClick === void 0 ? void 0 : onClick(itemKey), loading: loading && Boolean(mods.active) }, content));
17
21
  return (React.createElement(Fragment, null, addNavigationLinkForPages ? (React.createElement("a", { href: navigationLink, className: b('link'), onClick: (event) => event.preventDefault() }, renderButton)) : (React.createElement(Fragment, null, renderButton))));
18
22
  };
@@ -1,11 +1,12 @@
1
1
  import type { ReactNode } from 'react';
2
2
  import type { NoStrictEntityMods } from '@bem-react/classname';
3
- import type { ClassNameProps } from '../../models/common';
3
+ import type { ClassNameProps, Query } from '../../models/common';
4
4
  export interface PaginatorItemProps {
5
5
  key: string | ArrowType;
6
6
  dataKey: string | ArrowType;
7
7
  mods: NoStrictEntityMods;
8
8
  content: ReactNode;
9
+ queryParams: Query;
9
10
  onClick?: (key: number | ArrowType) => void;
10
11
  loading?: boolean;
11
12
  index: number;
@@ -17,6 +18,7 @@ export type PaginatorProps = {
17
18
  maxPages: number;
18
19
  onPageChange: (page: number) => void;
19
20
  pageCountForShowSupportButtons?: number;
21
+ queryParams: Query;
20
22
  } & ClassNameProps;
21
23
  export declare enum ArrowType {
22
24
  Prev = "prev",
@@ -25,5 +27,6 @@ export declare enum ArrowType {
25
27
  export type GetPageConfigParams = {
26
28
  page: number;
27
29
  pagesCount: number;
30
+ queryParams: Query;
28
31
  handlePageClick: (key: number | ArrowType) => void;
29
32
  };
@@ -1,3 +1,3 @@
1
1
  import { GetPageConfigParams, PaginatorItemProps, PaginatorProps } from './types';
2
- export declare const getPageConfigs: ({ page, pagesCount, handlePageClick }: GetPageConfigParams) => PaginatorItemProps[];
2
+ export declare const getPageConfigs: ({ page, queryParams, pagesCount, handlePageClick, }: GetPageConfigParams) => PaginatorItemProps[];
3
3
  export declare const getPagesCount: (props: Pick<PaginatorProps, 'totalItems' | 'itemsPerPage' | 'maxPages'>) => number;
@@ -1,5 +1,5 @@
1
1
  const MAX_VISIBLE_PAGES = 5;
2
- export const getPageConfigs = ({ page, pagesCount, handlePageClick }) => {
2
+ export const getPageConfigs = ({ page, queryParams, pagesCount, handlePageClick, }) => {
3
3
  const paginatorItems = [];
4
4
  // it is calculating the middle of visible pages below
5
5
  const pageOffset = (MAX_VISIBLE_PAGES - 1) / 2;
@@ -16,6 +16,7 @@ export const getPageConfigs = ({ page, pagesCount, handlePageClick }) => {
16
16
  dataKey: String(i),
17
17
  index: i,
18
18
  mods: { type: 'page', active: page === i },
19
+ queryParams,
19
20
  onClick: handlePageClick,
20
21
  content: i,
21
22
  });
@@ -1,5 +1,5 @@
1
1
  import React, { MouseEvent } from 'react';
2
- import { PostData } from '../../models/common';
2
+ import { PostData, Query } from '../../models/common';
3
3
  import './Posts.css';
4
4
  type PostCardProps = {
5
5
  containerId: string;
@@ -14,6 +14,7 @@ type PostCardProps = {
14
14
  postsOnPage?: PostData[];
15
15
  pinnedPostOnPage?: PostData;
16
16
  pageCountForShowSupportButtons?: number;
17
+ queryParams: Query;
17
18
  };
18
- export declare const Posts: ({ containerId, pinnedPostOnPage, currentPage, postsOnPage, isShowMoreVisible, errorShowMore, postCountOnPage, perPageInQuery, isFetching, handleShowMore, handlePageChange, pageCountForShowSupportButtons, }: PostCardProps) => React.JSX.Element;
19
+ export declare const Posts: ({ containerId, pinnedPostOnPage, currentPage, postsOnPage, isShowMoreVisible, errorShowMore, postCountOnPage, perPageInQuery, isFetching, handleShowMore, handlePageChange, pageCountForShowSupportButtons, queryParams, }: PostCardProps) => React.JSX.Element;
19
20
  export {};
@@ -9,7 +9,7 @@ import { PostCard } from '../PostCard/PostCard';
9
9
  import { PostsEmpty } from '../PostsEmpty/PostsEmpty';
10
10
  import './Posts.css';
11
11
  const b = block('posts');
12
- export const Posts = ({ containerId, pinnedPostOnPage, currentPage, postsOnPage, isShowMoreVisible, errorShowMore, postCountOnPage, perPageInQuery, isFetching, handleShowMore, handlePageChange, pageCountForShowSupportButtons, }) => (React.createElement("div", { className: b() },
12
+ export const Posts = ({ containerId, pinnedPostOnPage, currentPage, postsOnPage, isShowMoreVisible, errorShowMore, postCountOnPage, perPageInQuery, isFetching, handleShowMore, handlePageChange, pageCountForShowSupportButtons, queryParams, }) => (React.createElement("div", { className: b() },
13
13
  isFetching && React.createElement("div", { className: b('loaderContainer') }),
14
14
  React.createElement("div", { id: containerId, className: b('cards-container', { isLoading: isFetching }) },
15
15
  pinnedPostOnPage && currentPage === 1 && (React.createElement("div", { className: b('pinned-container') },
@@ -27,4 +27,4 @@ export const Posts = ({ containerId, pinnedPostOnPage, currentPage, postsOnPage,
27
27
  React.createElement("div", null, i18(Keyset.ErrorTitle)),
28
28
  React.createElement("div", null, i18(Keyset.PostLoadError)))),
29
29
  Boolean(currentPage && postCountOnPage) && (React.createElement("div", { className: b('paginator') },
30
- React.createElement(Paginator, { onPageChange: handlePageChange, page: currentPage, totalItems: postCountOnPage, itemsPerPage: perPageInQuery, maxPages: Infinity, pageCountForShowSupportButtons: pageCountForShowSupportButtons }))))));
30
+ React.createElement(Paginator, { onPageChange: handlePageChange, page: currentPage, totalItems: postCountOnPage, itemsPerPage: perPageInQuery, maxPages: Infinity, pageCountForShowSupportButtons: pageCountForShowSupportButtons, queryParams: queryParams }))))));
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  export interface SettingsContextProps {
3
3
  addNavigationLinkForPages?: boolean;
4
+ getBlogPath?: (pathPrefix: string) => string;
4
5
  }
5
6
  export declare const SettingsContext: React.Context<SettingsContextProps>;
@@ -13,9 +13,8 @@ export declare function getAbsolutePath(router: RouterContextProps, url?: string
13
13
  export declare const getPageSearchParams: (query?: Query) => URLSearchParams;
14
14
  export declare const scrollToHash: (hash: string, browser?: string) => void;
15
15
  type CloudListTagStub = {};
16
- export declare const getTags: ((tags: Tag[], prefix?: string) => CloudListTagStub[]) & import("lodash").MemoizedFunction;
16
+ export declare const getTags: ((tags: Tag[], blogPath: string) => CloudListTagStub[]) & import("lodash").MemoizedFunction;
17
17
  export declare const postLikeStatus: import("lodash").DebouncedFunc<(postId: number, hasUserLike: boolean) => void>;
18
- export declare const getTagFilterUrl: (tagId: string | number, prefix: string) => string;
19
18
  export declare const updateContentSizes: ({ size, colSizes, theme, ...contentData }: ContentBlockProps) => {
20
19
  size: import("@gravity-ui/page-constructor").ContentSize;
21
20
  colSizes: {
@@ -35,10 +34,10 @@ export declare const updateContentSizes: ({ size, colSizes, theme, ...contentDat
35
34
  };
36
35
  type GetBreadcrumbsProps = {
37
36
  tags?: Tag[];
38
- pathPrefix?: string;
37
+ blogPath: string;
39
38
  };
40
39
  export declare const getBlogPath: (pathPrefix: string) => string;
41
- export declare const getBreadcrumbs: ({ tags, pathPrefix }: GetBreadcrumbsProps) => HeaderBreadCrumbsProps;
40
+ export declare const getBreadcrumbs: ({ tags, blogPath }: GetBreadcrumbsProps) => HeaderBreadCrumbsProps;
42
41
  export declare const isMetrikaExist: (goal: NewMetrikaGoal, existGoals: NewMetrikaGoal[]) => boolean;
43
42
  export declare const getBlogElementMetrika: (blogCustomGoal: NewMetrikaGoal, existingGoals?: MetrikaGoal) => string | string[] | NewMetrikaGoal[];
44
43
  export declare const getFeedQueryParams: (queryString: Query, pageNumber?: number) => GetPostsRequest;
@@ -32,40 +32,36 @@ export const scrollToHash = (hash, browser) => {
32
32
  }
33
33
  setTimeout(() => element.scrollIntoView({ behavior: browser === 'Yandex' ? 'auto' : 'smooth' }), 0);
34
34
  };
35
- export const getTags = memoize((tags, prefix) => {
35
+ export const getTags = memoize((tags, blogPath) => {
36
36
  return tags.map((_a) => {
37
37
  var { slug } = _a, tag = __rest(_a, ["slug"]);
38
38
  const queryParams = new URLSearchParams();
39
39
  queryParams.set('tags', slug);
40
- return Object.assign(Object.assign({}, tag), { id: slug, url: `${prefix}blog?${queryParams}` });
40
+ return Object.assign(Object.assign({}, tag), { id: slug, url: `${blogPath}?${queryParams}` });
41
41
  });
42
42
  });
43
43
  const stub = (postId) => postId;
44
44
  export const postLikeStatus = debounce((postId, hasUserLike) => {
45
45
  (hasUserLike ? stub : stub)(postId);
46
46
  }, 300);
47
- export const getTagFilterUrl = (tagId, prefix) => {
48
- return `${prefix}blog?tags=` + tagId;
49
- };
50
47
  export const updateContentSizes = (_a) => {
51
48
  var { size, colSizes, theme } = _a, contentData = __rest(_a, ["size", "colSizes", "theme"]);
52
49
  return (Object.assign(Object.assign({}, contentData), { size: size || CONTENT_DEFAULT_SIZE, colSizes: colSizes || CONTENT_DEFAULT_COL_SIZES, theme: theme || CONTENT_DEFAULT_THEME }));
53
50
  };
54
51
  export const getBlogPath = (pathPrefix) => {
55
- const prefix = pathPrefix ? `/${pathPrefix}/` : '/';
56
- return `${prefix}blog`;
52
+ const prefix = pathPrefix ? `/${pathPrefix}` : '';
53
+ return `${prefix}/blog`;
57
54
  };
58
- export const getBreadcrumbs = ({ tags, pathPrefix }) => {
59
- const prefix = pathPrefix ? `/${pathPrefix}/` : '/';
55
+ export const getBreadcrumbs = ({ tags, blogPath }) => {
60
56
  const breadcrumbs = {
61
- items: [{ text: i18(Keyset.TitleBreadcrumbs), url: `${prefix}blog` }],
57
+ items: [{ text: i18(Keyset.TitleBreadcrumbs), url: blogPath }],
62
58
  theme: 'light',
63
59
  };
64
60
  if (tags === null || tags === void 0 ? void 0 : tags.length) {
65
- const localizedTags = getTags(tags, prefix);
61
+ const localizedTags = getTags(tags, blogPath);
66
62
  const tag = localizedTags[0];
67
63
  // @ts-ignore todo fix
68
- breadcrumbs.items.push({ text: tag.name, url: getTagFilterUrl(tag.id, prefix) });
64
+ breadcrumbs.items.push({ text: tag.name, url: tag.url });
69
65
  }
70
66
  return breadcrumbs;
71
67
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ui/blog-constructor",
3
- "version": "5.14.0",
3
+ "version": "5.16.0",
4
4
  "description": "Gravity UI Blog Constructor",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -86,7 +86,7 @@
86
86
  "@gravity-ui/prettier-config": "^1.1.0",
87
87
  "@gravity-ui/stylelint-config": "^4.0.1",
88
88
  "@gravity-ui/tsconfig": "^1.0.0",
89
- "@gravity-ui/uikit": "^5.20.0",
89
+ "@gravity-ui/uikit": "^5.25.0",
90
90
  "@jest/environment": "^29.7.0",
91
91
  "@storybook/addon-essentials": "^7.0.27",
92
92
  "@storybook/cli": "^7.0.27",