@gravity-ui/blog-constructor 10.1.1-alpha.0 → 10.1.1-alpha.2

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.
@@ -21,22 +21,32 @@ const FilterControl = ({ filter, initialValue, onChange }) => {
21
21
  onChange(query);
22
22
  }, [filter.analyticsEvents, handleAnalytics, onChange]);
23
23
  if (filter.type === 'search') {
24
- const { queryParamName, placeholder, onClick } = filter;
25
- return ((0, jsx_runtime_1.jsx)("div", { className: b(), children: (0, jsx_runtime_1.jsx)(SearchFilter_1.SearchFilter, { placeholder: placeholder, initialValue: initialValue, onChange: (value) => handleChange({ [queryParamName]: value }), onClick: onClick }) }));
24
+ const { queryParamName, placeholder, clickAnalyticsEvents } = filter;
25
+ return ((0, jsx_runtime_1.jsx)("div", { className: b(), children: (0, jsx_runtime_1.jsx)(SearchFilter_1.SearchFilter, { placeholder: placeholder, initialValue: initialValue, onChange: (value) => handleChange({ [queryParamName]: value }), onClick: clickAnalyticsEvents
26
+ ? () => handleAnalytics(clickAnalyticsEvents)
27
+ : undefined }) }));
26
28
  }
27
29
  if (filter.type === 'savedOnly') {
28
- const { queryParamName, onClick } = filter;
30
+ const { queryParamName, clickAnalyticsEvents } = filter;
29
31
  if (!hasLikes) {
30
32
  return null;
31
33
  }
32
34
  const handleSavedOnlyChange = (value) => {
33
- onClick === null || onClick === void 0 ? void 0 : onClick(value);
35
+ if (clickAnalyticsEvents) {
36
+ handleAnalytics(clickAnalyticsEvents, { state: value ? 'on' : 'off' });
37
+ }
34
38
  handleChange({ [queryParamName]: value ? 'true' : '', search: '' });
35
39
  };
36
40
  return ((0, jsx_runtime_1.jsx)("div", { className: b({ 'width-auto': true }), children: (0, jsx_runtime_1.jsx)(SavedOnlyFilter_1.SavedOnlyFilter, { initialValue: initialValue === 'true', onChange: handleSavedOnlyChange }) }));
37
41
  }
38
- const { queryParamName, multiple, filterable, hasClear, placeholder, options, allLabel, qa, onOpen, onClose, } = filter;
39
- return ((0, jsx_runtime_1.jsx)("div", { className: b(), children: (0, jsx_runtime_1.jsx)(SelectFilter_1.SelectFilter, { multiple: multiple, filterable: filterable, hasClear: hasClear, placeholder: placeholder, options: options, allLabel: allLabel, qa: qa, initialValue: initialValue, onChange: (value) => handleChange({ [queryParamName]: value }), onOpen: onOpen, onClose: onClose }) }));
42
+ const { queryParamName, multiple, filterable, hasClear, placeholder, options, allLabel, qa, openAnalyticsEvents, closeAnalyticsEvents, } = filter;
43
+ return ((0, jsx_runtime_1.jsx)("div", { className: b(), children: (0, jsx_runtime_1.jsx)(SelectFilter_1.SelectFilter, { multiple: multiple, filterable: filterable, hasClear: hasClear, placeholder: placeholder, options: options, allLabel: allLabel, qa: qa, initialValue: initialValue, onChange: (value) => handleChange({ [queryParamName]: value }), onOpen: openAnalyticsEvents ? () => handleAnalytics(openAnalyticsEvents) : undefined, onClose: closeAnalyticsEvents
44
+ ? ({ selectedValues, changesCount }) => handleAnalytics(closeAnalyticsEvents, {
45
+ selected_values: selectedValues.length ? selectedValues : null,
46
+ changes_count: changesCount,
47
+ count_filters: selectedValues.length,
48
+ })
49
+ : undefined }) }));
40
50
  };
41
51
  exports.FilterControl = FilterControl;
42
52
  //# sourceMappingURL=FilterControl.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"FilterControl.js","sourceRoot":"../../../../../../src","sources":["components/FeedHeader/components/FilterControl/FilterControl.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\n\nimport {useAnalytics} from '@gravity-ui/page-constructor';\n\nimport {LikesContext} from '../../../../contexts/LikesContext';\nimport {\n FilterConfig,\n Query,\n SavedOnlyFilterConfig,\n SearchFilterConfig,\n SelectFilterConfig,\n} from '../../../../models/common';\nimport {block} from '../../../../utils/cn';\nimport {SavedOnlyFilter} from '../SavedOnlyFilter/SavedOnlyFilter';\nimport {SearchFilter} from '../SearchFilter/SearchFilter';\nimport {SelectFilter} from '../SelectFilter/SelectFilter';\n\nimport './FilterControl.scss';\n\nconst b = block('filter-control');\n\nexport type FilterControlProps = {\n filter: FilterConfig;\n initialValue: string | number | null | undefined;\n onChange: (query: Query) => void;\n};\n\nexport const FilterControl = ({filter, initialValue, onChange}: FilterControlProps) => {\n const handleAnalytics = useAnalytics();\n const {hasLikes} = React.useContext(LikesContext);\n\n const handleChange = React.useCallback(\n (query: Query) => {\n if (filter.analyticsEvents) {\n handleAnalytics(filter.analyticsEvents);\n }\n onChange(query);\n },\n [filter.analyticsEvents, handleAnalytics, onChange],\n );\n\n if (filter.type === 'search') {\n const {queryParamName, placeholder, onClick} = filter as SearchFilterConfig;\n\n return (\n <div className={b()}>\n <SearchFilter\n placeholder={placeholder}\n initialValue={initialValue as string | undefined}\n onChange={(value) => handleChange({[queryParamName]: value} as Query)}\n onClick={onClick}\n />\n </div>\n );\n }\n\n if (filter.type === 'savedOnly') {\n const {queryParamName, onClick} = filter as SavedOnlyFilterConfig;\n\n if (!hasLikes) {\n return null;\n }\n\n const handleSavedOnlyChange = (value: boolean) => {\n onClick?.(value);\n handleChange({[queryParamName]: value ? 'true' : '', search: ''} as Query);\n };\n\n return (\n <div className={b({'width-auto': true})}>\n <SavedOnlyFilter\n initialValue={initialValue === 'true'}\n onChange={handleSavedOnlyChange}\n />\n </div>\n );\n }\n\n const {\n queryParamName,\n multiple,\n filterable,\n hasClear,\n placeholder,\n options,\n allLabel,\n qa,\n onOpen,\n onClose,\n } = filter as SelectFilterConfig;\n\n return (\n <div className={b()}>\n <SelectFilter\n multiple={multiple}\n filterable={filterable}\n hasClear={hasClear}\n placeholder={placeholder as string | undefined}\n options={options}\n allLabel={allLabel}\n qa={qa}\n initialValue={initialValue}\n onChange={(value) => handleChange({[queryParamName]: value} as Query)}\n onOpen={onOpen}\n onClose={onClose}\n />\n </div>\n );\n};\n"]}
1
+ {"version":3,"file":"FilterControl.js","sourceRoot":"../../../../../../src","sources":["components/FeedHeader/components/FilterControl/FilterControl.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\n\nimport {useAnalytics} from '@gravity-ui/page-constructor';\n\nimport {LikesContext} from '../../../../contexts/LikesContext';\nimport {\n FilterConfig,\n Query,\n SavedOnlyFilterConfig,\n SearchFilterConfig,\n SelectFilterConfig,\n} from '../../../../models/common';\nimport {block} from '../../../../utils/cn';\nimport {SavedOnlyFilter} from '../SavedOnlyFilter/SavedOnlyFilter';\nimport {SearchFilter} from '../SearchFilter/SearchFilter';\nimport {SelectFilter} from '../SelectFilter/SelectFilter';\n\nimport './FilterControl.scss';\n\nconst b = block('filter-control');\n\nexport type FilterControlProps = {\n filter: FilterConfig;\n initialValue: string | number | null | undefined;\n onChange: (query: Query) => void;\n};\n\nexport const FilterControl = ({filter, initialValue, onChange}: FilterControlProps) => {\n const handleAnalytics = useAnalytics();\n const {hasLikes} = React.useContext(LikesContext);\n\n const handleChange = React.useCallback(\n (query: Query) => {\n if (filter.analyticsEvents) {\n handleAnalytics(filter.analyticsEvents);\n }\n onChange(query);\n },\n [filter.analyticsEvents, handleAnalytics, onChange],\n );\n\n if (filter.type === 'search') {\n const {queryParamName, placeholder, clickAnalyticsEvents} = filter as SearchFilterConfig;\n\n return (\n <div className={b()}>\n <SearchFilter\n placeholder={placeholder}\n initialValue={initialValue as string | undefined}\n onChange={(value) => handleChange({[queryParamName]: value} as Query)}\n onClick={\n clickAnalyticsEvents\n ? () => handleAnalytics(clickAnalyticsEvents)\n : undefined\n }\n />\n </div>\n );\n }\n\n if (filter.type === 'savedOnly') {\n const {queryParamName, clickAnalyticsEvents} = filter as SavedOnlyFilterConfig;\n\n if (!hasLikes) {\n return null;\n }\n\n const handleSavedOnlyChange = (value: boolean) => {\n if (clickAnalyticsEvents) {\n handleAnalytics(clickAnalyticsEvents, {state: value ? 'on' : 'off'});\n }\n handleChange({[queryParamName]: value ? 'true' : '', search: ''} as Query);\n };\n\n return (\n <div className={b({'width-auto': true})}>\n <SavedOnlyFilter\n initialValue={initialValue === 'true'}\n onChange={handleSavedOnlyChange}\n />\n </div>\n );\n }\n\n const {\n queryParamName,\n multiple,\n filterable,\n hasClear,\n placeholder,\n options,\n allLabel,\n qa,\n openAnalyticsEvents,\n closeAnalyticsEvents,\n } = filter as SelectFilterConfig;\n\n return (\n <div className={b()}>\n <SelectFilter\n multiple={multiple}\n filterable={filterable}\n hasClear={hasClear}\n placeholder={placeholder as string | undefined}\n options={options}\n allLabel={allLabel}\n qa={qa}\n initialValue={initialValue}\n onChange={(value) => handleChange({[queryParamName]: value} as Query)}\n onOpen={\n openAnalyticsEvents ? () => handleAnalytics(openAnalyticsEvents) : undefined\n }\n onClose={\n closeAnalyticsEvents\n ? ({selectedValues, changesCount}) =>\n handleAnalytics(closeAnalyticsEvents, {\n selected_values: selectedValues.length ? selectedValues : null,\n changes_count: changesCount,\n count_filters: selectedValues.length,\n } as unknown as Record<string, string>)\n : undefined\n }\n />\n </div>\n );\n};\n"]}
@@ -10,6 +10,13 @@ const cn_1 = require("../../../../utils/cn.js");
10
10
  const customRenders_1 = require("./customRenders.js");
