@gravity-ui/blog-constructor 5.16.1 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (109) hide show
  1. package/README.md +5 -5
  2. package/build/cjs/blocks/Banner/Banner.js +7 -9
  3. package/build/cjs/blocks/CTA/CTA.js +7 -9
  4. package/build/cjs/blocks/Feed/Feed.js +5 -12
  5. package/build/cjs/blocks/Header/Header.js +10 -14
  6. package/build/cjs/blocks/Media/Media.js +1 -0
  7. package/build/cjs/blocks/Meta/Meta.js +11 -15
  8. package/build/cjs/blocks/Suggest/Suggest.js +8 -11
  9. package/build/cjs/components/FeedHeader/components/Controls/Controls.css +19 -5
  10. package/build/cjs/components/FeedHeader/components/Controls/Controls.js +22 -27
  11. package/build/cjs/components/FeedHeader/components/Controls/customRenders.js +1 -1
  12. package/build/cjs/components/FeedHeader/components/CustomSwitcher/CustomSwitcher.css +1 -1
  13. package/build/cjs/components/Paginator/Paginator.js +16 -19
  14. package/build/cjs/components/Paginator/components/NavigationButton.js +1 -1
  15. package/build/cjs/components/PostCard/PostCard.d.ts +3 -6
  16. package/build/cjs/components/PostCard/PostCard.js +2 -2
  17. package/build/cjs/components/PostInfo/PostInfo.d.ts +4 -10
  18. package/build/cjs/components/PostInfo/PostInfo.js +4 -4
  19. package/build/cjs/components/PostInfo/SuggestPostInfo.js +4 -1
  20. package/build/cjs/components/PostInfo/components/ReadingTime.js +1 -1
  21. package/build/cjs/components/PostInfo/components/Save.d.ts +4 -6
  22. package/build/cjs/components/PostInfo/components/Save.js +3 -6
  23. package/build/cjs/components/PostInfo/components/Sharing.d.ts +3 -5
  24. package/build/cjs/components/PostInfo/components/Sharing.js +4 -10
  25. package/build/cjs/components/Posts/Posts.js +3 -3
  26. package/build/cjs/components/PostsEmpty/PostsEmpty.js +2 -2
  27. package/build/cjs/components/PostsError/PostsError.js +3 -3
  28. package/build/cjs/components/PromptSignIn/PromptSignIn.js +2 -2
  29. package/build/cjs/components/Search/Search.js +1 -1
  30. package/build/cjs/constants.d.ts +2 -1
  31. package/build/cjs/constants.js +20 -19
  32. package/build/cjs/constructor/BlogConstructorProvider.js +1 -0
  33. package/build/cjs/containers/BlogPostPage/BlogPostPage.css +1 -1
  34. package/build/cjs/contexts/LocaleContext.js +2 -2
  35. package/build/cjs/counters/metrika.js +0 -3
  36. package/build/cjs/counters/utils.d.ts +1 -1
  37. package/build/cjs/counters/utils.js +7 -7
  38. package/build/cjs/i18n/index.d.ts +1 -3
  39. package/build/cjs/i18n/index.js +8 -10
  40. package/build/cjs/index.d.ts +0 -1
  41. package/build/cjs/index.js +1 -3
  42. package/build/cjs/models/common.d.ts +1 -1
  43. package/build/cjs/models/locale.d.ts +1 -4
  44. package/build/cjs/models/locale.js +1 -6
  45. package/build/cjs/utils/common.d.ts +15 -3
  46. package/build/cjs/utils/common.js +20 -19
  47. package/build/esm/blocks/Banner/Banner.js +8 -10
  48. package/build/esm/blocks/CTA/CTA.js +8 -10
  49. package/build/esm/blocks/Feed/Feed.js +8 -15
  50. package/build/esm/blocks/Header/Header.js +12 -16
  51. package/build/esm/blocks/Media/Media.js +1 -0
  52. package/build/esm/blocks/Meta/Meta.js +13 -17
  53. package/build/esm/blocks/Suggest/Suggest.js +9 -12
  54. package/build/esm/components/FeedHeader/components/Controls/Controls.css +19 -5
  55. package/build/esm/components/FeedHeader/components/Controls/Controls.js +25 -30
  56. package/build/esm/components/FeedHeader/components/Controls/customRenders.js +2 -2
  57. package/build/esm/components/FeedHeader/components/CustomSwitcher/CustomSwitcher.css +1 -1
  58. package/build/esm/components/Paginator/Paginator.js +18 -21
  59. package/build/esm/components/Paginator/components/NavigationButton.js +2 -2
  60. package/build/esm/components/PostCard/PostCard.d.ts +3 -6
  61. package/build/esm/components/PostCard/PostCard.js +2 -2
  62. package/build/esm/components/PostInfo/PostInfo.d.ts +4 -10
  63. package/build/esm/components/PostInfo/PostInfo.js +4 -4
  64. package/build/esm/components/PostInfo/SuggestPostInfo.js +4 -1
  65. package/build/esm/components/PostInfo/components/ReadingTime.js +2 -2
  66. package/build/esm/components/PostInfo/components/Save.d.ts +4 -6
  67. package/build/esm/components/PostInfo/components/Save.js +3 -6
  68. package/build/esm/components/PostInfo/components/Sharing.d.ts +3 -5
  69. package/build/esm/components/PostInfo/components/Sharing.js +5 -11
  70. package/build/esm/components/Posts/Posts.js +4 -4
  71. package/build/esm/components/PostsEmpty/PostsEmpty.js +3 -3
  72. package/build/esm/components/PostsError/PostsError.js +4 -4
  73. package/build/esm/components/PromptSignIn/PromptSignIn.js +3 -3
  74. package/build/esm/components/Search/Search.js +2 -2
  75. package/build/esm/constants.d.ts +2 -1
  76. package/build/esm/constants.js +19 -18
  77. package/build/esm/constructor/BlogConstructorProvider.js +2 -1
  78. package/build/esm/containers/BlogPostPage/BlogPostPage.css +1 -1
  79. package/build/esm/contexts/LocaleContext.js +1 -1
  80. package/build/esm/counters/metrika.js +0 -3
  81. package/build/esm/counters/utils.d.ts +1 -1
  82. package/build/esm/counters/utils.js +6 -6
  83. package/build/esm/i18n/index.d.ts +1 -3
  84. package/build/esm/i18n/index.js +7 -9
  85. package/build/esm/index.d.ts +0 -1
  86. package/build/esm/index.js +0 -1
  87. package/build/esm/models/common.d.ts +1 -1
  88. package/build/esm/models/locale.d.ts +1 -4
  89. package/build/esm/models/locale.js +0 -5
  90. package/build/esm/utils/common.d.ts +15 -3
  91. package/build/esm/utils/common.js +18 -17
  92. package/package.json +15 -14
  93. package/server/data/contentFilter.d.ts +1 -1
  94. package/server/data/contentFilter.js +2 -1
  95. package/server/data/transformPageContent.d.ts +2 -2
  96. package/server/data/transformPost.d.ts +7 -2
  97. package/server/data/transformPost.js +1 -1
  98. package/server/index.d.ts +1 -1
  99. package/server/models/common.d.ts +1 -1
  100. package/server/models/locale.d.ts +1 -4
  101. package/server/models/locale.js +1 -6
  102. package/styles/storybook/common.scss +8 -0
  103. package/styles/storybook/index.scss +1 -1
  104. package/styles/styles.css +115 -0
  105. package/styles/styles.scss +1 -0
  106. package/build/cjs/configure.d.ts +0 -5
  107. package/build/cjs/configure.js +0 -8
  108. package/build/esm/configure.d.ts +0 -5
  109. package/build/esm/configure.js +0 -4
