@gravity-ui/blog-constructor 5.16.1-alpha.1 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) 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 +6 -14
  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 +4 -1
  13. package/build/cjs/components/FeedHeader/components/CustomSwitcher/CustomSwitcher.js +2 -2
  14. package/build/cjs/components/Paginator/Paginator.js +16 -19
  15. package/build/cjs/components/Paginator/components/NavigationButton.js +1 -1
  16. package/build/cjs/components/PostCard/PostCard.d.ts +3 -6
  17. package/build/cjs/components/PostCard/PostCard.js +2 -2
  18. package/build/cjs/components/PostInfo/PostInfo.css +8 -0
  19. package/build/cjs/components/PostInfo/PostInfo.d.ts +4 -10
  20. package/build/cjs/components/PostInfo/PostInfo.js +4 -4
  21. package/build/cjs/components/PostInfo/SuggestPostInfo.js +4 -1
  22. package/build/cjs/components/PostInfo/components/ReadingTime.js +1 -1
  23. package/build/cjs/components/PostInfo/components/Save.d.ts +4 -6
  24. package/build/cjs/components/PostInfo/components/Save.js +4 -7
  25. package/build/cjs/components/PostInfo/components/Sharing.d.ts +3 -5
  26. package/build/cjs/components/PostInfo/components/Sharing.js +4 -10
  27. package/build/cjs/components/Posts/Posts.js +3 -3
  28. package/build/cjs/components/PostsEmpty/PostsEmpty.js +2 -2
  29. package/build/cjs/components/PostsError/PostsError.js +3 -3
  30. package/build/cjs/components/PromptSignIn/PromptSignIn.js +2 -2
  31. package/build/cjs/components/Search/Search.css +3 -0
  32. package/build/cjs/components/Search/Search.js +2 -2
  33. package/build/cjs/constants.d.ts +2 -1
  34. package/build/cjs/constants.js +20 -19
  35. package/build/cjs/constructor/BlogConstructorProvider.js +1 -0
  36. package/build/cjs/containers/BlogPostPage/BlogPostPage.css +1 -1
  37. package/build/cjs/contexts/LocaleContext.js +2 -2
  38. package/build/cjs/counters/metrika.js +0 -3
  39. package/build/cjs/counters/utils.d.ts +1 -1
  40. package/build/cjs/counters/utils.js +7 -7
  41. package/build/cjs/i18n/index.d.ts +1 -3
  42. package/build/cjs/i18n/index.js +8 -10
  43. package/build/cjs/index.d.ts +0 -1
  44. package/build/cjs/index.js +1 -3
  45. package/build/cjs/models/common.d.ts +1 -1
  46. package/build/cjs/models/locale.d.ts +1 -4
  47. package/build/cjs/models/locale.js +1 -6
  48. package/build/cjs/utils/common.d.ts +15 -3
  49. package/build/cjs/utils/common.js +20 -19
  50. package/build/esm/blocks/Banner/Banner.js +8 -10
  51. package/build/esm/blocks/CTA/CTA.js +8 -10
  52. package/build/esm/blocks/Feed/Feed.js +9 -17
  53. package/build/esm/blocks/Header/Header.js +12 -16
  54. package/build/esm/blocks/Media/Media.js +1 -0
  55. package/build/esm/blocks/Meta/Meta.js +13 -17
  56. package/build/esm/blocks/Suggest/Suggest.js +9 -12
  57. package/build/esm/components/FeedHeader/components/Controls/Controls.css +19 -5
  58. package/build/esm/components/FeedHeader/components/Controls/Controls.js +25 -30
  59. package/build/esm/components/FeedHeader/components/Controls/customRenders.js +2 -2
  60. package/build/esm/components/FeedHeader/components/CustomSwitcher/CustomSwitcher.css +4 -1
  61. package/build/esm/components/FeedHeader/components/CustomSwitcher/CustomSwitcher.js +2 -2
  62. package/build/esm/components/Paginator/Paginator.js +18 -21
  63. package/build/esm/components/Paginator/components/NavigationButton.js +2 -2
  64. package/build/esm/components/PostCard/PostCard.d.ts +3 -6
  65. package/build/esm/components/PostCard/PostCard.js +2 -2
  66. package/build/esm/components/PostInfo/PostInfo.css +8 -0
  67. package/build/esm/components/PostInfo/PostInfo.d.ts +4 -10
  68. package/build/esm/components/PostInfo/PostInfo.js +4 -4
  69. package/build/esm/components/PostInfo/SuggestPostInfo.js +4 -1
  70. package/build/esm/components/PostInfo/components/ReadingTime.js +2 -2
  71. package/build/esm/components/PostInfo/components/Save.d.ts +4 -6
  72. package/build/esm/components/PostInfo/components/Save.js +4 -7
  73. package/build/esm/components/PostInfo/components/Sharing.d.ts +3 -5
  74. package/build/esm/components/PostInfo/components/Sharing.js +5 -11
  75. package/build/esm/components/Posts/Posts.js +4 -4
  76. package/build/esm/components/PostsEmpty/PostsEmpty.js +3 -3
  77. package/build/esm/components/PostsError/PostsError.js +4 -4
  78. package/build/esm/components/PromptSignIn/PromptSignIn.js +3 -3
  79. package/build/esm/components/Search/Search.css +3 -0
  80. package/build/esm/components/Search/Search.js +3 -3
  81. package/build/esm/constants.d.ts +2 -1
  82. package/build/esm/constants.js +19 -18
  83. package/build/esm/constructor/BlogConstructorProvider.js +2 -1
  84. package/build/esm/containers/BlogPostPage/BlogPostPage.css +1 -1
  85. package/build/esm/contexts/LocaleContext.js +1 -1
  86. package/build/esm/counters/metrika.js +0 -3
  87. package/build/esm/counters/utils.d.ts +1 -1
  88. package/build/esm/counters/utils.js +6 -6
  89. package/build/esm/i18n/index.d.ts +1 -3
  90. package/build/esm/i18n/index.js +7 -9
  91. package/build/esm/index.d.ts +0 -1
  92. package/build/esm/index.js +0 -1
  93. package/build/esm/models/common.d.ts +1 -1
  94. package/build/esm/models/locale.d.ts +1 -4
  95. package/build/esm/models/locale.js +0 -5
  96. package/build/esm/utils/common.d.ts +15 -3
  97. package/build/esm/utils/common.js +18 -17
  98. package/package.json +15 -14
  99. package/server/data/contentFilter.d.ts +1 -1
  100. package/server/data/contentFilter.js +2 -1
  101. package/server/data/transformPageContent.d.ts +2 -2
  102. package/server/data/transformPost.d.ts +7 -2
  103. package/server/data/transformPost.js +1 -1
  104. package/server/index.d.ts +1 -1
  105. package/server/models/common.d.ts +1 -1
  106. package/server/models/locale.d.ts +1 -4
  107. package/server/models/locale.js +1 -6
  108. package/styles/storybook/common.scss +8 -0
  109. package/styles/storybook/index.scss +1 -1
  110. package/styles/styles.css +115 -0
  111. package/styles/styles.scss +1 -0
  112. package/build/cjs/configure.d.ts +0 -5
  113. package/build/cjs/configure.js +0 -8
  114. package/build/esm/configure.d.ts +0 -5
  115. package/build/esm/configure.js +0 -4