11
11
  const b = (0, cn_1.block)('feed-filter');
12
12
  const VIRTUALIZATION_THRESHOLD = 1000;
13
+ const getSelectedValuesChangesCount = (initial, current) => {
14
+ const initialValues = new Set(initial);
15
+ const currentValues = new Set(current);
16
+ const removedValuesCount = initial.filter((value) => !currentValues.has(value)).length;
17
+ const addedValuesCount = current.filter((value) => !initialValues.has(value)).length;
18
+ return removedValuesCount + addedValuesCount;
19
+ };
13
20
  const SelectFilter = ({ multiple, filterable, hasClear, placeholder, options, allLabel, qa, initialValue, onChange, onOpen, onClose, className, }) => {
14
21
  const isMobile = React.useContext(MobileContext_1.MobileContext);
15
22
  let defaultValue;
@@ -48,7 +55,7 @@ const SelectFilter = ({ multiple, filterable, hasClear, placeholder, options, al
48
55
  const selectedValues = [...selectedValuesRef.current];
49
56
  onClose === null || onClose === void 0 ? void 0 : onClose({
50
57
  selectedValues,
51
- selectedValuesOnOpen: [...selectedValuesOnOpenRef.current],
58
+ changesCount: getSelectedValuesChangesCount(selectedValuesOnOpenRef.current, selectedValues),
52
59
  });
53
60
  }
54
61
  isOpenRef.current = false;
@@ -1 +1 @@
1
- {"version":3,"file":"SelectFilter.js","sourceRoot":"../../../../../../src","sources":["components/FeedHeader/components/SelectFilter/SelectFilter.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\n\nimport {Select, SelectOption} from '@gravity-ui/uikit';\n\nimport {MobileContext} from '../../../../contexts/MobileContext';\nimport {SelectFilterCloseData} from '../../../../models/common';\nimport {block} from '../../../../utils/cn';\n\nimport {renderFilter, renderOption, renderSwitcher} from './customRenders';\n\nimport './SelectFilter.scss';\n\nconst b = block('feed-filter');\n\nconst VIRTUALIZATION_THRESHOLD = 1000;\n\nexport type SelectFilterProps = {\n multiple?: boolean;\n filterable?: boolean;\n hasClear?: boolean;\n placeholder?: string;\n options: SelectOption[];\n allLabel: string;\n qa?: string;\n initialValue: string | number | null | undefined;\n onChange: (value: string) => void;\n onOpen?: () => void;\n onClose?: (data: SelectFilterCloseData) => void;\n className?: string;\n};\n\nexport const SelectFilter = ({\n multiple,\n filterable,\n hasClear,\n placeholder,\n options,\n allLabel,\n qa,\n initialValue,\n onChange,\n onOpen,\n onClose,\n className,\n}: SelectFilterProps) => {\n const isMobile = React.useContext(MobileContext);\n\n let defaultValue: string[];\n if (multiple) {\n defaultValue = initialValue ? (initialValue as string).split(',') : [];\n } else {\n defaultValue =\n initialValue === null || initialValue === undefined ? [] : [`${initialValue}`];\n }\n\n const selectedValuesRef = React.useRef(defaultValue);\n const selectedValuesOnOpenRef = React.useRef(defaultValue);\n const isOpenRef = React.useRef(false);\n\n const optionsWithEmpty: SelectOption[] = multiple\n ? options\n : [{value: 'empty', content: allLabel}, ...options];\n\n const handleChange = (selectedValues: string[]) => {\n if (multiple) {\n selectedValuesRef.current = selectedValues;\n onChange(selectedValues.join(','));\n } else {\n const isEmpty = selectedValues.some((v) => v === 'empty');\n selectedValuesRef.current = isEmpty ? [] : selectedValues;\n onChange(isEmpty ? '' : selectedValues[0]);\n }\n };\n\n const handleOpenChange = (isOpen: boolean) => {\n if (isOpen) {\n selectedValuesOnOpenRef.current = [...selectedValuesRef.current];\n isOpenRef.current = true;\n onOpen?.();\n return;\n }\n\n if (isOpenRef.current) {\n const selectedValues = [...selectedValuesRef.current];\n onClose?.({\n selectedValues,\n selectedValuesOnOpen: [...selectedValuesOnOpenRef.current],\n });\n }\n\n isOpenRef.current = false;\n };\n\n return (\n <div className={className}>\n <Select\n className={b('select')}\n size=\"xl\"\n multiple={multiple}\n filterable={filterable}\n hasClear={hasClear ?? multiple}\n disablePortal\n options={optionsWithEmpty}\n defaultValue={defaultValue}\n popupClassName={b('popup', {isMobile})}\n onUpdate={handleChange}\n onOpenChange={handleOpenChange}\n placeholder={placeholder ?? allLabel}\n renderControl={renderSwitcher({\n initial: defaultValue,\n list: optionsWithEmpty,\n defaultLabel: allLabel,\n qa,\n })}\n virtualizationThreshold={VIRTUALIZATION_THRESHOLD}\n renderOption={renderOption}\n renderFilter={filterable ? renderFilter({className: b('popup-filter')}) : undefined}\n />\n </div>\n );\n};\n"]}
1
+ {"version":3,"file":"SelectFilter.js","sourceRoot":"../../../../../../src","sources":["components/FeedHeader/components/SelectFilter/SelectFilter.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\n\nimport {Select, SelectOption} from '@gravity-ui/uikit';\n\nimport {MobileContext} from '../../../../contexts/MobileContext';\nimport {SelectFilterCloseData} from '../../../../models/common';\nimport {block} from '../../../../utils/cn';\n\nimport {renderFilter, renderOption, renderSwitcher} from './customRenders';\n\nimport './SelectFilter.scss';\n\nconst b = block('feed-filter');\n\nconst VIRTUALIZATION_THRESHOLD = 1000;\n\nexport type SelectFilterProps = {\n multiple?: boolean;\n filterable?: boolean;\n hasClear?: boolean;\n placeholder?: string;\n options: SelectOption[];\n allLabel: string;\n qa?: string;\n initialValue: string | number | null | undefined;\n onChange: (value: string) => void;\n onOpen?: () => void;\n onClose?: (data: SelectFilterCloseData) => void;\n className?: string;\n};\n\nconst getSelectedValuesChangesCount = (initial: string[], current: string[]) => {\n const initialValues = new Set(initial);\n const currentValues = new Set(current);\n\n const removedValuesCount = initial.filter((value) => !currentValues.has(value)).length;\n const addedValuesCount = current.filter((value) => !initialValues.has(value)).length;\n\n return removedValuesCount + addedValuesCount;\n};\n\nexport const SelectFilter = ({\n multiple,\n filterable,\n hasClear,\n placeholder,\n options,\n allLabel,\n qa,\n initialValue,\n onChange,\n onOpen,\n onClose,\n className,\n}: SelectFilterProps) => {\n const isMobile = React.useContext(MobileContext);\n\n let defaultValue: string[];\n if (multiple) {\n defaultValue = initialValue ? (initialValue as string).split(',') : [];\n } else {\n defaultValue =\n initialValue === null || initialValue === undefined ? [] : [`${initialValue}`];\n }\n\n const selectedValuesRef = React.useRef(defaultValue);\n const selectedValuesOnOpenRef = React.useRef(defaultValue);\n const isOpenRef = React.useRef(false);\n\n const optionsWithEmpty: SelectOption[] = multiple\n ? options\n : [{value: 'empty', content: allLabel}, ...options];\n\n const handleChange = (selectedValues: string[]) => {\n if (multiple) {\n selectedValuesRef.current = selectedValues;\n onChange(selectedValues.join(','));\n } else {\n const isEmpty = selectedValues.some((v) => v === 'empty');\n selectedValuesRef.current = isEmpty ? [] : selectedValues;\n onChange(isEmpty ? '' : selectedValues[0]);\n }\n };\n\n const handleOpenChange = (isOpen: boolean) => {\n if (isOpen) {\n selectedValuesOnOpenRef.current = [...selectedValuesRef.current];\n isOpenRef.current = true;\n onOpen?.();\n return;\n }\n\n if (isOpenRef.current) {\n const selectedValues = [...selectedValuesRef.current];\n onClose?.({\n selectedValues,\n changesCount: getSelectedValuesChangesCount(\n selectedValuesOnOpenRef.current,\n selectedValues,\n ),\n });\n }\n\n isOpenRef.current = false;\n };\n\n return (\n <div className={className}>\n <Select\n className={b('select')}\n size=\"xl\"\n multiple={multiple}\n filterable={filterable}\n hasClear={hasClear ?? multiple}\n disablePortal\n options={optionsWithEmpty}\n defaultValue={defaultValue}\n popupClassName={b('popup', {isMobile})}\n onUpdate={handleChange}\n onOpenChange={handleOpenChange}\n placeholder={placeholder ?? allLabel}\n renderControl={renderSwitcher({\n initial: defaultValue,\n list: optionsWithEmpty,\n defaultLabel: allLabel,\n qa,\n })}\n virtualizationThreshold={VIRTUALIZATION_THRESHOLD}\n renderOption={renderOption}\n renderFilter={filterable ? renderFilter({className: b('popup-filter')}) : undefined}\n />\n </div>\n );\n};\n"]}
@@ -171,7 +171,7 @@ type FilterConfigBase = {
171
171
  };
172
172
  export type SelectFilterCloseData = {
173
173
  selectedValues: string[];
174
- selectedValuesOnOpen: string[];
174
+ changesCount: number;
175
175
  };
176
176
  export type SelectFilterConfig = FilterConfigBase & Pick<SelectProps, 'multiple' | 'filterable' | 'hasClear' | 'placeholder'> & {
177
177
  type?: 'select';
@@ -181,22 +181,22 @@ export type SelectFilterConfig = FilterConfigBase & Pick<SelectProps, 'multiple'
181
181
  allLabel: string;
182
182
  /** Optional QA attribute forwarded to the switcher */
183
183
  qa?: string;
184
- /** Optional callback fired when the select opens */
185
- onOpen?: () => void;
186
- /** Optional callback fired when the select closes */
187
- onClose?: (data: SelectFilterCloseData) => void;
184
+ /** Optional analytics events fired when the select opens */
185
+ openAnalyticsEvents?: AnalyticsEventsProp;
186
+ /** Optional analytics events fired when the select closes */
187
+ closeAnalyticsEvents?: AnalyticsEventsProp;
188
188
  };
189
189
  export type SearchFilterConfig = FilterConfigBase & {
190
190
  type: 'search';
191
191
  /** Placeholder text for the search input */
192
192
  placeholder?: string;
193
- /** Optional callback fired when the search input is clicked */
194
- onClick?: () => void;
193
+ /** Optional analytics events fired when the search input is clicked */
194
+ clickAnalyticsEvents?: AnalyticsEventsProp;
195
195
  };
196
196
  export type SavedOnlyFilterConfig = FilterConfigBase & {
197
197
  type: 'savedOnly';
198
- /** Optional callback fired with the next saved-only state */
199
- onClick?: (state: boolean) => void;
198
+ /** Optional analytics events fired with the next saved-only state */
199
+ clickAnalyticsEvents?: AnalyticsEventsProp;
200
200
  };
201
201
  export type FilterConfig = SelectFilterConfig | SearchFilterConfig | SavedOnlyFilterConfig;
202
202
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"common.js","sourceRoot":"../../../src","sources":["models/common.ts"],"names":[],"mappings":";;;AA6PA,wDAWC;AA3PD,IAAY,KAGX;AAHD,WAAY,KAAK;IACb,wBAAe,CAAA;IACf,sBAAa,CAAA;AACjB,CAAC,EAHW,KAAK,qBAAL,KAAK,QAGhB;AAmFD,IAAY,SAgBX;AAhBD,WAAY,SAAS;IACjB,yCAA4B,CAAA;IAC5B,mCAAsB,CAAA;IACtB,yCAA4B,CAAA;IAC5B,uCAA0B,CAAA;IAC1B,yCAA4B,CAAA;IAC5B,mCAAsB,CAAA;IACtB,oDAAuC,CAAA;IACvC,yCAA4B,CAAA;IAC5B,2CAA8B,CAAA;IAC9B,qCAAwB,CAAA;IACxB,qCAAwB,CAAA;IACxB,qCAAwB,CAAA;IACxB,sDAAyC,CAAA;IACzC,qCAAwB,CAAA;IACxB,uDAA0C,CAAA;AAC9C,CAAC,EAhBW,SAAS,yBAAT,SAAS,QAgBpB;AA8DD,IAAY,iBAUX;AAVD,WAAY,iBAAiB;IACzB,uDAAkC,CAAA;IAClC,qDAAgC,CAAA;IAChC,wDAAmC,CAAA;IACnC,kEAA6C,CAAA;IAC7C,kEAA6C,CAAA;IAC7C,kEAA6C,CAAA;IAC7C,+CAA0B,CAAA;IAC1B,uDAAkC,CAAA;IAClC,wDAAmC,CAAA;AACvC,CAAC,EAVW,iBAAiB,iCAAjB,iBAAiB,QAU5B;AAkED,SAAgB,sBAAsB,CAAC,OAAsB;IACzD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,CAAC;IACd,CAAC;IAED,2EAA2E;IAC3E,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5B,OAAO,OAA2B,CAAC;IACvC,CAAC;IAED,OAAO,CAAC,OAAyB,CAAC,CAAC;AACvC,CAAC;AAED,IAAY,YAGX;AAHD,WAAY,YAAY;IACpB,2BAAW,CAAA;IACX,4BAAY,CAAA;AAChB,CAAC,EAHW,YAAY,4BAAZ,YAAY,QAGvB;AAED,IAAY,yBAGX;AAHD,WAAY,yBAAyB;IACjC,sCAAS,CAAA;IACT,sCAAS,CAAA;AACb,CAAC,EAHW,yBAAyB,yCAAzB,yBAAyB,QAGpC","sourcesContent":["import * as React from 'react';\n\n// eslint-disable-next-line import/no-extraneous-dependencies\nimport {MarkdownItPluginCb} from '@diplodoc/transform/lib/plugins/typings';\nimport {\n AnalyticsEventsProp,\n HeaderBlockProps as PageConstructorHeaderBlockProps,\n} from '@gravity-ui/page-constructor';\nimport {SelectOption, SelectProps} from '@gravity-ui/uikit';\nimport {IBrowser, IDevice} from 'ua-parser-js';\n\nimport {Locale} from '../models/locale';\n\nexport enum Theme {\n Light = 'light',\n Dark = 'dark',\n}\n\nexport interface ClassNameProps {\n className?: string;\n}\n\nexport type Author = {\n id: number | string;\n avatar: string | null;\n createdAt: string;\n updatedAt: string;\n firstName: string | null;\n secondName: string | null;\n description: string | null;\n fullDescription: string | null;\n shortDescription: string | null;\n} & {\n [x: string]: string | null;\n};\n\nexport type Query = Record<string, number | string | null>;\n\n//page models\n\nexport interface Menu {\n title: string;\n}\n\nexport interface WithDeviceProps {\n device: IDevice;\n browser: IBrowser;\n isRobot: boolean;\n}\n\nexport interface PostsProps {\n posts: PostData[];\n count: number;\n totalCount: number;\n pinnedPost?: PostData;\n}\n\nexport type Tag = {\n slug: string;\n name: string;\n createdAt?: string;\n updatedAt?: string;\n icon?: string;\n isDeleted?: boolean;\n locale?: string;\n blogTagId?: number | string;\n count?: number;\n};\n\nexport interface PostData {\n author?: string;\n authors?: Author[];\n blogPostId?: number | string;\n content?: string;\n date: string;\n description?: string;\n hasUserLike: boolean;\n htmlTitle: string;\n id: number;\n image: string;\n isPublished?: boolean;\n sharedImage?: string;\n likes: number;\n locale: Locale;\n metaDescription?: string | null;\n metaTitle?: string | null;\n readingTime?: number;\n shareDescription?: string;\n shareImage?: string;\n shareTitle?: string;\n slug: string;\n keywords?: string[];\n tags: Tag[];\n textTitle: string;\n title: string;\n url: string;\n noIndex?: boolean;\n}\n\nexport enum BlockType {\n Header = 'blog-header-block',\n YFM = 'blog-yfm-block',\n Layout = 'blog-layout-block',\n Media = 'blog-media-block',\n Banner = 'blog-banner-block',\n CTA = 'blog-cta-block',\n ColoredText = 'blog-colored-text-block',\n Author = 'blog-author-block',\n Suggest = 'blog-suggest-block',\n Meta = 'blog-meta-block',\n Feed = 'blog-feed-block',\n Form = 'blog-form-block',\n CompactMedia = 'blog-compact-media-block',\n Take = 'blog-take-block',\n SideCardList = 'blog-side-card-list-block',\n}\n\nexport type MetaProps = {\n metaComponent: JSX.Element;\n needHelmetWrapper: boolean;\n};\n\nexport type MetaOrganizationType = {\n url: string;\n appTitle: string;\n legalName: string;\n supportEmail: string;\n};\n\nexport interface PostMetaProps {\n title: string;\n date: string;\n image: string;\n canonicalUrl: string;\n content?: string;\n description?: string;\n sharing: {\n shareTitle: string;\n shareDescription: string;\n shareImage: string;\n shareGenImage: string;\n shareGenTitle: string;\n };\n keywords?: string[];\n noIndex?: boolean;\n authors?: Author[];\n tags?: Tag[];\n organization: MetaOrganizationType;\n}\n\nexport type ToggleLikeCallbackType = ({\n postId,\n hasLike,\n}: {\n postId?: number | string;\n hasLike?: boolean;\n}) => void;\n\nexport interface HeaderBlockProps extends PageConstructorHeaderBlockProps {\n backLink?: {\n url: string;\n title: React.ReactNode;\n };\n}\n\nexport type GetPostsRequest = {\n page: number;\n perPage: number;\n savedOnly: boolean;\n search: string | undefined;\n [filterParam: string]: string | number | boolean | undefined;\n};\n\nexport type GetPostsType = (query: GetPostsRequest) => Promise<PostsProps>;\n\nexport type HandleChangeQueryParams = (params: Query) => void;\n\nexport enum DefaultEventNames {\n ShareButton = 'share-button-click',\n SaveButton = 'save-button-click',\n ShowMore = 'show-more-button-click',\n PaginatorHome = 'paginator-home-button-click',\n PaginatorNext = 'paginator-next-button-click',\n PaginatorPage = 'paginator-page-button-click',\n Tag = 'selector-tag-click',\n Service = 'selector-service-click',\n SaveOnly = 'save-only-button-click',\n}\n\nexport type FetchArgs = {\n page?: number;\n query: Query;\n};\n\nexport interface QAProps {\n qa?: string;\n}\n\ntype FilterConfigBase = {\n /** The key used in queryParams and passed to handleLoadData query */\n queryParamName: string;\n /** Optional analytics events fired when this control's value changes */\n analyticsEvents?: AnalyticsEventsProp;\n};\n\nexport type SelectFilterCloseData = {\n selectedValues: string[];\n selectedValuesOnOpen: string[];\n};\n\nexport type SelectFilterConfig = FilterConfigBase &\n Pick<SelectProps, 'multiple' | 'filterable' | 'hasClear' | 'placeholder'> & {\n type?: 'select';\n /** The selectable items for this filter */\n options: SelectOption[];\n /** Label shown when nothing is selected (acts as \"All ...\" placeholder) */\n allLabel: string;\n /** Optional QA attribute forwarded to the switcher */\n qa?: string;\n /** Optional callback fired when the select opens */\n onOpen?: () => void;\n /** Optional callback fired when the select closes */\n onClose?: (data: SelectFilterCloseData) => void;\n };\n\nexport type SearchFilterConfig = FilterConfigBase & {\n type: 'search';\n /** Placeholder text for the search input */\n placeholder?: string;\n /** Optional callback fired when the search input is clicked */\n onClick?: () => void;\n};\n\nexport type SavedOnlyFilterConfig = FilterConfigBase & {\n type: 'savedOnly';\n /** Optional callback fired with the next saved-only state */\n onClick?: (state: boolean) => void;\n};\n\nexport type FilterConfig = SelectFilterConfig | SearchFilterConfig | SavedOnlyFilterConfig;\n\n/**\n * Filters can be supplied either as a flat array (all filters in one row)\n * or as an array of rows (each inner array is rendered as a separate row).\n *\n * @example Single row (backward-compatible)\n * filters: [searchFilter, tagsFilter]\n *\n * @example Multiple rows\n * filters: [[searchFilter, savedOnlyFilter], [tagsFilter, serviceFilter]]\n */\nexport type FiltersConfig = FilterConfig[] | FilterConfig[][];\n\nexport function normalizeFiltersToRows(filters: FiltersConfig): FilterConfig[][] {\n if (filters.length === 0) {\n return [];\n }\n\n // If the first element is itself an array, the input is already multi-row.\n if (Array.isArray(filters[0])) {\n return filters as FilterConfig[][];\n }\n\n return [filters as FilterConfig[]];\n}\n\nexport enum PostCardSize {\n SMALL = 's',\n MEDIUM = 'm',\n}\n\nexport enum PostCardTitleHeadingLevel {\n H2 = 'h2',\n H3 = 'h3',\n}\n\nexport interface TransformPostOptions {\n plugins?: MarkdownItPluginCb[];\n}\n"]}
1
+ {"version":3,"file":"common.js","sourceRoot":"../../../src","sources":["models/common.ts"],"names":[],"mappings":";;;AA6PA,wDAWC;AA3PD,IAAY,KAGX;AAHD,WAAY,KAAK;IACb,wBAAe,CAAA;IACf,sBAAa,CAAA;AACjB,CAAC,EAHW,KAAK,qBAAL,KAAK,QAGhB;AAmFD,IAAY,SAgBX;AAhBD,WAAY,SAAS;IACjB,yCAA4B,CAAA;IAC5B,mCAAsB,CAAA;IACtB,yCAA4B,CAAA;IAC5B,uCAA0B,CAAA;IAC1B,yCAA4B,CAAA;IAC5B,mCAAsB,CAAA;IACtB,oDAAuC,CAAA;IACvC,yCAA4B,CAAA;IAC5B,2CAA8B,CAAA;IAC9B,qCAAwB,CAAA;IACxB,qCAAwB,CAAA;IACxB,qCAAwB,CAAA;IACxB,sDAAyC,CAAA;IACzC,qCAAwB,CAAA;IACxB,uDAA0C,CAAA;AAC9C,CAAC,EAhBW,SAAS,yBAAT,SAAS,QAgBpB;AA8DD,IAAY,iBAUX;AAVD,WAAY,iBAAiB;IACzB,uDAAkC,CAAA;IAClC,qDAAgC,CAAA;IAChC,wDAAmC,CAAA;IACnC,kEAA6C,CAAA;IAC7C,kEAA6C,CAAA;IAC7C,kEAA6C,CAAA;IAC7C,+CAA0B,CAAA;IAC1B,uDAAkC,CAAA;IAClC,wDAAmC,CAAA;AACvC,CAAC,EAVW,iBAAiB,iCAAjB,iBAAiB,QAU5B;AAkED,SAAgB,sBAAsB,CAAC,OAAsB;IACzD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,CAAC;IACd,CAAC;IAED,2EAA2E;IAC3E,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5B,OAAO,OAA2B,CAAC;IACvC,CAAC;IAED,OAAO,CAAC,OAAyB,CAAC,CAAC;AACvC,CAAC;AAED,IAAY,YAGX;AAHD,WAAY,YAAY;IACpB,2BAAW,CAAA;IACX,4BAAY,CAAA;AAChB,CAAC,EAHW,YAAY,4BAAZ,YAAY,QAGvB;AAED,IAAY,yBAGX;AAHD,WAAY,yBAAyB;IACjC,sCAAS,CAAA;IACT,sCAAS,CAAA;AACb,CAAC,EAHW,yBAAyB,yCAAzB,yBAAyB,QAGpC","sourcesContent":["import * as React from 'react';\n\n// eslint-disable-next-line import/no-extraneous-dependencies\nimport {MarkdownItPluginCb} from '@diplodoc/transform/lib/plugins/typings';\nimport {\n AnalyticsEventsProp,\n HeaderBlockProps as PageConstructorHeaderBlockProps,\n} from '@gravity-ui/page-constructor';\nimport {SelectOption, SelectProps} from '@gravity-ui/uikit';\nimport {IBrowser, IDevice} from 'ua-parser-js';\n\nimport {Locale} from '../models/locale';\n\nexport enum Theme {\n Light = 'light',\n Dark = 'dark',\n}\n\nexport interface ClassNameProps {\n className?: string;\n}\n\nexport type Author = {\n id: number | string;\n avatar: string | null;\n createdAt: string;\n updatedAt: string;\n firstName: string | null;\n secondName: string | null;\n description: string | null;\n fullDescription: string | null;\n shortDescription: string | null;\n} & {\n [x: string]: string | null;\n};\n\nexport type Query = Record<string, number | string | null>;\n\n//page models\n\nexport interface Menu {\n title: string;\n}\n\nexport interface WithDeviceProps {\n device: IDevice;\n browser: IBrowser;\n isRobot: boolean;\n}\n\nexport interface PostsProps {\n posts: PostData[];\n count: number;\n totalCount: number;\n pinnedPost?: PostData;\n}\n\nexport type Tag = {\n slug: string;\n name: string;\n createdAt?: string;\n updatedAt?: string;\n icon?: string;\n isDeleted?: boolean;\n locale?: string;\n blogTagId?: number | string;\n count?: number;\n};\n\nexport interface PostData {\n author?: string;\n authors?: Author[];\n blogPostId?: number | string;\n content?: string;\n date: string;\n description?: string;\n hasUserLike: boolean;\n htmlTitle: string;\n id: number;\n image: string;\n isPublished?: boolean;\n sharedImage?: string;\n likes: number;\n locale: Locale;\n metaDescription?: string | null;\n metaTitle?: string | null;\n readingTime?: number;\n shareDescription?: string;\n shareImage?: string;\n shareTitle?: string;\n slug: string;\n keywords?: string[];\n tags: Tag[];\n textTitle: string;\n title: string;\n url: string;\n noIndex?: boolean;\n}\n\nexport enum BlockType {\n Header = 'blog-header-block',\n YFM = 'blog-yfm-block',\n Layout = 'blog-layout-block',\n Media = 'blog-media-block',\n Banner = 'blog-banner-block',\n CTA = 'blog-cta-block',\n ColoredText = 'blog-colored-text-block',\n Author = 'blog-author-block',\n Suggest = 'blog-suggest-block',\n Meta = 'blog-meta-block',\n Feed = 'blog-feed-block',\n Form = 'blog-form-block',\n CompactMedia = 'blog-compact-media-block',\n Take = 'blog-take-block',\n SideCardList = 'blog-side-card-list-block',\n}\n\nexport type MetaProps = {\n metaComponent: JSX.Element;\n needHelmetWrapper: boolean;\n};\n\nexport type MetaOrganizationType = {\n url: string;\n appTitle: string;\n legalName: string;\n supportEmail: string;\n};\n\nexport interface PostMetaProps {\n title: string;\n date: string;\n image: string;\n canonicalUrl: string;\n content?: string;\n description?: string;\n sharing: {\n shareTitle: string;\n shareDescription: string;\n shareImage: string;\n shareGenImage: string;\n shareGenTitle: string;\n };\n keywords?: string[];\n noIndex?: boolean;\n authors?: Author[];\n tags?: Tag[];\n organization: MetaOrganizationType;\n}\n\nexport type ToggleLikeCallbackType = ({\n postId,\n hasLike,\n}: {\n postId?: number | string;\n hasLike?: boolean;\n}) => void;\n\nexport interface HeaderBlockProps extends PageConstructorHeaderBlockProps {\n backLink?: {\n url: string;\n title: React.ReactNode;\n };\n}\n\nexport type GetPostsRequest = {\n page: number;\n perPage: number;\n savedOnly: boolean;\n search: string | undefined;\n [filterParam: string]: string | number | boolean | undefined;\n};\n\nexport type GetPostsType = (query: GetPostsRequest) => Promise<PostsProps>;\n\nexport type HandleChangeQueryParams = (params: Query) => void;\n\nexport enum DefaultEventNames {\n ShareButton = 'share-button-click',\n SaveButton = 'save-button-click',\n ShowMore = 'show-more-button-click',\n PaginatorHome = 'paginator-home-button-click',\n PaginatorNext = 'paginator-next-button-click',\n PaginatorPage = 'paginator-page-button-click',\n Tag = 'selector-tag-click',\n Service = 'selector-service-click',\n SaveOnly = 'save-only-button-click',\n}\n\nexport type FetchArgs = {\n page?: number;\n query: Query;\n};\n\nexport interface QAProps {\n qa?: string;\n}\n\ntype FilterConfigBase = {\n /** The key used in queryParams and passed to handleLoadData query */\n queryParamName: string;\n /** Optional analytics events fired when this control's value changes */\n analyticsEvents?: AnalyticsEventsProp;\n};\n\nexport type SelectFilterCloseData = {\n selectedValues: string[];\n changesCount: number;\n};\n\nexport type SelectFilterConfig = FilterConfigBase &\n Pick<SelectProps, 'multiple' | 'filterable' | 'hasClear' | 'placeholder'> & {\n type?: 'select';\n /** The selectable items for this filter */\n options: SelectOption[];\n /** Label shown when nothing is selected (acts as \"All ...\" placeholder) */\n allLabel: string;\n /** Optional QA attribute forwarded to the switcher */\n qa?: string;\n /** Optional analytics events fired when the select opens */\n openAnalyticsEvents?: AnalyticsEventsProp;\n /** Optional analytics events fired when the select closes */\n closeAnalyticsEvents?: AnalyticsEventsProp;\n };\n\nexport type SearchFilterConfig = FilterConfigBase & {\n type: 'search';\n /** Placeholder text for the search input */\n placeholder?: string;\n /** Optional analytics events fired when the search input is clicked */\n clickAnalyticsEvents?: AnalyticsEventsProp;\n};\n\nexport type SavedOnlyFilterConfig = FilterConfigBase & {\n type: 'savedOnly';\n /** Optional analytics events fired with the next saved-only state */\n clickAnalyticsEvents?: AnalyticsEventsProp;\n};\n\nexport type FilterConfig = SelectFilterConfig | SearchFilterConfig | SavedOnlyFilterConfig;\n\n/**\n * Filters can be supplied either as a flat array (all filters in one row)\n * or as an array of rows (each inner array is rendered as a separate row).\n *\n * @example Single row (backward-compatible)\n * filters: [searchFilter, tagsFilter]\n *\n * @example Multiple rows\n * filters: [[searchFilter, savedOnlyFilter], [tagsFilter, serviceFilter]]\n */\nexport type FiltersConfig = FilterConfig[] | FilterConfig[][];\n\nexport function normalizeFiltersToRows(filters: FiltersConfig): FilterConfig[][] {\n if (filters.length === 0) {\n return [];\n }\n\n // If the first element is itself an array, the input is already multi-row.\n if (Array.isArray(filters[0])) {\n return filters as FilterConfig[][];\n }\n\n return [filters as FilterConfig[]];\n}\n\nexport enum PostCardSize {\n SMALL = 's',\n MEDIUM = 'm',\n}\n\nexport enum PostCardTitleHeadingLevel {\n H2 = 'h2',\n H3 = 'h3',\n}\n\nexport interface TransformPostOptions {\n plugins?: MarkdownItPluginCb[];\n}\n"]}
@@ -18,21 +18,31 @@ export const FilterControl = ({ filter, initialValue, onChange }) => {
18
18
  onChange(query);
19
19
  }, [filter.analyticsEvents, handleAnalytics, onChange]);