@@ -1,20 +1,18 @@
1
1
  import React from 'react';
2
2
  import { Content } from '@gravity-ui/page-constructor';
3
3
  import { Wrapper } from '../../components/Wrapper/Wrapper';
4
- import { BlogMetrikaGoalIds } from '../../constants';
5
4
  import { PaddingsDirections } from '../../models/paddings';
6
5
  import { block } from '../../utils/cn';
7
- import { getBlogElementMetrika, getQaAttributes, updateContentSizes } from '../../utils/common';
6
+ import { getMergedAnalyticsEvents, getQaAttributes, prepareAnalyticsEvent, updateContentSizes, } from '../../utils/common';
7
+ import { DefaultGoalIds } from '../../constants';
8
+ import { AnalyticsCounter } from '../../counters/utils';
8
9
  import './CTA.css';
9
10
  const b = block('cta');
11
+ const linkGoals = prepareAnalyticsEvent({
12
+ name: DefaultGoalIds.cta,
13
+ counter: AnalyticsCounter.CrossSite,
14
+ });
10
15
  export const CTA = ({ items, paddingTop, paddingBottom, qa }) => {
11
- /**
12
- * @deprecated Metrika will be deleted after launch of analyticsEvents
13
- */
14
- const metrikaGoal = {
15
- name: BlogMetrikaGoalIds.cta,
16
- isCrossSite: true,
17
- };
18
16
  const qaAttributes = getQaAttributes(qa, 'card');
19
17
  return (React.createElement(Wrapper, { paddings: {
20
18
  [PaddingsDirections.top]: paddingTop,
@@ -24,7 +22,7 @@ export const CTA = ({ items, paddingTop, paddingBottom, qa }) => {
24
22
  const contentData = updateContentSizes(content);
25
23
  (_a = contentData.links) === null || _a === void 0 ? void 0 : _a.forEach((link) => {
26
24
  // eslint-disable-next-line no-not-accumulator-reassign/no-not-accumulator-reassign
27
- link.metrikaGoals = getBlogElementMetrika(metrikaGoal, link.metrikaGoals);
25
+ link.analyticsEvents = getMergedAnalyticsEvents(linkGoals, link.analyticsEvents);
28
26
  });
29
27
  return (React.createElement("div", { key: index, className: b('card'), "data-qa": qaAttributes.card },
30
28
  React.createElement(Content, Object.assign({}, contentData, { qa: qaAttributes.content }))));
@@ -1,22 +1,15 @@
1
1
  import React, { useCallback, useContext, useEffect, useMemo, useReducer } from 'react';
2
2
  import { useAnalytics } from '@gravity-ui/page-constructor';
3
- /**
4
- * @deprecated Metrika will be deleted after launch of analyticsEvents
5
- */
6
3
  import { Icon } from '@gravity-ui/uikit';
7
4
  import { FeedHeader } from '../../components/FeedHeader/FeedHeader';
8
5
  import { Posts } from '../../components/Posts/Posts';
9
6
  import { PostsError } from '../../components/PostsError/PostsError';
10
- import { BlogMetrikaGoalIds } from '../../constants';
7
+ import { DefaultGoalIds } from '../../constants';
11
8
  import { FeedContext } from '../../contexts/FeedContext';
12
9
  import { RouterContext } from '../../contexts/RouterContext';
13
- /**
14
- * @deprecated Metrika will be deleted after launch of analyticsEvents
15
- */
16
- import metrika from '../../counters/metrika';
17
- import { MetrikaCounter } from '../../counters/utils';
10
+ import { AnalyticsCounter } from '../../counters/utils';
18
11
  import { DefaultEventNames } from '../../models/common';
19
- import { getFeedQueryParams, scrollOnPageChange } from '../../utils/common';
12
+ import { getFeedQueryParams, prepareAnalyticsEvent, scrollOnPageChange } from '../../utils/common';
20
13
  import { DEFAULT_PAGE, DEFAULT_ROWS_PER_PAGE } from '../constants';
21
14
  import { ActionTypes, reducer } from './reducer';
22
15
  const CONTAINER_ID = 'blog-cards';
@@ -27,6 +20,10 @@ export const Feed = ({ image }) => {
27
20
  const { posts, totalCount, tags, services, pinnedPost, getPosts, pageCountForShowSupportButtons, } = useContext(FeedContext);
28
21
  const router = useContext(RouterContext);
29
22
  const handleAnalytics = useAnalytics(DefaultEventNames.ShowMore);
23
+ const additionalAnalyticsEvent = prepareAnalyticsEvent({
24
+ name: DefaultGoalIds.showMore,
25
+ counter: AnalyticsCounter.CrossSite,
26
+ });
30
27
  const [{ errorLoad, errorShowMore, isFetching, isShowMoreVisible, lastLoadedCount, postCountOnPage, postsOnPage, pinnedPostOnPage, currentPage, queryParams, }, dispatch,] = useReducer(reducer, {
31
28
  errorLoad: false,
32
29
  errorShowMore: false,
@@ -101,11 +98,7 @@ export const Feed = ({ image }) => {
101
98
  });
102
99
  };
103
100
  const handleShowMore = async () => {
104
- /**
105
- * @deprecated Metrika will be deleted after launch of analyticsEvents
106
- */
107
- metrika.reachGoal(MetrikaCounter.CrossSite, BlogMetrikaGoalIds.showMore);
108
- handleAnalytics();
101
+ handleAnalytics(additionalAnalyticsEvent);
109
102
  const nextPage = currentPage + 1;
110
103
  try {
111
104
  setIsFetching(true);
@@ -2,25 +2,21 @@ import React, { useContext } from 'react';
2
2
  import { HeaderBlock } from '@gravity-ui/page-constructor';
3
3
  import { PostInfo } from '../../components/PostInfo/PostInfo';
4
4
  import { Wrapper } from '../../components/Wrapper/Wrapper';
5
- import { BlogMetrikaGoalIds } from '../../constants';
5
+ import { DefaultGoalIds } 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, getBlogPath as getDefaultBlogPath } from '../../utils/common';
9
+ import { getBreadcrumbs, getBlogPath as getDefaultBlogPath, prepareAnalyticsEvent, } from '../../utils/common';
10
10
  import { SettingsContext } from '../../contexts/SettingsContext';
11
- /**
12
- * @deprecated Metrika will be deleted after launch of analyticsEvents
13
- */
14
- const metrikaGoals = {
15
- sharing: BlogMetrikaGoalIds.shareTop,
16
- save: BlogMetrikaGoalIds.saveTop,
11
+ import { AnalyticsCounter } from '../../counters/utils';
12
+ const analyticsEventsContainer = {
13
+ sharing: prepareAnalyticsEvent({ name: DefaultGoalIds.shareTop }),
14
+ save: prepareAnalyticsEvent({ name: DefaultGoalIds.saveTop }),
17
15
  };
18
- const breadcrumbsGoals = [
19
- {
20
- name: BlogMetrikaGoalIds.breadcrumbsTop,
21
- isCrossSite: true,
22
- },
23
- ];
16
+ const breadcrumbsGoals = prepareAnalyticsEvent({
17
+ name: DefaultGoalIds.breadcrumbsTop,
18
+ counter: AnalyticsCounter.CrossSite,
19
+ });
24
20
  export const Header = (props) => {
25
21
  const { theme, paddingTop, paddingBottom } = props;
26
22
  const { post } = useContext(PostPageContext);
@@ -32,11 +28,11 @@ export const Header = (props) => {
32
28
  if (theme === 'dark' && breadcrumbs) {
33
29
  breadcrumbs.theme = 'dark';
34
30
  }
35
- breadcrumbs.metrikaGoals = breadcrumbsGoals;
31
+ breadcrumbs.analyticsEvents = breadcrumbsGoals;
36
32
  return (React.createElement(Wrapper, { paddings: {
37
33
  [PaddingsDirections.top]: paddingTop,
38
34
  [PaddingsDirections.bottom]: paddingBottom,
39
35
  } },
40
36
  React.createElement(HeaderBlock, Object.assign({}, props, { title: title, description: description, breadcrumbs: breadcrumbs }),
41
- React.createElement(PostInfo, { postId: id, date: date, readingTime: readingTime, metrikaGoals: metrikaGoals, theme: theme, qa: "blog-header-meta-container" }))));
37
+ React.createElement(PostInfo, { postId: id, date: date, readingTime: readingTime, analyticsEventsContainer: analyticsEventsContainer, theme: theme, qa: "blog-header-meta-container" }))));
42
38
  };
@@ -16,6 +16,7 @@ export const Media = (_a) => {
16
16
  React.createElement(PCMedia, Object.assign({ className: b('content'), videoClassName: b('video'), imageClassName: b('image') }, mediaProps))),
17
17
  text && (React.createElement("div", { className: b('text-content') },
18
18
  React.createElement(YFMWrapper, { content: text, modifiers: {
19
+ blog: true,
19
20
  blogMedia: true,
20
21
  resetPaddings: true,
21
22
  } })))));
@@ -2,28 +2,24 @@ import React, { useContext } from 'react';
2
2
  import { HeaderBreadcrumbs, YFMWrapper } from '@gravity-ui/page-constructor';
3
3
  import { PostInfo } from '../../components/PostInfo/PostInfo';
4
4
  import { Wrapper } from '../../components/Wrapper/Wrapper';
5
- import { BlogMetrikaGoalIds } from '../../constants';
5
+ import { DefaultGoalIds } from '../../constants';
6
6
  import { LocaleContext } from '../../contexts/LocaleContext';
7
7
  import { SettingsContext } from '../../contexts/SettingsContext';
8
8
  import { PostPageContext } from '../../contexts/PostPageContext';
9
9
  import { PaddingsDirections } from '../../models/paddings';
10
10
  import { block } from '../../utils/cn';
11
- import { getBreadcrumbs, getBlogPath as getDefaultBlogPath, getQaAttributes, } from '../../utils/common';
11
+ import { getBreadcrumbs, getBlogPath as getDefaultBlogPath, getMergedAnalyticsEvents, getQaAttributes, prepareAnalyticsEvent, } from '../../utils/common';
12
+ import { AnalyticsCounter } from '../../counters/utils';
12
13
  import './Meta.css';
13
14
  const b = block('meta');
14
- /**
15
- * @deprecated Metrika will be deleted after launch of analyticsEvents
16
- */
17
- const metrikaGoals = {
18
- sharing: BlogMetrikaGoalIds.shareBottom,
19
- save: BlogMetrikaGoalIds.saveBottom,
15
+ const analyticsEventsContainer = {
16
+ sharing: prepareAnalyticsEvent({ name: DefaultGoalIds.shareBottom }),
17
+ save: prepareAnalyticsEvent({ name: DefaultGoalIds.saveBottom }),
20
18
  };
21
- const breadcrumbsGoals = [
22
- {
23
- name: BlogMetrikaGoalIds.breadcrumbsBottom,
24
- isCrossSite: true,
25
- },
26
- ];
19
+ const breadcrumbsGoals = prepareAnalyticsEvent({
20
+ name: DefaultGoalIds.breadcrumbsBottom,
21
+ counter: AnalyticsCounter.CrossSite,
22
+ });
27
23
  export const Meta = (props) => {
28
24
  const { paddingTop = 'l', paddingBottom = 'l', theme = 'light', qa } = props;
29
25
  const { post } = useContext(PostPageContext);
@@ -33,15 +29,15 @@ export const Meta = (props) => {
33
29
  const blogPath = getBlogPath(locale.pathPrefix || '');
34
30
  const { title, id, date, readingTime, tags } = post;
35
31
  const breadcrumbs = getBreadcrumbs({ tags, blogPath });
36
- breadcrumbs.metrikaGoals = breadcrumbsGoals;
32
+ breadcrumbs.analyticsEvents = getMergedAnalyticsEvents(breadcrumbsGoals);
37
33
  return (React.createElement(Wrapper, { paddings: {
38
34
  [PaddingsDirections.top]: paddingTop,
39
35
  [PaddingsDirections.bottom]: paddingBottom,
40
36
  }, qa: qaAttributes.wrapper },
41
- breadcrumbs && (React.createElement(HeaderBreadcrumbs, { items: breadcrumbs.items, className: b('breadcrumbs'), theme: theme, metrikaGoals: breadcrumbs.metrikaGoals })),
37
+ breadcrumbs && (React.createElement(HeaderBreadcrumbs, { items: breadcrumbs.items, className: b('breadcrumbs'), theme: theme })),
42
38
  title && (React.createElement(YFMWrapper, { content: title, modifiers: {
43
39
  blogBreadcrumbs: true,
44
40
  resetPaddings: true,
45
41
  } })),
46
- post && (React.createElement(PostInfo, { postId: id, date: date, readingTime: readingTime, metrikaGoals: metrikaGoals, qa: qaAttributes.postInfo }))));
42
+ post && (React.createElement(PostInfo, { postId: id, date: date, readingTime: readingTime, analyticsEventsContainer: analyticsEventsContainer, qa: qaAttributes.postInfo }))));
47
43
  };
@@ -2,19 +2,16 @@ import React, { useContext } from 'react';
2
2
  import { SliderBlock } from '@gravity-ui/page-constructor';
3
3
  import { PostCard } from '../../components/PostCard/PostCard';
4
4
  import { Wrapper } from '../../components/Wrapper/Wrapper';
5
- import { BlogMetrikaGoalIds } from '../../constants';
6
5
  import { PostPageContext } from '../../contexts/PostPageContext';
7
- import { Keyset, i18 } from '../../i18n';
6
+ import { Keyset, i18n } from '../../i18n';
8
7
  import { PaddingsDirections } from '../../models/paddings';
9
- /**
10
- * @deprecated Metrika will be deleted after launch of analyticsEvents
11
- */
12
- const metrikaGoals = [
13
- {
14
- name: BlogMetrikaGoalIds.suggest,
15
- isCrossSite: true,
16
- },
17
- ];
8
+ import { prepareAnalyticsEvent } from '../../utils/common';
9
+ import { DefaultGoalIds } from '../../constants';
10
+ import { AnalyticsCounter } from '../../counters/utils';
11
+ const suggestGoals = prepareAnalyticsEvent({
12
+ name: DefaultGoalIds.suggest,
13
+ counter: AnalyticsCounter.CrossSite,
14
+ });
18
15
  /**
19
16
  * Suggested posts block
20
17
  *
@@ -33,5 +30,5 @@ export const Suggest = ({ paddingTop = 'l', paddingBottom = 'l' }) => {
33
30
  [PaddingsDirections.top]: paddingTop,
34
31
  [PaddingsDirections.bottom]: paddingBottom,
35
32
  } },
36
- React.createElement(SliderBlock, { slidesToShow: { xl: 3, lg: 2, sm: 1 }, title: { text: i18(Keyset.TitleSuggest) }, lazyLoad: false }, suggestedPosts.map((post) => (React.createElement(PostCard, { key: post.id, metrikaGoals: metrikaGoals, post: post }))))));
33
+ React.createElement(SliderBlock, { slidesToShow: { xl: 3, lg: 2, sm: 1 }, title: { text: i18n(Keyset.TitleSuggest) }, lazyLoad: false }, suggestedPosts.map((post) => (React.createElement(PostCard, { key: post.id, analyticsEvents: suggestGoals, post: post }))))));
37
34
  };
@@ -36,10 +36,10 @@ unpredictable css rules order in build */
36
36
  .bc-feed-controls__popup.bc-feed-controls__popup .g-select-list::-webkit-scrollbar {
37
37
  display: none;
38
38
  }
39
- .bc-feed-controls__popup.bc-feed-controls__popup .g-select-list .yc-list {
39
+ .bc-feed-controls__popup.bc-feed-controls__popup .g-select-list .g-list {
40
40
  max-height: calc(500px - var(--g-text-body-3-line-height) - 12px);
41
41
  }
42
- .bc-feed-controls__popup.bc-feed-controls__popup .yc-list__item {
42
+ .bc-feed-controls__popup.bc-feed-controls__popup .g-list__item {
43
43
  margin: 4px;
44
44
  border-radius: 8px;
45
45
  }
@@ -48,12 +48,28 @@ unpredictable css rules order in build */
48
48
  max-height: inherit;
49
49
  }
50
50
 
51
+ .bc-feed-controls__popup_isMobile .bc-feed-controls__popup-filter {
52
+ position: relative;
53
+ border: none;
54
+ }
55
+ .bc-feed-controls__popup_isMobile .bc-feed-controls__popup-filter::before {
56
+ content: "";
57
+ position: absolute;
58
+ left: 50%;
59
+ bottom: 0px;
60
+ border-bottom: 2px solid var(--g-color-line-generic);
61
+ border-bottom-right-radius: 0;
62
+ border-bottom-left-radius: 0;
63
+ width: 100vw;
64
+ height: 2px;
65
+ transform: translateX(-50%);
66
+ }
51
67
  .bc-feed-controls__popup-filter {
52
68
  font-size: var(--g-text-body-2-font-size);
53
69
  line-height: var(--g-text-body-2-line-height);
54
70
  padding: 4px 12px;
55
71
  border: none;
56
- border-bottom: 1px solid var(--yc-color-line-generic);
72
+ border-bottom: 1px solid var(--g-color-line-generic);
57
73
  border-bottom-right-radius: 0;
58
74
  border-bottom-left-radius: 0;
59
75
  }
@@ -63,8 +79,6 @@ unpredictable css rules order in build */
63
79
  .bc-feed-controls__saved-only-button_savedOnly.bc-feed-controls__saved-only-button_savedOnly {
64
80
  --g-button-background-color: var(--pc-monochrome-button-background-color);
65
81
  --g-button-background-color-hover: var(--pc-monochrome-button-background-color-hover);
66
- --yc-button-background-color: var(--pc-monochrome-button-background-color);
67
- --yc-button-background-color-hover: var(--pc-monochrome-button-background-color-hover);
68
82
  }
69
83
  .bc-feed-controls__saved-only-button_savedOnly.bc-feed-controls__saved-only-button_savedOnly, .bc-feed-controls__saved-only-button_savedOnly.bc-feed-controls__saved-only-button_savedOnly:link, .bc-feed-controls__saved-only-button_savedOnly.bc-feed-controls__saved-only-button_savedOnly:visited, .bc-feed-controls__saved-only-button_savedOnly.bc-feed-controls__saved-only-button_savedOnly:active, .bc-feed-controls__saved-only-button_savedOnly.bc-feed-controls__saved-only-button_savedOnly:focus {
70
84
  color: var(--pc-monochrome-button-color);
@@ -1,19 +1,16 @@
1
1
  import React, { useContext, useMemo, useState } from 'react';
2
2
  import { useAnalytics } from '@gravity-ui/page-constructor';
3
3
  import { Button, Icon, Select } from '@gravity-ui/uikit';
4
- /**
5
- * @deprecated Metrika will be deleted after launch of analyticsEvents
6
- */
7
- import { BlogMetrikaGoalIds } from '../../../../constants';
4
+ import { DefaultGoalIds } from '../../../../constants';
8
5
  import { LikesContext } from '../../../../contexts/LikesContext';
9
6
  import { MobileContext } from '../../../../contexts/MobileContext';
10
- import metrika from '../../../../counters/metrika';
11
- import { MetrikaCounter } from '../../../../counters/utils';
12
- import { Keyset, i18 } from '../../../../i18n';
7
+ import { AnalyticsCounter } from '../../../../counters/utils';
8
+ import { Keyset, i18n } from '../../../../i18n';
13
9
  import { Save } from '../../../../icons/Save';
14
10
  import { DefaultEventNames } from '../../../../models/common';
15
11
  import { block } from '../../../../utils/cn';
16
12
  import { Search } from '../../../Search/Search';
13
+ import { prepareAnalyticsEvent } from '../../../../utils/common';
17
14
  import { renderFilter, renderOption, renderSwitcher } from './customRenders';
18
15
  import './Controls.css';
19
16
  const b = block('feed-controls');
@@ -51,13 +48,11 @@ export const Controls = ({ handleLoadData, tags = [], services = [], queryParams
51
48
  });
52
49
  };
53
50
  const handleTagSelect = (selectedTags) => {
54
- /**
55
- * @deprecated Metrika will be deleted after launch of analyticsEvents
56
- */
57
- metrika.reachGoal(MetrikaCounter.CrossSite, BlogMetrikaGoalIds.tag, {
58
- theme: selectedTags[0],
51
+ const event = prepareAnalyticsEvent({
52
+ name: DefaultGoalIds.tag,
53
+ counter: AnalyticsCounter.CrossSite,
59
54
  });
60
- handleAnalyticsTag(null, {
55
+ handleAnalyticsTag(event, {
61
56
  theme: selectedTags[0],
62
57
  });
63
58
  const isEmptyTag = selectedTags.some((tag) => tag === 'empty');
@@ -70,18 +65,18 @@ export const Controls = ({ handleLoadData, tags = [], services = [], queryParams
70
65
  });
71
66
  };
72
67
  const handleServicesSelect = (selectedServices) => {
73
- const forMetrikaServices = services.filter((service) => {
68
+ const forAnalyticsServices = services.filter((service) => {
74
69
  return selectedServices.includes(service.value);
75
70
  });
76
- const metrikaAsString = forMetrikaServices.map((service) => service.content).join(',');
77
- /**
78
- * @deprecated Metrika will be deleted after launch of analyticsEvents
79
- */
80
- metrika.reachGoal(MetrikaCounter.CrossSite, BlogMetrikaGoalIds.service, {
81
- service: metrikaAsString,
71
+ const servicesAsStringForAnalytics = forAnalyticsServices
72
+ .map((service) => service.content)
73
+ .join(',');
74
+ const event = prepareAnalyticsEvent({
75
+ name: DefaultGoalIds.service,
76
+ counter: AnalyticsCounter.CrossSite,
82
77
  });
83
- handleAnalyticsService(null, {
84
- service: metrikaAsString,
78
+ handleAnalyticsService(event, {
79
+ service: servicesAsStringForAnalytics,
85
80
  });
86
81
  const servicesAsString = selectedServices.join(',');
87
82
  handleLoadData({
@@ -89,27 +84,27 @@ export const Controls = ({ handleLoadData, tags = [], services = [], queryParams
89
84
  query: { services: servicesAsString, page: DEFAULT_PAGE },
90
85
  });
91
86
  };
92
- const tagsItems = useMemo(() => [{ value: 'empty', content: i18(Keyset.AllTags) }, ...tags], [tags]);
87
+ const tagsItems = useMemo(() => [{ value: 'empty', content: i18n(Keyset.AllTags) }, ...tags], [tags]);
93
88
  const servicesItems = useMemo(() => (servicesInitial ? [...servicesInitial.split(',')] : []), [servicesInitial]);
94
89
  return (React.createElement("div", { className: b('header') },
95
- React.createElement("h1", { className: b('header-item', { title: true }) }, i18(Keyset.Title)),
90
+ React.createElement("h1", { className: b('header-item', { title: true }) }, i18n(Keyset.Title)),
96
91
  React.createElement("div", { className: b('header-item', { filters: true }) },
97
92
  React.createElement("div", { className: b('filter-item') },
98
- React.createElement(Search, { className: b('search'), placeholder: i18(Keyset.Search), initialValue: search && typeof search === 'string' ? search : '', onSubmit: handleSearch })),
93
+ React.createElement(Search, { className: b('search'), placeholder: i18n(Keyset.Search), initialValue: search && typeof search === 'string' ? search : '', onSubmit: handleSearch })),
99
94
  React.createElement("div", { className: b('filter-item') },
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({
95
+ React.createElement(Select, { className: b('select'), size: "xl", options: tagsItems, defaultValue: [tagInitial], onUpdate: handleTagSelect, placeholder: i18n(Keyset.AllTags), popupClassName: b('popup', { isMobile }), renderControl: renderSwitcher({
101
96
  initial: [tagInitial],
102
97
  list: tagsItems,
103
- defaultLabel: i18(Keyset.AllTags),
98
+ defaultLabel: i18n(Keyset.AllTags),
104
99
  }), disablePortal: true, virtualizationThreshold: VIRTUALIZATION_THRESHOLD, renderOption: renderOption })),
105
100
  services.length > 0 ? (React.createElement("div", { className: b('filter-item') },
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({
101
+ 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: i18n(Keyset.AllServices), renderControl: renderSwitcher({
107
102
  initial: servicesItems,
108
103
  list: services,
109
- defaultLabel: i18(Keyset.AllServices),
104
+ defaultLabel: i18n(Keyset.AllServices),
110
105
  }), virtualizationThreshold: VIRTUALIZATION_THRESHOLD, renderOption: renderOption, renderFilter: renderFilter }))) : null,
111
106
  hasLikes ? (React.createElement("div", { className: b('filter-item', { 'width-auto': true }) },
112
107
  React.createElement(Button, { view: 'outlined', className: b('saved-only-button', { savedOnly }), size: "xl", onClick: handleSavedOnly },
113
108
  React.createElement(Icon, { data: Save, size: ICON_SIZE, className: b('icon', { savedOnly }) }),
114
- i18(Keyset.ActionSavedOnly)))) : null)));
109
+ i18n(Keyset.ActionSavedOnly)))) : null)));
115
110
  };
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { TextInput } from '@gravity-ui/uikit';
3
- import { Keyset, i18 } from '../../../../i18n';
3
+ import { Keyset, i18n } from '../../../../i18n';
4
4
  import { block } from '../../../../utils/cn';
5
5
  import { CustomSelectOption, } from '../CustomSelectOption/CustomSelectOption';
6
6
  import { CustomSwitcher } from '../CustomSwitcher/CustomSwitcher';
@@ -9,5 +9,5 @@ const b = block('feed-controls');
9
9
  export const renderSwitcher = ({ initial, list, defaultLabel }) =>
10
10
  // eslint-disable-next-line react/display-name
11
11
  ({ onClick, ref, onKeyDown, open, renderClear }) => (React.createElement(CustomSwitcher, { initial: initial, defaultLabel: defaultLabel, list: list, controlRef: ref, onClick: onClick, onKeyDown: onKeyDown, renderClear: renderClear, open: open }));
12
- export const renderFilter = ({ value, onChange, onKeyDown }) => (React.createElement(TextInput, { controlProps: { size: 1 }, value: value, view: "clear", placeholder: i18(Keyset.Search), onUpdate: onChange, onKeyDown: onKeyDown, className: b('popup-filter') }));
12
+ export const renderFilter = ({ value, onChange, onKeyDown }) => (React.createElement(TextInput, { controlProps: { size: 1 }, value: value, view: "clear", placeholder: i18n(Keyset.Search), onUpdate: onChange, onKeyDown: onKeyDown, className: b('popup-filter') }));
13
13
  export const renderOption = (option) => (React.createElement(CustomSelectOption, { data: option }));
@@ -24,7 +24,7 @@ unpredictable css rules order in build */
24
24
  .bc-feed-custom-switcher__custom-switcher:focus:not(:focus-visible) {
25
25
  outline: 0;
26
26
  }
27
- .bc-feed-custom-switcher__custom-switcher + .yc-popup.yc-popup_open {
27
+ .bc-feed-custom-switcher__custom-switcher + .g-popup.g-popup_open {
28
28
  position: absolute !important;
29
29
  inset: auto !important;
30
30
  transform: translate3d(0, 4px, 0) !important;
@@ -1,18 +1,15 @@
1
1
  import { __rest } from "tslib";
2
2
  import React, { useEffect, useMemo, useState } from 'react';
3
3
  import { useAnalytics } from '@gravity-ui/page-constructor';
4
- import { BlogMetrikaGoalIds } from '../../constants';
5
- /**
6
- * @deprecated Metrika will be deleted after launch of analyticsEvents
7
- */
8
- import metrika from '../../counters/metrika';
9
- import { MetrikaCounter } from '../../counters/utils';
4
+ import { DefaultGoalIds } from '../../constants';
5
+ import { AnalyticsCounter } from '../../counters/utils';
10
6
  import { DefaultEventNames } from '../../models/common';
11
7
  import { block } from '../../utils/cn';
12
8
  import { NavigationButton } from './components/NavigationButton';
13
9
  import { PaginatorItem } from './components/PaginatorItem';
14
10
  import { ArrowType } from './types';
15
11
  import { getPageConfigs, getPagesCount } from './utils';
12
+ import { prepareAnalyticsEvent } from '../../utils/common';
16
13
  import _ from 'lodash';
17
14
  import './Paginator.css';
18
15
  const b = block('paginator');
@@ -37,19 +34,19 @@ export const Paginator = ({ itemsPerPage, totalItems, maxPages, page, className,
37
34
  const handleArrowClick = (type) => {
38
35
  let newPage = page;
39
36
  if (type === 'prev' && page > 1) {
40
- /**
41
- * @deprecated Metrika will be deleted after launch of analyticsEvents
42
- */
43
- metrika.reachGoal(MetrikaCounter.CrossSite, BlogMetrikaGoalIds.home);
44
- handleAnalyticsHome();
37
+ const event = prepareAnalyticsEvent({
38
+ name: DefaultGoalIds.home,
39
+ counter: AnalyticsCounter.CrossSite,
40
+ });
41
+ handleAnalyticsHome(event);
45
42
  newPage = 1;
46
43
  }
47
44
  else if (type === 'next' && page < pagesCount) {
48
- /**
49
- * @deprecated Metrika will be deleted after launch of analyticsEvents
50
- */
51
- handleAnalyticsNext();
52
- metrika.reachGoal(MetrikaCounter.CrossSite, BlogMetrikaGoalIds.next);
45
+ const event = prepareAnalyticsEvent({
46
+ name: DefaultGoalIds.next,
47
+ counter: AnalyticsCounter.CrossSite,
48
+ });
49
+ handleAnalyticsNext(event);
53
50
  newPage = page + 1;
54
51
  }
55
52
  if (newPage !== page) {
@@ -58,11 +55,11 @@ export const Paginator = ({ itemsPerPage, totalItems, maxPages, page, className,
58
55
  };
59
56
  const handlePageClick = (index) => {
60
57
  if (index !== page && typeof index === 'number') {
61
- /**
62
- * @deprecated Metrika will be deleted after launch of analyticsEvents
63
- */
64
- metrika.reachGoal(MetrikaCounter.CrossSite, BlogMetrikaGoalIds.page, { page: index });
65
- handleAnalyticsPage(null, { page: String(index) });
58
+ const event = prepareAnalyticsEvent({
59
+ name: DefaultGoalIds.page,
60
+ counter: AnalyticsCounter.CrossSite,
61
+ });
62
+ handleAnalyticsPage(event, { page: String(index) });
66
63
  handlePageChange(index);
67
64
  }
68
65
  };
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
- import { Keyset, i18 } from '../../../i18n';
2
+ import { Keyset, i18n } from '../../../i18n';
3
3
  import { block } from '../../../utils/cn';
4
4
  import { ArrowType } from '../types';
5
5
  import '../Paginator.css';
6
6
  const b = block('paginator');
7
- export const NavigationButton = ({ arrowType, disabled }) => disabled ? null : (React.createElement("div", { className: b('icon') }, arrowType === ArrowType.Prev ? i18(Keyset.ButtonBegin) : i18(Keyset.ButtonFarther)));
7
+ export const NavigationButton = ({ arrowType, disabled }) => disabled ? null : (React.createElement("div", { className: b('icon') }, arrowType === ArrowType.Prev ? i18n(Keyset.ButtonBegin) : i18n(Keyset.ButtonFarther)));
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { MetrikaGoal } from '@gravity-ui/page-constructor';
2
+ import { AnalyticsEventsProp } from '@gravity-ui/page-constructor';
3
3
  import { PostCardSize, PostCardTitleHeadingLevel, PostData } from '../../models/common';
4
4
  import './PostCard.css';
5
5
  type PostCardProps = {
@@ -8,10 +8,7 @@ type PostCardProps = {
8
8
  showTag?: boolean;
9
9
  size?: PostCardSize;
10
10
  titleHeadingLevel?: PostCardTitleHeadingLevel;
11
- /**
12
- * @deprecated Metrika will be deleted after launch of analyticsEvents
13
- */
14
- metrikaGoals?: MetrikaGoal;
11
+ analyticsEvents?: AnalyticsEventsProp;
15
12
  };
16
- export declare const PostCard: ({ post, metrikaGoals, fullWidth, size, showTag, titleHeadingLevel, }: PostCardProps) => React.JSX.Element;
13
+ export declare const PostCard: ({ post, fullWidth, size, showTag, titleHeadingLevel, analyticsEvents, }: PostCardProps) => React.JSX.Element;
17
14
  export {};
@@ -8,7 +8,7 @@ import { SuggestPostInfo } from '../PostInfo/SuggestPostInfo';
8
8
  import { useAriaAttributes } from '../../hooks/useAriaAttributes';
9
9
  import './PostCard.css';
10
10
  const b = block('post-card');
11
- export const PostCard = ({ post, metrikaGoals, fullWidth = false, size = PostCardSize.SMALL, showTag = false, titleHeadingLevel = PostCardTitleHeadingLevel.H3, }) => {
11
+ export const PostCard = ({ post, fullWidth = false, size = PostCardSize.SMALL, showTag = false, titleHeadingLevel = PostCardTitleHeadingLevel.H3, analyticsEvents, }) => {
12
12
  var _a;
13
13
  const { title: postTitle, htmlTitle, textTitle, blogPostId, id, date, readingTime, hasUserLike, likes, image, description, tags, url, } = post;
14
14
  const title = postTitle || textTitle || htmlTitle;
@@ -34,7 +34,7 @@ export const PostCard = ({ post, metrikaGoals, fullWidth = false, size = PostCar
34
34
  readingTime && readingTimeId,
35
35
  ],
36
36
  });
37
- return (React.createElement(CardBase, { url: url, metrikaGoals: metrikaGoals, className: b('card', { fullWidth }), extraProps: ariaAttributes },
37
+ return (React.createElement(CardBase, { url: url, analyticsEvents: analyticsEvents, className: b('card', { fullWidth }), extraProps: ariaAttributes },
38
38
  React.createElement(CardBase.Header, { image: image, className: b('header', { fullWidth }) },
39
39
  React.createElement("div", { className: b('image-container'), "data-qa": "blog-suggest-header" })),
40
40
  React.createElement(CardBase.Content, null,
@@ -1,19 +1,13 @@
1
1
  import React from 'react';
2
+ import { AnalyticsEventsProp } from '@gravity-ui/page-constructor';
2
3
  import { PostData, QAProps } from '../../models/common';
3
4
  import './PostInfo.css';
4
- export type BlogMetrikaGoals = {
5
- sharing?: string;
6
- save?: string;
7
- };
8
5
  type PostInfoProps = QAProps & {
9
6
  postId: PostData['id'];
10
7
  readingTime: PostData['readingTime'];
11
8
  date: PostData['date'];
12
9
  theme?: 'light' | 'dark';
13
- /**
14
- * @deprecated Metrika will be deleted after launch of analyticsEvents
15
- */
16
- metrikaGoals?: BlogMetrikaGoals;
10
+ analyticsEventsContainer?: Record<string, AnalyticsEventsProp>;
17
11
  };
18
12
  /**
19
13
  * Blog post info panel component
@@ -22,10 +16,10 @@ type PostInfoProps = QAProps & {
22
16
  * @param readingTime - post reading time
23
17
  * @param date - post create date
24
18
  * @param theme - theme name
25
- * @param metrikaGoals - metrika goals name
26
19
  * @param qa - test-attr
20
+ * @param analyticsEventsContainer - a map of records with a single or collection of objects detailing analytics events
27
21
  *
28
22
  * @returns jsx
29
23
  */
30
- export declare const PostInfo: ({ date, readingTime, postId, theme, metrikaGoals, qa, }: PostInfoProps) => React.JSX.Element;
24
+ export declare const PostInfo: ({ date, readingTime, postId, theme, qa, analyticsEventsContainer, }: PostInfoProps) => React.JSX.Element;
31
25
  export {};
@@ -15,17 +15,17 @@ const b = block('post-info');
15
15
  * @param readingTime - post reading time
16
16
  * @param date - post create date
17
17
  * @param theme - theme name
18
- * @param metrikaGoals - metrika goals name
19
18
  * @param qa - test-attr
19
+ * @param analyticsEventsContainer - a map of records with a single or collection of objects detailing analytics events
20
20
  *
21
21
  * @returns jsx
22
22
  */
23
- export const PostInfo = ({ date, readingTime, postId, theme = 'light', metrikaGoals, qa, }) => {
23
+ export const PostInfo = ({ date, readingTime, postId, theme = 'light', qa, analyticsEventsContainer, }) => {
24
24
  const { likes } = useContext(PostPageContext);
25
25
  const qaAttributes = getQaAttributes(qa, 'date', 'reading-time', 'save');
26
26
  return (React.createElement("div", { className: b('container', { theme }) },
27
27
  date && React.createElement(Date, { date: date, qa: qaAttributes.date }),
28
28
  readingTime && React.createElement(ReadingTime, { readingTime: readingTime, qa: qaAttributes.readingTime }),
29
- React.createElement(Sharing, { metrikaGoal: metrikaGoals === null || metrikaGoals === void 0 ? void 0 : metrikaGoals.sharing, theme: theme }),
30
- likes && (React.createElement(Save, { postId: postId, title: likes.likesCount, hasUserLike: likes.hasUserLike, handleUserLike: likes.handleUserLike, metrikaGoal: metrikaGoals === null || metrikaGoals === void 0 ? void 0 : metrikaGoals.save, theme: theme, qa: qaAttributes.save }))));
29
+ React.createElement(Sharing, { theme: theme, analyticsEvents: analyticsEventsContainer === null || analyticsEventsContainer === void 0 ? void 0 : analyticsEventsContainer.sharing }),
30
+ likes && (React.createElement(Save, { postId: postId, title: likes.likesCount, hasUserLike: likes.hasUserLike, handleUserLike: likes.handleUserLike, analyticsEvents: analyticsEventsContainer === null || analyticsEventsContainer === void 0 ? void 0 : analyticsEventsContainer.save, theme: theme, qa: qaAttributes.save }))));
31
31
  };
@@ -5,8 +5,11 @@ import { block } from '../../utils/cn';
5
5
  import { Date } from './components/Date';
6
6
  import { ReadingTime } from './components/ReadingTime';
7
7
  import { Save } from './components/Save';
8
+ import { prepareAnalyticsEvent } from '../../utils/common';
9
+ import { DefaultGoalIds } from '../../constants';
8
10
  import './PostInfo.css';
9
11
  const b = block('post-info');
12
+ const saveEvents = prepareAnalyticsEvent({ name: DefaultGoalIds.saveSuggest });
10
13
  /**
11
14
  * Suggest blog card info component
12
15
  *
@@ -34,5 +37,5 @@ export const SuggestPostInfo = ({ postId, date, readingTime, likes, size = PostC
34
37
  React.createElement("div", { className: b('suggest-container') },
35
38
  date && React.createElement(Date, { date: date, size: size, id: dateId }),
36
39
  readingTime && (React.createElement(ReadingTime, { readingTime: readingTime, size: size, id: readingTimeId }))),
37
- likes && postId && (React.createElement(Save, { postId: postId, title: likesCount, hasUserLike: hasUserLike, handleUserLike: handleLike, size: size, qa: qa }))));
40
+ likes && postId && (React.createElement(Save, { postId: postId, title: likesCount, analyticsEvents: saveEvents, hasUserLike: hasUserLike, handleUserLike: handleLike, size: size, qa: qa }))));
38
41
  };