@@ -1,15 +1,15 @@
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.postLikeStatus = exports.getTags = exports.scrollToHash = exports.getPageSearchParams = exports.getAbsolutePath = void 0;
3
+ exports.prepareAnalyticsEvent = exports.getQaAttributes = exports.scrollOnPageChange = exports.getFeedQueryParams = exports.getMergedAnalyticsEvents = 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
- const page_constructor_1 = require("@gravity-ui/page-constructor");
7
6
  const camelCase_1 = tslib_1.__importDefault(require("lodash/camelCase"));
8
7
  const debounce_1 = tslib_1.__importDefault(require("lodash/debounce"));
9
8
  const flatten_1 = tslib_1.__importDefault(require("lodash/flatten"));
10
9
  const memoize_1 = tslib_1.__importDefault(require("lodash/memoize"));
11
10
  const constants_1 = require("../blocks/constants");
12
11
  const i18n_1 = require("../i18n");
12
+ const utils_1 = require("../counters/utils");
13
13
  const QA_ATTRIBUTES_KEYS = ['container', 'content', 'wrapper', 'image', 'button'];
14
14
  function getAbsolutePath(router, url) {
15
15
  if (!router || !router.pathname) {
@@ -62,7 +62,7 @@ const getBlogPath = (pathPrefix) => {
62
62
  exports.getBlogPath = getBlogPath;
63
63
  const getBreadcrumbs = ({ tags, blogPath }) => {
64
64
  const breadcrumbs = {
65
- items: [{ text: (0, i18n_1.i18)(i18n_1.Keyset.TitleBreadcrumbs), url: blogPath }],
65
+ items: [{ text: (0, i18n_1.i18n)(i18n_1.Keyset.TitleBreadcrumbs), url: blogPath }],
66
66
  theme: 'light',
67
67
  };
68
68
  if (tags === null || tags === void 0 ? void 0 : tags.length) {
@@ -74,24 +74,21 @@ const getBreadcrumbs = ({ tags, blogPath }) => {
74
74
  return breadcrumbs;
75
75
  };
76
76
  exports.getBreadcrumbs = getBreadcrumbs;
77
- const isMetrikaExist = (goal, existGoals) => {
78
- return Boolean(existGoals.find((existGoal) => goal.name === existGoal.name));
79
- };
80
- exports.isMetrikaExist = isMetrikaExist;
81
- const getBlogElementMetrika = (blogCustomGoal, existingGoals) => {
82
- if (existingGoals) {
83
- if ((0, page_constructor_1.isNewMetrikaFormat)(existingGoals) && !(0, exports.isMetrikaExist)(blogCustomGoal, existingGoals)) {
84
- const goals = [...existingGoals];
85
- goals.push(blogCustomGoal);
86
- return goals;
87
- }
88
- return existingGoals;
77
+ const getArrayOfEvents = (events) => {
78
+ if (!events) {
79
+ return [];
89
80
  }
90
- else {
91
- return [blogCustomGoal];
81
+ if (Array.isArray(events)) {
82
+ return events;
92
83
  }
84
+ return [events];
85
+ };
86
+ const getMergedAnalyticsEvents = (analyticEvents, existringEvents) => {
87
+ const eventsAsArray = getArrayOfEvents(analyticEvents);
88
+ const existingAsArray = getArrayOfEvents(existringEvents);
89
+ return eventsAsArray.concat(existingAsArray);
93
90
  };
94
- exports.getBlogElementMetrika = getBlogElementMetrika;
91
+ exports.getMergedAnalyticsEvents = getMergedAnalyticsEvents;
95
92
  const getFeedQueryParams = (queryString, pageNumber) => {
96
93
  const queryParams = (0, exports.getPageSearchParams)(queryString);
97
94
  const tags = queryParams.get('tags') || undefined;
@@ -123,4 +120,8 @@ const getQaAttributes = (qa, ...customKeys) => {
123
120
  }
124
121
  return attributes;
125
122
  };
126
- exports.getQaAttributes = getQaAttributes;
123
+ exports.getQaAttributes = getQaAttributes;
124
+ const prepareAnalyticsEvent = ({ name, counter = utils_1.AnalyticsCounter.Main, options = {}, }) => (Object.assign(Object.assign({}, options), { name, counters: {
125
+ include: [counter],
126
+ } }));
127
+ exports.prepareAnalyticsEvent = prepareAnalyticsEvent;
@@ -2,13 +2,18 @@ import { __rest } from "tslib";
2
2
  import React from 'react';
3
3
  import { Content, Image } from '@gravity-ui/page-constructor';
4
4
  import { Wrapper } from '../../components/Wrapper/Wrapper';
5
- import { BlogMetrikaGoalIds } from '../../constants';
6
5
  import { PaddingsDirections } from '../../models/paddings';
7
6
  import { block } from '../../utils/cn';
8
- import { getBlogElementMetrika, getQaAttributes, updateContentSizes } from '../../utils/common';
7
+ import { getMergedAnalyticsEvents, getQaAttributes, prepareAnalyticsEvent, updateContentSizes, } from '../../utils/common';
8
+ import { DefaultGoalIds } from '../../constants';
9
+ import { AnalyticsCounter } from '../../counters/utils';
9
10
  import './Banner.css';
10
11
  const b = block('banner');
11
12
  const BANNER_CUSTOM_QA_ATTRIBUTES = ['image-container'];
13
+ const buttonGoals = prepareAnalyticsEvent({
14
+ name: DefaultGoalIds.bannerCommon,
15
+ counter: AnalyticsCounter.CrossSite,
16
+ });
12
17
  export const Banner = (_a) => {
13
18
  var _b;
14
19
  var { color, imageSize = 's', image, paddingTop, paddingBottom, qa } = _a, content = __rest(_a, ["color", "imageSize", "image", "paddingTop", "paddingBottom", "qa"]);
@@ -18,16 +23,9 @@ export const Banner = (_a) => {
18
23
  contentStyle.backgroundColor = color;
19
24
  }
20
25
  const contentData = updateContentSizes(content);
21
- /**
22
- * @deprecated Metrika will be deleted after launch of analyticsEvents
23
- */
24
- const metrikaGoal = {
25
- name: BlogMetrikaGoalIds.bannerCommon,
26
- isCrossSite: true,
27
- };
28
26
  (_b = contentData.buttons) === null || _b === void 0 ? void 0 : _b.forEach((button) => {
29
27
  // eslint-disable-next-line no-not-accumulator-reassign/no-not-accumulator-reassign
30
- button.metrikaGoals = getBlogElementMetrika(metrikaGoal, button.metrikaGoals);
28
+ button.analyticsEvents = getMergedAnalyticsEvents(buttonGoals, button.analyticsEvents);
31
29
  });
32
30
  return (React.createElement(Wrapper, { paddings: {
33
31
  [PaddingsDirections.top]: paddingTop,
@@ -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,
@@ -52,12 +49,11 @@ export const Feed = ({ image }) => {
52
49
  dispatch({ type: ActionTypes.SetErrorLoad, payload: value });
53
50
  };
54
51
  const handleChangeQueryParams = useCallback((value) => {
55
- var _a;
56
52
  dispatch({ type: ActionTypes.QueryParamsChange, payload: value });
57
53
  const hasFirstPageQuery = Object.keys(value).some((queryKey) => queryKey === PAGE_QUERY && value[queryKey] === FIRST_PAGE);
58
54
  const result = hasFirstPageQuery
59
55
  ? Object.assign(Object.assign({}, value), { [PAGE_QUERY]: null }) : Object.assign({}, value);
60
- (_a = router === null || router === void 0 ? void 0 : router.updateQueryCallback) === null || _a === void 0 ? void 0 : _a.call(router, result);
56
+ router.updateQueryCallback(result);
61
57
  }, [router]);
62
58
  const fetchData = useCallback(async ({ page, query }) => {
63
59
  if (query && getPosts) {
@@ -102,11 +98,7 @@ export const Feed = ({ image }) => {
102
98
  });
103
99
  };
104
100
  const handleShowMore = async () => {
105
- /**
106
- * @deprecated Metrika will be deleted after launch of analyticsEvents
107
- */
108
- metrika.reachGoal(MetrikaCounter.CrossSite, BlogMetrikaGoalIds.showMore);
109
- handleAnalytics();
101
+ handleAnalytics(additionalAnalyticsEvent);
110
102
  const nextPage = currentPage + 1;
111
103
  try {
112
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;
@@ -70,6 +70,9 @@ unpredictable css rules order in build */
70
70
  position: absolute;
71
71
  inset: 0;
72
72
  border-radius: var(--g-border-radius-xl);
73
+ background: transparent;
74
+ border: none;
75
+ cursor: pointer;
73
76
  }
74
77
  .bc-feed-custom-switcher__switcher-arrow {
75
78
  width: 16px;
@@ -15,8 +15,8 @@ export const CustomSwitcher = ({ initial, defaultLabel, list, onClick, controlRe
15
15
  return items.length ? items : [defaultLabel];
16
16
  }, [defaultLabel, initial, list]);
17
17
  const hasCounter = itemsNames.length > 1;
18
- return (React.createElement("button", { className: b('custom-switcher'), ref: controlRef, onKeyDown: onKeyDown, "aria-expanded": open },
19
- React.createElement("div", { onClick: onClick, className: b('custom-switcher-element', { overlay: true }) }),
18
+ return (React.createElement("div", { className: b('custom-switcher'), ref: controlRef },
19
+ React.createElement("button", { onClick: onClick, className: b('custom-switcher-element', { overlay: true }), onKeyDown: onKeyDown, "aria-expanded": open }),
20
20
  React.createElement("div", { className: b('custom-switcher-element', { content: true }) }, itemsNames === null || itemsNames === void 0 ? void 0 : itemsNames.join(', ')),
21
21
  renderClear &&
22
22
  renderClear({