20
20
  if (filter.type === 'search') {
21
- const { queryParamName, placeholder, onClick } = filter;
22
- return (_jsx("div", { className: b(), children: _jsx(SearchFilter, { placeholder: placeholder, initialValue: initialValue, onChange: (value) => handleChange({ [queryParamName]: value }), onClick: onClick }) }));
21
+ const { queryParamName, placeholder, clickAnalyticsEvents } = filter;
22
+ return (_jsx("div", { className: b(), children: _jsx(SearchFilter, { placeholder: placeholder, initialValue: initialValue, onChange: (value) => handleChange({ [queryParamName]: value }), onClick: clickAnalyticsEvents
23
+ ? () => handleAnalytics(clickAnalyticsEvents)
24
+ : undefined }) }));
23
25
  }
24
26
  if (filter.type === 'savedOnly') {
25
- const { queryParamName, onClick } = filter;
27
+ const { queryParamName, clickAnalyticsEvents } = filter;
26
28
  if (!hasLikes) {
27
29
  return null;
28
30
  }
29
31
  const handleSavedOnlyChange = (value) => {
30
- onClick === null || onClick === void 0 ? void 0 : onClick(value);
32
+ if (clickAnalyticsEvents) {
33
+ handleAnalytics(clickAnalyticsEvents, { state: value ? 'on' : 'off' });
34
+ }
31
35
  handleChange({ [queryParamName]: value ? 'true' : '', search: '' });
32
36
  };
33
37
  return (_jsx("div", { className: b({ 'width-auto': true }), children: _jsx(SavedOnlyFilter, { initialValue: initialValue === 'true', onChange: handleSavedOnlyChange }) }));
34
38
  }
35
- const { queryParamName, multiple, filterable, hasClear, placeholder, options, allLabel, qa, onOpen, onClose, } = filter;
36
- return (_jsx("div", { className: b(), children: _jsx(SelectFilter, { multiple: multiple, filterable: filterable, hasClear: hasClear, placeholder: placeholder, options: options, allLabel: allLabel, qa: qa, initialValue: initialValue, onChange: (value) => handleChange({ [queryParamName]: value }), onOpen: onOpen, onClose: onClose }) }));
39
+ const { queryParamName, multiple, filterable, hasClear, placeholder, options, allLabel, qa, openAnalyticsEvents, closeAnalyticsEvents, } = filter;
40
+ return (_jsx("div", { className: b(), children: _jsx(SelectFilter, { multiple: multiple, filterable: filterable, hasClear: hasClear, placeholder: placeholder, options: options, allLabel: allLabel, qa: qa, initialValue: initialValue, onChange: (value) => handleChange({ [queryParamName]: value }), onOpen: openAnalyticsEvents ? () => handleAnalytics(openAnalyticsEvents) : undefined, onClose: closeAnalyticsEvents
41
+ ? ({ selectedValues, changesCount }) => handleAnalytics(closeAnalyticsEvents, {
42
+ selected_values: selectedValues.length ? selectedValues : null,
43
+ changes_count: changesCount,
44
+ count_filters: selectedValues.length,
45
+ })
46
+ : undefined }) }));
37
47
  };
38
48
  //# sourceMappingURL=FilterControl.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"FilterControl.js","sourceRoot":"../../../../../../src","sources":["components/FeedHeader/components/FilterControl/FilterControl.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\n\nimport {useAnalytics} from '@gravity-ui/page-constructor';\n\nimport {LikesContext} from '../../../../contexts/LikesContext';\nimport {\n FilterConfig,\n Query,\n SavedOnlyFilterConfig,\n SearchFilterConfig,\n SelectFilterConfig,\n} from '../../../../models/common';\nimport {block} from '../../../../utils/cn';\nimport {SavedOnlyFilter} from '../SavedOnlyFilter/SavedOnlyFilter';\nimport {SearchFilter} from '../SearchFilter/SearchFilter';\nimport {SelectFilter} from '../SelectFilter/SelectFilter';\n\nimport './FilterControl.scss';\n\nconst b = block('filter-control');\n\nexport type FilterControlProps = {\n filter: FilterConfig;\n initialValue: string | number | null | undefined;\n onChange: (query: Query) => void;\n};\n\nexport const FilterControl = ({filter, initialValue, onChange}: FilterControlProps) => {\n const handleAnalytics = useAnalytics();\n const {hasLikes} = React.useContext(LikesContext);\n\n const handleChange = React.useCallback(\n (query: Query) => {\n if (filter.analyticsEvents) {\n handleAnalytics(filter.analyticsEvents);\n }\n onChange(query);\n },\n [filter.analyticsEvents, handleAnalytics, onChange],\n );\n\n if (filter.type === 'search') {\n const {queryParamName, placeholder, onClick} = filter as SearchFilterConfig;\n\n return (\n <div className={b()}>\n <SearchFilter\n placeholder={placeholder}\n initialValue={initialValue as string | undefined}\n onChange={(value) => handleChange({[queryParamName]: value} as Query)}\n onClick={onClick}\n />\n </div>\n );\n }\n\n if (filter.type === 'savedOnly') {\n const {queryParamName, onClick} = filter as SavedOnlyFilterConfig;\n\n if (!hasLikes) {\n return null;\n }\n\n const handleSavedOnlyChange = (value: boolean) => {\n onClick?.(value);\n handleChange({[queryParamName]: value ? 'true' : '', search: ''} as Query);\n };\n\n return (\n <div className={b({'width-auto': true})}>\n <SavedOnlyFilter\n initialValue={initialValue === 'true'}\n onChange={handleSavedOnlyChange}\n />\n </div>\n );\n }\n\n const {\n queryParamName,\n multiple,\n filterable,\n hasClear,\n placeholder,\n options,\n allLabel,\n qa,\n onOpen,\n onClose,\n } = filter as SelectFilterConfig;\n\n return (\n <div className={b()}>\n <SelectFilter\n multiple={multiple}\n filterable={filterable}\n hasClear={hasClear}\n placeholder={placeholder as string | undefined}\n options={options}\n allLabel={allLabel}\n qa={qa}\n initialValue={initialValue}\n onChange={(value) => handleChange({[queryParamName]: value} as Query)}\n onOpen={onOpen}\n onClose={onClose}\n />\n </div>\n );\n};\n"]}
1
+ {"version":3,"file":"FilterControl.js","sourceRoot":"../../../../../../src","sources":["components/FeedHeader/components/FilterControl/FilterControl.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\n\nimport {useAnalytics} from '@gravity-ui/page-constructor';\n\nimport {LikesContext} from '../../../../contexts/LikesContext';\nimport {\n FilterConfig,\n Query,\n SavedOnlyFilterConfig,\n SearchFilterConfig,\n SelectFilterConfig,\n} from '../../../../models/common';\nimport {block} from '../../../../utils/cn';\nimport {SavedOnlyFilter} from '../SavedOnlyFilter/SavedOnlyFilter';\nimport {SearchFilter} from '../SearchFilter/SearchFilter';\nimport {SelectFilter} from '../SelectFilter/SelectFilter';\n\nimport './FilterControl.scss';\n\nconst b = block('filter-control');\n\nexport type FilterControlProps = {\n filter: FilterConfig;\n initialValue: string | number | null | undefined;\n onChange: (query: Query) => void;\n};\n\nexport const FilterControl = ({filter, initialValue, onChange}: FilterControlProps) => {\n const handleAnalytics = useAnalytics();\n const {hasLikes} = React.useContext(LikesContext);\n\n const handleChange = React.useCallback(\n (query: Query) => {\n if (filter.analyticsEvents) {\n handleAnalytics(filter.analyticsEvents);\n }\n onChange(query);\n },\n [filter.analyticsEvents, handleAnalytics, onChange],\n );\n\n if (filter.type === 'search') {\n const {queryParamName, placeholder, clickAnalyticsEvents} = filter as SearchFilterConfig;\n\n return (\n <div className={b()}>\n <SearchFilter\n placeholder={placeholder}\n initialValue={initialValue as string | undefined}\n onChange={(value) => handleChange({[queryParamName]: value} as Query)}\n onClick={\n clickAnalyticsEvents\n ? () => handleAnalytics(clickAnalyticsEvents)\n : undefined\n }\n />\n </div>\n );\n }\n\n if (filter.type === 'savedOnly') {\n const {queryParamName, clickAnalyticsEvents} = filter as SavedOnlyFilterConfig;\n\n if (!hasLikes) {\n return null;\n }\n\n const handleSavedOnlyChange = (value: boolean) => {\n if (clickAnalyticsEvents) {\n handleAnalytics(clickAnalyticsEvents, {state: value ? 'on' : 'off'});\n }\n handleChange({[queryParamName]: value ? 'true' : '', search: ''} as Query);\n };\n\n return (\n <div className={b({'width-auto': true})}>\n <SavedOnlyFilter\n initialValue={initialValue === 'true'}\n onChange={handleSavedOnlyChange}\n />\n </div>\n );\n }\n\n const {\n queryParamName,\n multiple,\n filterable,\n hasClear,\n placeholder,\n options,\n allLabel,\n qa,\n openAnalyticsEvents,\n closeAnalyticsEvents,\n } = filter as SelectFilterConfig;\n\n return (\n <div className={b()}>\n <SelectFilter\n multiple={multiple}\n filterable={filterable}\n hasClear={hasClear}\n placeholder={placeholder as string | undefined}\n options={options}\n allLabel={allLabel}\n qa={qa}\n initialValue={initialValue}\n onChange={(value) => handleChange({[queryParamName]: value} as Query)}\n onOpen={\n openAnalyticsEvents ? () => handleAnalytics(openAnalyticsEvents) : undefined\n }\n onClose={\n closeAnalyticsEvents\n ? ({selectedValues, changesCount}) =>\n handleAnalytics(closeAnalyticsEvents, {\n selected_values: selectedValues.length ? selectedValues : null,\n changes_count: changesCount,\n count_filters: selectedValues.length,\n } as unknown as Record<string, string>)\n : undefined\n }\n />\n </div>\n );\n};\n"]}
@@ -7,6 +7,13 @@ import { renderFilter, renderOption, renderSwitcher } from "./customRenders.js";
7
7
  import './SelectFilter.css';
8
8
  const b = block('feed-filter');
9
9
  const VIRTUALIZATION_THRESHOLD = 1000;
10
+ const getSelectedValuesChangesCount = (initial, current) => {
11
+ const initialValues = new Set(initial);
12
+ const currentValues = new Set(current);
13
+ const removedValuesCount = initial.filter((value) => !currentValues.has(value)).length;
14
+ const addedValuesCount = current.filter((value) => !initialValues.has(value)).length;
15
+ return removedValuesCount + addedValuesCount;
16
+ };
10
17
  export const SelectFilter = ({ multiple, filterable, hasClear, placeholder, options, allLabel, qa, initialValue, onChange, onOpen, onClose, className, }) => {
11
18
  const isMobile = React.useContext(MobileContext);
12
19
  let defaultValue;
@@ -45,7 +52,7 @@ export const SelectFilter = ({ multiple, filterable, hasClear, placeholder, opti
45
52
  const selectedValues = [...selectedValuesRef.current];
46
53
  onClose === null || onClose === void 0 ? void 0 : onClose({
47
54
  selectedValues,
48
- selectedValuesOnOpen: [...selectedValuesOnOpenRef.current],
55
+ changesCount: getSelectedValuesChangesCount(selectedValuesOnOpenRef.current, selectedValues),
49
56
  });
50
57
  }
51
58
  isOpenRef.current = false;
@@ -1 +1 @@
1
- {"version":3,"file":"SelectFilter.js","sourceRoot":"../../../../../../src","sources":["components/FeedHeader/components/SelectFilter/SelectFilter.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\n\nimport {Select, SelectOption} from '@gravity-ui/uikit';\n\nimport {MobileContext} from '../../../../contexts/MobileContext';\nimport {SelectFilterCloseData} from '../../../../models/common';\nimport {block} from '../../../../utils/cn';\n\nimport {renderFilter, renderOption, renderSwitcher} from './customRenders';\n\nimport './SelectFilter.scss';\n\nconst b = block('feed-filter');\n\nconst VIRTUALIZATION_THRESHOLD = 1000;\n\nexport type SelectFilterProps = {\n multiple?: boolean;\n filterable?: boolean;\n hasClear?: boolean;\n placeholder?: string;\n options: SelectOption[];\n allLabel: string;\n qa?: string;\n initialValue: string | number | null | undefined;\n onChange: (value: string) => void;\n onOpen?: () => void;\n onClose?: (data: SelectFilterCloseData) => void;\n className?: string;\n};\n\nexport const SelectFilter = ({\n multiple,\n filterable,\n hasClear,\n placeholder,\n options,\n allLabel,\n qa,\n initialValue,\n onChange,\n onOpen,\n onClose,\n className,\n}: SelectFilterProps) => {\n const isMobile = React.useContext(MobileContext);\n\n let defaultValue: string[];\n if (multiple) {\n defaultValue = initialValue ? (initialValue as string).split(',') : [];\n } else {\n defaultValue =\n initialValue === null || initialValue === undefined ? [] : [`${initialValue}`];\n }\n\n const selectedValuesRef = React.useRef(defaultValue);\n const selectedValuesOnOpenRef = React.useRef(defaultValue);\n const isOpenRef = React.useRef(false);\n\n const optionsWithEmpty: SelectOption[] = multiple\n ? options\n : [{value: 'empty', content: allLabel}, ...options];\n\n const handleChange = (selectedValues: string[]) => {\n if (multiple) {\n selectedValuesRef.current = selectedValues;\n onChange(selectedValues.join(','));\n } else {\n const isEmpty = selectedValues.some((v) => v === 'empty');\n selectedValuesRef.current = isEmpty ? [] : selectedValues;\n onChange(isEmpty ? '' : selectedValues[0]);\n }\n };\n\n const handleOpenChange = (isOpen: boolean) => {\n if (isOpen) {\n selectedValuesOnOpenRef.current = [...selectedValuesRef.current];\n isOpenRef.current = true;\n onOpen?.();\n return;\n }\n\n if (isOpenRef.current) {\n const selectedValues = [...selectedValuesRef.current];\n onClose?.({\n selectedValues,\n selectedValuesOnOpen: [...selectedValuesOnOpenRef.current],\n });\n }\n\n isOpenRef.current = false;\n };\n\n return (\n <div className={className}>\n <Select\n className={b('select')}\n size=\"xl\"\n multiple={multiple}\n filterable={filterable}\n hasClear={hasClear ?? multiple}\n disablePortal\n options={optionsWithEmpty}\n defaultValue={defaultValue}\n popupClassName={b('popup', {isMobile})}\n onUpdate={handleChange}\n onOpenChange={handleOpenChange}\n placeholder={placeholder ?? allLabel}\n renderControl={renderSwitcher({\n initial: defaultValue,\n list: optionsWithEmpty,\n defaultLabel: allLabel,\n qa,\n })}\n virtualizationThreshold={VIRTUALIZATION_THRESHOLD}\n renderOption={renderOption}\n renderFilter={filterable ? renderFilter({className: b('popup-filter')}) : undefined}\n />\n </div>\n );\n};\n"]}
1
+ {"version":3,"file":"SelectFilter.js","sourceRoot":"../../../../../../src","sources":["components/FeedHeader/components/SelectFilter/SelectFilter.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\n\nimport {Select, SelectOption} from '@gravity-ui/uikit';\n\nimport {MobileContext} from '../../../../contexts/MobileContext';\nimport {SelectFilterCloseData} from '../../../../models/common';\nimport {block} from '../../../../utils/cn';\n\nimport {renderFilter, renderOption, renderSwitcher} from './customRenders';\n\nimport './SelectFilter.scss';\n\nconst b = block('feed-filter');\n\nconst VIRTUALIZATION_THRESHOLD = 1000;\n\nexport type SelectFilterProps = {\n multiple?: boolean;\n filterable?: boolean;\n hasClear?: boolean;\n placeholder?: string;\n options: SelectOption[];\n allLabel: string;\n qa?: string;\n initialValue: string | number | null | undefined;\n onChange: (value: string) => void;\n onOpen?: () => void;\n onClose?: (data: SelectFilterCloseData) => void;\n className?: string;\n};\n\nconst getSelectedValuesChangesCount = (initial: string[], current: string[]) => {\n const initialValues = new Set(initial);\n const currentValues = new Set(current);\n\n const removedValuesCount = initial.filter((value) => !currentValues.has(value)).length;\n const addedValuesCount = current.filter((value) => !initialValues.has(value)).length;\n\n return removedValuesCount + addedValuesCount;\n};\n\nexport const SelectFilter = ({\n multiple,\n filterable,\n hasClear,\n placeholder,\n options,\n allLabel,\n qa,\n initialValue,\n onChange,\n onOpen,\n onClose,\n className,\n}: SelectFilterProps) => {\n const isMobile = React.useContext(MobileContext);\n\n let defaultValue: string[];\n if (multiple) {\n defaultValue = initialValue ? (initialValue as string).split(',') : [];\n } else {\n defaultValue =\n initialValue === null || initialValue === undefined ? [] : [`${initialValue}`];\n }\n\n const selectedValuesRef = React.useRef(defaultValue);\n const selectedValuesOnOpenRef = React.useRef(defaultValue);\n const isOpenRef = React.useRef(false);\n\n const optionsWithEmpty: SelectOption[] = multiple\n ? options\n : [{value: 'empty', content: allLabel}, ...options];\n\n const handleChange = (selectedValues: string[]) => {\n if (multiple) {\n selectedValuesRef.current = selectedValues;\n onChange(selectedValues.join(','));\n } else {\n const isEmpty = selectedValues.some((v) => v === 'empty');\n selectedValuesRef.current = isEmpty ? [] : selectedValues;\n onChange(isEmpty ? '' : selectedValues[0]);\n }\n };\n\n const handleOpenChange = (isOpen: boolean) => {\n if (isOpen) {\n selectedValuesOnOpenRef.current = [...selectedValuesRef.current];\n isOpenRef.current = true;\n onOpen?.();\n return;\n }\n\n if (isOpenRef.current) {\n const selectedValues = [...selectedValuesRef.current];\n onClose?.({\n selectedValues,\n changesCount: getSelectedValuesChangesCount(\n selectedValuesOnOpenRef.current,\n selectedValues,\n ),\n });\n }\n\n isOpenRef.current = false;\n };\n\n return (\n <div className={className}>\n <Select\n className={b('select')}\n size=\"xl\"\n multiple={multiple}\n filterable={filterable}\n hasClear={hasClear ?? multiple}\n disablePortal\n options={optionsWithEmpty}\n defaultValue={defaultValue}\n popupClassName={b('popup', {isMobile})}\n onUpdate={handleChange}\n onOpenChange={handleOpenChange}\n placeholder={placeholder ?? allLabel}\n renderControl={renderSwitcher({\n initial: defaultValue,\n list: optionsWithEmpty,\n defaultLabel: allLabel,\n qa,\n })}\n virtualizationThreshold={VIRTUALIZATION_THRESHOLD}\n renderOption={renderOption}\n renderFilter={filterable ? renderFilter({className: b('popup-filter')}) : undefined}\n />\n </div>\n );\n};\n"]}
@@ -171,7 +171,7 @@ type FilterConfigBase = {
171
171
  };
172
172
  export type SelectFilterCloseData = {
173
173
  selectedValues: string[];
174
- selectedValuesOnOpen: string[];
174
+ changesCount: number;
175
175
  };
176
176
  export type SelectFilterConfig = FilterConfigBase & Pick<SelectProps, 'multiple' | 'filterable' | 'hasClear' | 'placeholder'> & {
177
177
  type?: 'select';
@@ -181,22 +181,22 @@ export type SelectFilterConfig = FilterConfigBase & Pick<SelectProps, 'multiple'
181
181
  allLabel: string;
182
182
  /** Optional QA attribute forwarded to the switcher */
183
183
  qa?: string;
184
- /** Optional callback fired when the select opens */
185
- onOpen?: () => void;
186
- /** Optional callback fired when the select closes */
187
- onClose?: (data: SelectFilterCloseData) => void;
184
+ /** Optional analytics events fired when the select opens */
185
+ openAnalyticsEvents?: AnalyticsEventsProp;
186
+ /** Optional analytics events fired when the select closes */
187
+ closeAnalyticsEvents?: AnalyticsEventsProp;
188
188
  };
189
189
  export type SearchFilterConfig = FilterConfigBase & {
190
190
  type: 'search';
191
191
  /** Placeholder text for the search input */
192
192
  placeholder?: string;
193
- /** Optional callback fired when the search input is clicked */
194
- onClick?: () => void;
193
+ /** Optional analytics events fired when the search input is clicked */
194
+ clickAnalyticsEvents?: AnalyticsEventsProp;
195
195
  };
196
196
  export type SavedOnlyFilterConfig = FilterConfigBase & {
197
197
  type: 'savedOnly';
198
- /** Optional callback fired with the next saved-only state */
199
- onClick?: (state: boolean) => void;
198
+ /** Optional analytics events fired with the next saved-only state */
199
+ clickAnalyticsEvents?: AnalyticsEventsProp;
200
200
  };
201
201
  export type FilterConfig = SelectFilterConfig | SearchFilterConfig | SavedOnlyFilterConfig;
202
202
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"common.js","sourceRoot":"../../../src","sources":["models/common.ts"],"names":[],"mappings":"AAaA,MAAM,CAAN,IAAY,KAGX;AAHD,WAAY,KAAK;IACb,wBAAe,CAAA;IACf,sBAAa,CAAA;AACjB,CAAC,EAHW,KAAK,KAAL,KAAK,QAGhB;AAmFD,MAAM,CAAN,IAAY,SAgBX;AAhBD,WAAY,SAAS;IACjB,yCAA4B,CAAA;IAC5B,mCAAsB,CAAA;IACtB,yCAA4B,CAAA;IAC5B,uCAA0B,CAAA;IAC1B,yCAA4B,CAAA;IAC5B,mCAAsB,CAAA;IACtB,oDAAuC,CAAA;IACvC,yCAA4B,CAAA;IAC5B,2CAA8B,CAAA;IAC9B,qCAAwB,CAAA;IACxB,qCAAwB,CAAA;IACxB,qCAAwB,CAAA;IACxB,sDAAyC,CAAA;IACzC,qCAAwB,CAAA;IACxB,uDAA0C,CAAA;AAC9C,CAAC,EAhBW,SAAS,KAAT,SAAS,QAgBpB;AA8DD,MAAM,CAAN,IAAY,iBAUX;AAVD,WAAY,iBAAiB;IACzB,uDAAkC,CAAA;IAClC,qDAAgC,CAAA;IAChC,wDAAmC,CAAA;IACnC,kEAA6C,CAAA;IAC7C,kEAA6C,CAAA;IAC7C,kEAA6C,CAAA;IAC7C,+CAA0B,CAAA;IAC1B,uDAAkC,CAAA;IAClC,wDAAmC,CAAA;AACvC,CAAC,EAVW,iBAAiB,KAAjB,iBAAiB,QAU5B;AAkED,MAAM,UAAU,sBAAsB,CAAC,OAAsB;IACzD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,CAAC;IACd,CAAC;IAED,2EAA2E;IAC3E,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5B,OAAO,OAA2B,CAAC;IACvC,CAAC;IAED,OAAO,CAAC,OAAyB,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,CAAN,IAAY,YAGX;AAHD,WAAY,YAAY;IACpB,2BAAW,CAAA;IACX,4BAAY,CAAA;AAChB,CAAC,EAHW,YAAY,KAAZ,YAAY,QAGvB;AAED,MAAM,CAAN,IAAY,yBAGX;AAHD,WAAY,yBAAyB;IACjC,sCAAS,CAAA;IACT,sCAAS,CAAA;AACb,CAAC,EAHW,yBAAyB,KAAzB,yBAAyB,QAGpC","sourcesContent":["import * as React from 'react';\n\n// eslint-disable-next-line import/no-extraneous-dependencies\nimport {MarkdownItPluginCb} from '@diplodoc/transform/lib/plugins/typings';\nimport {\n AnalyticsEventsProp,\n HeaderBlockProps as PageConstructorHeaderBlockProps,\n} from '@gravity-ui/page-constructor';\nimport {SelectOption, SelectProps} from '@gravity-ui/uikit';\nimport {IBrowser, IDevice} from 'ua-parser-js';\n\nimport {Locale} from '../models/locale';\n\nexport enum Theme {\n Light = 'light',\n Dark = 'dark',\n}\n\nexport interface ClassNameProps {\n className?: string;\n}\n\nexport type Author = {\n id: number | string;\n avatar: string | null;\n createdAt: string;\n updatedAt: string;\n firstName: string | null;\n secondName: string | null;\n description: string | null;\n fullDescription: string | null;\n shortDescription: string | null;\n} & {\n [x: string]: string | null;\n};\n\nexport type Query = Record<string, number | string | null>;\n\n//page models\n\nexport interface Menu {\n title: string;\n}\n\nexport interface WithDeviceProps {\n device: IDevice;\n browser: IBrowser;\n isRobot: boolean;\n}\n\nexport interface PostsProps {\n posts: PostData[];\n count: number;\n totalCount: number;\n pinnedPost?: PostData;\n}\n\nexport type Tag = {\n slug: string;\n name: string;\n createdAt?: string;\n updatedAt?: string;\n icon?: string;\n isDeleted?: boolean;\n locale?: string;\n blogTagId?: number | string;\n count?: number;\n};\n\nexport interface PostData {\n author?: string;\n authors?: Author[];\n blogPostId?: number | string;\n content?: string;\n date: string;\n description?: string;\n hasUserLike: boolean;\n htmlTitle: string;\n id: number;\n image: string;\n isPublished?: boolean;\n sharedImage?: string;\n likes: number;\n locale: Locale;\n metaDescription?: string | null;\n metaTitle?: string | null;\n readingTime?: number;\n shareDescription?: string;\n shareImage?: string;\n shareTitle?: string;\n slug: string;\n keywords?: string[];\n tags: Tag[];\n textTitle: string;\n title: string;\n url: string;\n noIndex?: boolean;\n}\n\nexport enum BlockType {\n Header = 'blog-header-block',\n YFM = 'blog-yfm-block',\n Layout = 'blog-layout-block',\n Media = 'blog-media-block',\n Banner = 'blog-banner-block',\n CTA = 'blog-cta-block',\n ColoredText = 'blog-colored-text-block',\n Author = 'blog-author-block',\n Suggest = 'blog-suggest-block',\n Meta = 'blog-meta-block',\n Feed = 'blog-feed-block',\n Form = 'blog-form-block',\n CompactMedia = 'blog-compact-media-block',\n Take = 'blog-take-block',\n SideCardList = 'blog-side-card-list-block',\n}\n\nexport type MetaProps = {\n metaComponent: JSX.Element;\n needHelmetWrapper: boolean;\n};\n\nexport type MetaOrganizationType = {\n url: string;\n appTitle: string;\n legalName: string;\n supportEmail: string;\n};\n\nexport interface PostMetaProps {\n title: string;\n date: string;\n image: string;\n canonicalUrl: string;\n content?: string;\n description?: string;\n sharing: {\n shareTitle: string;\n shareDescription: string;\n shareImage: string;\n shareGenImage: string;\n shareGenTitle: string;\n };\n keywords?: string[];\n noIndex?: boolean;\n authors?: Author[];\n tags?: Tag[];\n organization: MetaOrganizationType;\n}\n\nexport type ToggleLikeCallbackType = ({\n postId,\n hasLike,\n}: {\n postId?: number | string;\n hasLike?: boolean;\n}) => void;\n\nexport interface HeaderBlockProps extends PageConstructorHeaderBlockProps {\n backLink?: {\n url: string;\n title: React.ReactNode;\n };\n}\n\nexport type GetPostsRequest = {\n page: number;\n perPage: number;\n savedOnly: boolean;\n search: string | undefined;\n [filterParam: string]: string | number | boolean | undefined;\n};\n\nexport type GetPostsType = (query: GetPostsRequest) => Promise<PostsProps>;\n\nexport type HandleChangeQueryParams = (params: Query) => void;\n\nexport enum DefaultEventNames {\n ShareButton = 'share-button-click',\n SaveButton = 'save-button-click',\n ShowMore = 'show-more-button-click',\n PaginatorHome = 'paginator-home-button-click',\n PaginatorNext = 'paginator-next-button-click',\n PaginatorPage = 'paginator-page-button-click',\n Tag = 'selector-tag-click',\n Service = 'selector-service-click',\n SaveOnly = 'save-only-button-click',\n}\n\nexport type FetchArgs = {\n page?: number;\n query: Query;\n};\n\nexport interface QAProps {\n qa?: string;\n}\n\ntype FilterConfigBase = {\n /** The key used in queryParams and passed to handleLoadData query */\n queryParamName: string;\n /** Optional analytics events fired when this control's value changes */\n analyticsEvents?: AnalyticsEventsProp;\n};\n\nexport type SelectFilterCloseData = {\n selectedValues: string[];\n selectedValuesOnOpen: string[];\n};\n\nexport type SelectFilterConfig = FilterConfigBase &\n Pick<SelectProps, 'multiple' | 'filterable' | 'hasClear' | 'placeholder'> & {\n type?: 'select';\n /** The selectable items for this filter */\n options: SelectOption[];\n /** Label shown when nothing is selected (acts as \"All ...\" placeholder) */\n allLabel: string;\n /** Optional QA attribute forwarded to the switcher */\n qa?: string;\n /** Optional callback fired when the select opens */\n onOpen?: () => void;\n /** Optional callback fired when the select closes */\n onClose?: (data: SelectFilterCloseData) => void;\n };\n\nexport type SearchFilterConfig = FilterConfigBase & {\n type: 'search';\n /** Placeholder text for the search input */\n placeholder?: string;\n /** Optional callback fired when the search input is clicked */\n onClick?: () => void;\n};\n\nexport type SavedOnlyFilterConfig = FilterConfigBase & {\n type: 'savedOnly';\n /** Optional callback fired with the next saved-only state */\n onClick?: (state: boolean) => void;\n};\n\nexport type FilterConfig = SelectFilterConfig | SearchFilterConfig | SavedOnlyFilterConfig;\n\n/**\n * Filters can be supplied either as a flat array (all filters in one row)\n * or as an array of rows (each inner array is rendered as a separate row).\n *\n * @example Single row (backward-compatible)\n * filters: [searchFilter, tagsFilter]\n *\n * @example Multiple rows\n * filters: [[searchFilter, savedOnlyFilter], [tagsFilter, serviceFilter]]\n */\nexport type FiltersConfig = FilterConfig[] | FilterConfig[][];\n\nexport function normalizeFiltersToRows(filters: FiltersConfig): FilterConfig[][] {\n if (filters.length === 0) {\n return [];\n }\n\n // If the first element is itself an array, the input is already multi-row.\n if (Array.isArray(filters[0])) {\n return filters as FilterConfig[][];\n }\n\n return [filters as FilterConfig[]];\n}\n\nexport enum PostCardSize {\n SMALL = 's',\n MEDIUM = 'm',\n}\n\nexport enum PostCardTitleHeadingLevel {\n H2 = 'h2',\n H3 = 'h3',\n}\n\nexport interface TransformPostOptions {\n plugins?: MarkdownItPluginCb[];\n}\n"]}
1
+ {"version":3,"file":"common.js","sourceRoot":"../../../src","sources":["models/common.ts"],"names":[],"mappings":"AAaA,MAAM,CAAN,IAAY,KAGX;AAHD,WAAY,KAAK;IACb,wBAAe,CAAA;IACf,sBAAa,CAAA;AACjB,CAAC,EAHW,KAAK,KAAL,KAAK,QAGhB;AAmFD,MAAM,CAAN,IAAY,SAgBX;AAhBD,WAAY,SAAS;IACjB,yCAA4B,CAAA;IAC5B,mCAAsB,CAAA;IACtB,yCAA4B,CAAA;IAC5B,uCAA0B,CAAA;IAC1B,yCAA4B,CAAA;IAC5B,mCAAsB,CAAA;IACtB,oDAAuC,CAAA;IACvC,yCAA4B,CAAA;IAC5B,2CAA8B,CAAA;IAC9B,qCAAwB,CAAA;IACxB,qCAAwB,CAAA;IACxB,qCAAwB,CAAA;IACxB,sDAAyC,CAAA;IACzC,qCAAwB,CAAA;IACxB,uDAA0C,CAAA;AAC9C,CAAC,EAhBW,SAAS,KAAT,SAAS,QAgBpB;AA8DD,MAAM,CAAN,IAAY,iBAUX;AAVD,WAAY,iBAAiB;IACzB,uDAAkC,CAAA;IAClC,qDAAgC,CAAA;IAChC,wDAAmC,CAAA;IACnC,kEAA6C,CAAA;IAC7C,kEAA6C,CAAA;IAC7C,kEAA6C,CAAA;IAC7C,+CAA0B,CAAA;IAC1B,uDAAkC,CAAA;IAClC,wDAAmC,CAAA;AACvC,CAAC,EAVW,iBAAiB,KAAjB,iBAAiB,QAU5B;AAkED,MAAM,UAAU,sBAAsB,CAAC,OAAsB;IACzD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,CAAC;IACd,CAAC;IAED,2EAA2E;IAC3E,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5B,OAAO,OAA2B,CAAC;IACvC,CAAC;IAED,OAAO,CAAC,OAAyB,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,CAAN,IAAY,YAGX;AAHD,WAAY,YAAY;IACpB,2BAAW,CAAA;IACX,4BAAY,CAAA;AAChB,CAAC,EAHW,YAAY,KAAZ,YAAY,QAGvB;AAED,MAAM,CAAN,IAAY,yBAGX;AAHD,WAAY,yBAAyB;IACjC,sCAAS,CAAA;IACT,sCAAS,CAAA;AACb,CAAC,EAHW,yBAAyB,KAAzB,yBAAyB,QAGpC","sourcesContent":["import * as React from 'react';\n\n// eslint-disable-next-line import/no-extraneous-dependencies\nimport {MarkdownItPluginCb} from '@diplodoc/transform/lib/plugins/typings';\nimport {\n AnalyticsEventsProp,\n HeaderBlockProps as PageConstructorHeaderBlockProps,\n} from '@gravity-ui/page-constructor';\nimport {SelectOption, SelectProps} from '@gravity-ui/uikit';\nimport {IBrowser, IDevice} from 'ua-parser-js';\n\nimport {Locale} from '../models/locale';\n\nexport enum Theme {\n Light = 'light',\n Dark = 'dark',\n}\n\nexport interface ClassNameProps {\n className?: string;\n}\n\nexport type Author = {\n id: number | string;\n avatar: string | null;\n createdAt: string;\n updatedAt: string;\n firstName: string | null;\n secondName: string | null;\n description: string | null;\n fullDescription: string | null;\n shortDescription: string | null;\n} & {\n [x: string]: string | null;\n};\n\nexport type Query = Record<string, number | string | null>;\n\n//page models\n\nexport interface Menu {\n title: string;\n}\n\nexport interface WithDeviceProps {\n device: IDevice;\n browser: IBrowser;\n isRobot: boolean;\n}\n\nexport interface PostsProps {\n posts: PostData[];\n count: number;\n totalCount: number;\n pinnedPost?: PostData;\n}\n\nexport type Tag = {\n slug: string;\n name: string;\n createdAt?: string;\n updatedAt?: string;\n icon?: string;\n isDeleted?: boolean;\n locale?: string;\n blogTagId?: number | string;\n count?: number;\n};\n\nexport interface PostData {\n author?: string;\n authors?: Author[];\n blogPostId?: number | string;\n content?: string;\n date: string;\n description?: string;\n hasUserLike: boolean;\n htmlTitle: string;\n id: number;\n image: string;\n isPublished?: boolean;\n sharedImage?: string;\n likes: number;\n locale: Locale;\n metaDescription?: string | null;\n metaTitle?: string | null;\n readingTime?: number;\n shareDescription?: string;\n shareImage?: string;\n shareTitle?: string;\n slug: string;\n keywords?: string[];\n tags: Tag[];\n textTitle: string;\n title: string;\n url: string;\n noIndex?: boolean;\n}\n\nexport enum BlockType {\n Header = 'blog-header-block',\n YFM = 'blog-yfm-block',\n Layout = 'blog-layout-block',\n Media = 'blog-media-block',\n Banner = 'blog-banner-block',\n CTA = 'blog-cta-block',\n ColoredText = 'blog-colored-text-block',\n Author = 'blog-author-block',\n Suggest = 'blog-suggest-block',\n Meta = 'blog-meta-block',\n Feed = 'blog-feed-block',\n Form = 'blog-form-block',\n CompactMedia = 'blog-compact-media-block',\n Take = 'blog-take-block',\n SideCardList = 'blog-side-card-list-block',\n}\n\nexport type MetaProps = {\n metaComponent: JSX.Element;\n needHelmetWrapper: boolean;\n};\n\nexport type MetaOrganizationType = {\n url: string;\n appTitle: string;\n legalName: string;\n supportEmail: string;\n};\n\nexport interface PostMetaProps {\n title: string;\n date: string;\n image: string;\n canonicalUrl: string;\n content?: string;\n description?: string;\n sharing: {\n shareTitle: string;\n shareDescription: string;\n shareImage: string;\n shareGenImage: string;\n shareGenTitle: string;\n };\n keywords?: string[];\n noIndex?: boolean;\n authors?: Author[];\n tags?: Tag[];\n organization: MetaOrganizationType;\n}\n\nexport type ToggleLikeCallbackType = ({\n postId,\n hasLike,\n}: {\n postId?: number | string;\n hasLike?: boolean;\n}) => void;\n\nexport interface HeaderBlockProps extends PageConstructorHeaderBlockProps {\n backLink?: {\n url: string;\n title: React.ReactNode;\n };\n}\n\nexport type GetPostsRequest = {\n page: number;\n perPage: number;\n savedOnly: boolean;\n search: string | undefined;\n [filterParam: string]: string | number | boolean | undefined;\n};\n\nexport type GetPostsType = (query: GetPostsRequest) => Promise<PostsProps>;\n\nexport type HandleChangeQueryParams = (params: Query) => void;\n\nexport enum DefaultEventNames {\n ShareButton = 'share-button-click',\n SaveButton = 'save-button-click',\n ShowMore = 'show-more-button-click',\n PaginatorHome = 'paginator-home-button-click',\n PaginatorNext = 'paginator-next-button-click',\n PaginatorPage = 'paginator-page-button-click',\n Tag = 'selector-tag-click',\n Service = 'selector-service-click',\n SaveOnly = 'save-only-button-click',\n}\n\nexport type FetchArgs = {\n page?: number;\n query: Query;\n};\n\nexport interface QAProps {\n qa?: string;\n}\n\ntype FilterConfigBase = {\n /** The key used in queryParams and passed to handleLoadData query */\n queryParamName: string;\n /** Optional analytics events fired when this control's value changes */\n analyticsEvents?: AnalyticsEventsProp;\n};\n\nexport type SelectFilterCloseData = {\n selectedValues: string[];\n changesCount: number;\n};\n\nexport type SelectFilterConfig = FilterConfigBase &\n Pick<SelectProps, 'multiple' | 'filterable' | 'hasClear' | 'placeholder'> & {\n type?: 'select';\n /** The selectable items for this filter */\n options: SelectOption[];\n /** Label shown when nothing is selected (acts as \"All ...\" placeholder) */\n allLabel: string;\n /** Optional QA attribute forwarded to the switcher */\n qa?: string;\n /** Optional analytics events fired when the select opens */\n openAnalyticsEvents?: AnalyticsEventsProp;\n /** Optional analytics events fired when the select closes */\n closeAnalyticsEvents?: AnalyticsEventsProp;\n };\n\nexport type SearchFilterConfig = FilterConfigBase & {\n type: 'search';\n /** Placeholder text for the search input */\n placeholder?: string;\n /** Optional analytics events fired when the search input is clicked */\n clickAnalyticsEvents?: AnalyticsEventsProp;\n};\n\nexport type SavedOnlyFilterConfig = FilterConfigBase & {\n type: 'savedOnly';\n /** Optional analytics events fired with the next saved-only state */\n clickAnalyticsEvents?: AnalyticsEventsProp;\n};\n\nexport type FilterConfig = SelectFilterConfig | SearchFilterConfig | SavedOnlyFilterConfig;\n\n/**\n * Filters can be supplied either as a flat array (all filters in one row)\n * or as an array of rows (each inner array is rendered as a separate row).\n *\n * @example Single row (backward-compatible)\n * filters: [searchFilter, tagsFilter]\n *\n * @example Multiple rows\n * filters: [[searchFilter, savedOnlyFilter], [tagsFilter, serviceFilter]]\n */\nexport type FiltersConfig = FilterConfig[] | FilterConfig[][];\n\nexport function normalizeFiltersToRows(filters: FiltersConfig): FilterConfig[][] {\n if (filters.length === 0) {\n return [];\n }\n\n // If the first element is itself an array, the input is already multi-row.\n if (Array.isArray(filters[0])) {\n return filters as FilterConfig[][];\n }\n\n return [filters as FilterConfig[]];\n}\n\nexport enum PostCardSize {\n SMALL = 's',\n MEDIUM = 'm',\n}\n\nexport enum PostCardTitleHeadingLevel {\n H2 = 'h2',\n H3 = 'h3',\n}\n\nexport interface TransformPostOptions {\n plugins?: MarkdownItPluginCb[];\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ui/blog-constructor",
3
- "version": "10.1.1-alpha.0",
3
+ "version": "10.1.1-alpha.2",
4
4
  "description": "Gravity UI Blog Constructor",
5
5
  "license": "MIT",
6
6
  "type": "commonjs",
@@ -171,7 +171,7 @@ type FilterConfigBase = {
171
171
  };
172
172
  export type SelectFilterCloseData = {
173
173
  selectedValues: string[];
174
- selectedValuesOnOpen: string[];
174
+ changesCount: number;
175
175
  };
176
176
  export type SelectFilterConfig = FilterConfigBase & Pick<SelectProps, 'multiple' | 'filterable' | 'hasClear' | 'placeholder'> & {
177
177
  type?: 'select';
@@ -181,22 +181,22 @@ export type SelectFilterConfig = FilterConfigBase & Pick<SelectProps, 'multiple'
181
181
  allLabel: string;
182
182
  /** Optional QA attribute forwarded to the switcher */
183
183
  qa?: string;
184
- /** Optional callback fired when the select opens */
185
- onOpen?: () => void;
186
- /** Optional callback fired when the select closes */
187
- onClose?: (data: SelectFilterCloseData) => void;
184
+ /** Optional analytics events fired when the select opens */
185
+ openAnalyticsEvents?: AnalyticsEventsProp;
186
+ /** Optional analytics events fired when the select closes */
187
+ closeAnalyticsEvents?: AnalyticsEventsProp;
188
188
  };
189
189
  export type SearchFilterConfig = FilterConfigBase & {
190
190
  type: 'search';
191
191
  /** Placeholder text for the search input */
192
192
  placeholder?: string;
193
- /** Optional callback fired when the search input is clicked */
194
- onClick?: () => void;
193
+ /** Optional analytics events fired when the search input is clicked */
194
+ clickAnalyticsEvents?: AnalyticsEventsProp;
195
195
  };
196
196
  export type SavedOnlyFilterConfig = FilterConfigBase & {
197
197
  type: 'savedOnly';
198
- /** Optional callback fired with the next saved-only state */
199
- onClick?: (state: boolean) => void;
198
+ /** Optional analytics events fired with the next saved-only state */
199
+ clickAnalyticsEvents?: AnalyticsEventsProp;
200
200
  };
201
201
  export type FilterConfig = SelectFilterConfig | SearchFilterConfig | SavedOnlyFilterConfig;
202
202
  /**