@evergis/react 4.0.159 → 4.0.162

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/components/Dashboard/componentTypes.d.ts +6 -6
  2. package/dist/components/Dashboard/constants.d.ts +25 -3
  3. package/dist/components/Dashboard/containers/FiltersContainer/utils/getFilterWidth.d.ts +2 -3
  4. package/dist/components/Dashboard/elements/ElementControl/hooks/useFirstNonEmptyValue.d.ts +6 -0
  5. package/dist/components/Dashboard/elements/ElementModal/hooks/useModalContent.d.ts +2 -2
  6. package/dist/components/Dashboard/elements/ElementTable/utils/tableBox.d.ts +2 -2
  7. package/dist/components/Dashboard/hooks/index.d.ts +2 -0
  8. package/dist/components/Dashboard/hooks/useConfigStringSources.d.ts +8 -0
  9. package/dist/components/Dashboard/hooks/useDashboardFilterStore.d.ts +9 -0
  10. package/dist/components/Dashboard/hooks/useEqualTileWidth.d.ts +1 -1
  11. package/dist/components/Dashboard/hooks/useWidgetPage.d.ts +3 -0
  12. package/dist/components/Dashboard/hooks/useWrapperSize.d.ts +3 -3
  13. package/dist/components/Dashboard/styled/containers.d.ts +5 -6
  14. package/dist/components/Dashboard/styled/index.d.ts +2 -3
  15. package/dist/components/Dashboard/types.d.ts +33 -2
  16. package/dist/components/Dashboard/utils/applyQueryFilters.d.ts +4 -3
  17. package/dist/components/Dashboard/utils/chartAxis.d.ts +1 -1
  18. package/dist/components/Dashboard/utils/configString/formatConditionString.d.ts +18 -0
  19. package/dist/components/Dashboard/utils/configString/formatters.d.ts +16 -0
  20. package/dist/components/Dashboard/utils/configString/getFilterTokenValue.d.ts +13 -0
  21. package/dist/components/Dashboard/utils/configString/index.d.ts +10 -0
  22. package/dist/components/Dashboard/utils/configString/isDashboardReference.d.ts +2 -0
  23. package/dist/components/Dashboard/utils/configString/referencesFilters.d.ts +11 -0
  24. package/dist/components/Dashboard/utils/configString/resolveConfigToken.d.ts +3 -0
  25. package/dist/components/Dashboard/utils/configString/resolveElementStrings.d.ts +8 -0
  26. package/dist/components/Dashboard/utils/configString/resolveFilterDefaults.d.ts +8 -0
  27. package/dist/components/Dashboard/utils/configString/tokenizeConfigString.d.ts +5 -0
  28. package/dist/components/Dashboard/utils/configString/types.d.ts +78 -0
  29. package/dist/components/Dashboard/utils/formatDataSourceCondition.d.ts +16 -23
  30. package/dist/components/Dashboard/utils/getChangedFilterNames.d.ts +8 -0
  31. package/dist/components/Dashboard/utils/getPageFilters.d.ts +3 -0
  32. package/dist/components/Dashboard/utils/getRenderElement.d.ts +1 -1
  33. package/dist/components/Dashboard/utils/index.d.ts +4 -0
  34. package/dist/components/Dashboard/utils/selectUpdatingDataSources.d.ts +21 -0
  35. package/dist/index.js +900 -559
  36. package/dist/index.js.map +1 -1
  37. package/dist/react.esm.js +879 -560
  38. package/dist/react.esm.js.map +1 -1
  39. package/package.json +11 -4
@@ -537,16 +537,16 @@ export interface FeatureCardSlideshowHeaderConfig extends Omit<ConfigContainerHe
537
537
  * Каждая ветвь — `<Name>Config` с литеральным дискриминатором. При наличии `templateName` или `type`
538
538
  * у конкретного значения TS сразу сужает union до соответствующей ветви и проверяет поля `options`.
539
539
  *
540
- * Поскольку оба поля помечены как опциональные (`?`), значения **без** дискриминатора по-прежнему
541
- * приемлемы для любой ветви — это переходная мягкая совместимость с legacy-конфигами.
540
+ * Поскольку оба поля помечены как опциональные (`?`), значения **без** дискриминатора приемлемы
541
+ * для любой ветви — так тип принимает и конфиги, где дискриминатор не указан.
542
542
  */
543
543
  export type DashboardChild = ElementButtonConfig | ElementCameraConfig | ElementChartConfig | ElementChipsConfig | ElementControlConfig | ElementIconConfig | ElementImageConfig | ElementLegendConfig | ElementLinkConfig | ElementMarkdownConfig | ElementModalConfig | ElementSlideshowConfig | ElementSvgConfig | ElementTableConfig | ElementTooltipConfig | ElementUploaderConfig | AddFeatureContainerConfig | AttachmentContainerConfig | CameraContainerConfig | ChartContainerConfig | ContainersGroupContainerConfig | DataSourceContainerConfig | DataSourceProgressContainerConfig | DefaultAttributesContainerConfig | DividerContainerElementConfig | EditContainerConfig | EditGroupContainerConfig | EditBooleanContainerConfig | EditStringContainerConfig | EditNumberContainerConfig | EditDropdownContainerConfig | EditChipsContainerConfig | EditCheckboxContainerConfig | EditDateContainerConfig | EditAttachmentContainerConfig | ExportPdfContainerConfig | FiltersContainerConfig | GridRowContainerConfig | IconContainerConfig | ImageContainerConfig | LayersContainerConfig | OneColumnContainerConfig | ProgressContainerConfig | RoundedBackgroundContainerConfig | SlideshowContainerConfig | StructuredDataContainerConfig | TabsContainerConfig | TaskContainerConfig | TitleContainerConfig | TwoColumnContainerConfig | UploadContainerConfig | VoteContainerConfig;
544
544
  /**
545
545
  * Строгий authoring-тип узла конфига. В отличие от мягкого {@link ConfigContainerChild}
546
- * (`id?` — опционален ради legacy-совместимости), здесь `id` **обязателен** и рекурсивно
547
- * требуется у всех потомков в `children`. Предназначен для авторинга НОВЫХ конфигов и примеров
546
+ * (`id?` опционален, чтобы рантайм принимал любые конфиги), здесь `id` **обязателен** и рекурсивно
547
+ * требуется у всех потомков в `children`. Предназначен для авторинга конфигов и примеров
548
548
  * в документации: `ts-check` ловит пропуск `id` на любой глубине. Базовый
549
- * {@link ConfigContainerChild} остаётся мягким — на нём держится рантайм/legacy-парсер.
549
+ * {@link ConfigContainerChild} остаётся мягким — на нём держится рантайм-парсер.
550
550
  *
551
551
  * @example
552
552
  * const child: StrictConfigContainerChild = {
@@ -581,7 +581,7 @@ export type DashboardHeaderConfig = DashboardDefaultHeaderConfig | FeatureCardBa
581
581
  * Карта `ContainerTemplate` → `<Name>ContainerProps`. Используется для типобезопасного
582
582
  * `containers/registry.ts`, фабрики `getContainerComponent` и Code Connect Figma.
583
583
  *
584
- * `Progress` и `RoundedBackground` исторически используют `InnerContainerProps` (см.
584
+ * `Progress` и `RoundedBackground` принимают `InnerContainerProps` (см.
585
585
  * `containers/DataSourceInnerContainer/types.ts`). В сигнатуре регистрации это переживёт
586
586
  * благодаря contravariance `FC<P>`: `FC<InnerContainerProps>` совместим с `FC<<Name>Props>`,
587
587
  * пока `<Name>Props` ⊆ `InnerContainerProps`.
@@ -101,9 +101,31 @@ export declare const PROJECT_ALIAS_PROP = "alias";
101
101
  export declare const PROJECT_PROPS: string[];
102
102
  export declare const PROVIDER_PREFIX = "$";
103
103
  export declare enum ProviderPrefix {
104
+ /** `$card:<слой>:<поле>` — атрибут объекта карточки. */
104
105
  Card = "card",
105
- Left = "left"
106
+ /**
107
+ * Ближайший дашборд, в ряд к `%` своего виджета: `$dashboard:<фильтр>[.свойство]` — его фильтр,
108
+ * `$dashboard:<датасорс>:<поле>` — поле первой строки его датасорса.
109
+ */
110
+ Dashboard = "dashboard"
106
111
  }
112
+ /**
113
+ * Все подстановки строки конфига одной грамматикой, по группам:
114
+ * 1–2 `$dashboard:<датасорс>:<поле>`, 3–4 `$dashboard:<фильтр>[.свойство]`, 5–6 `$card:<слой>:<поле>`,
115
+ * 7–8 `%<фильтр>[.свойство]`, 9 `{<атрибут>}`. Форма датасорса проверяется раньше формы фильтра:
116
+ * их различает второе двоеточие. Имя фильтра — `\w+` целиком, поэтому `%name` не цепляет начало
117
+ * `%name2`, а точка в конце предложения («за %year.») не считается свойством.
118
+ */
119
+ export declare const CONFIG_TOKEN_REGEXP: RegExp;
120
+ /** Свойства границ диапазона: `%name.min` / `%name.max`. */
121
+ export declare const RANGE_PROPS: readonly ["min", "max"];
122
+ /** Разделитель элементов массива, подставленного в текст UI. */
123
+ export declare const CONFIG_TEXT_ARRAY_SEPARATOR = ", ";
124
+ /**
125
+ * Подписи в `options` элемента, которые проходят через подстановки строк конфига. Список явный:
126
+ * служебные строки (`attributeName`, `chartId`, `relatedDataSource`, ...) подстановкам не подлежат.
127
+ */
128
+ export declare const CONFIG_STRING_OPTION_KEYS: readonly ["label", "placeholder", "title"];
107
129
  export declare const FILTERED_VALUE_OPACITY = 28;
108
130
  export declare const DEFAULT_ATTRIBUTE_NAME = "name";
109
131
  export declare const DEFAULT_DATA_SOURCE_LIMIT = 100;
@@ -144,8 +166,8 @@ export declare const BASE_CONTAINER_STYLE: CSSObject;
144
166
  /**
145
167
  * Маркер тела контейнера внутри `ContainerRoot` — содержимое без заголовка.
146
168
  *
147
- * Нужен, чтобы находить тело по DOM снаружи: `#<id контейнера>` теперь указывает на корень,
148
- * то есть на пару «заголовок + тело».
169
+ * Нужен, чтобы находить тело по DOM снаружи: `#<id контейнера>` указывает на корень, то есть на
170
+ * пару «заголовок + тело».
149
171
  */
150
172
  export declare const CONTAINER_BODY_ATTRIBUTE = "data-container-body";
151
173
  /**
@@ -2,8 +2,7 @@ import { CssSize } from '../../../types';
2
2
  /**
3
3
  * Ширина фильтра из конфига. Без явного значения фильтр занимает всю ширину контейнера.
4
4
  *
5
- * Раньше у каждого фильтра был свой пиксельный фолбэк, подогнанный под левую панель приложения
6
- * (288px у Dropdown, 17.25rem у Text, 17rem у RangeNumber, ничего у Tree), из-за чего в одной
7
- * панели фильтры вставали «лесенкой» — и тем заметнее, чем шире контейнер.
5
+ * Фолбэк общий для всех типов фильтров: свои пиксельные фолбэки у разных типов выстраивали бы
6
+ * фильтры одной панели «лесенкой» — и тем заметнее, чем шире контейнер.
8
7
  */
9
8
  export declare const getFilterWidth: (width?: CssSize) => string;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Первое непустое значение за жизнь компонента. Дефолт контрола с подстановкой
3
+ * (`$dashboard:scenario`) фиксируется при открытии карточки: пока фильтры дашборда грузятся, он ещё
4
+ * пуст, а после — смена фильтра дашборда не должна затирать выбор.
5
+ */
6
+ export declare const useFirstNonEmptyValue: <T>(value: T) => T;
@@ -1,4 +1,4 @@
1
- import { ConfigContainerChild, WidgetType } from '../../../types';
1
+ import { ConfigContainerChild, ConfigModal, WidgetType } from '../../../types';
2
2
  /**
3
3
  * Конфиг модалки `modalId` и рендер её детей.
4
4
  *
@@ -7,7 +7,7 @@ import { ConfigContainerChild, WidgetType } from '../../../types';
7
7
  * контейнера всплыл бы в заголовок или шапку модалки; `renderSlot` видит только её прямых детей.
8
8
  */
9
9
  export declare const useModalContent: (type: WidgetType, modalId?: string) => {
10
- modalConfig: any;
10
+ modalConfig: ConfigModal;
11
11
  modalContent: ConfigContainerChild[];
12
12
  renderElement: import('../../../types').RenderElementFunction;
13
13
  renderSlot: import('../../../types').RenderElementFunction;
@@ -4,8 +4,8 @@ import { CssSize } from '../../../types';
4
4
  * Css собственного бокса таблицы: размер из `options` представления плюс прокрутка того,
5
5
  * что в этот размер не влез.
6
6
  *
7
- * Размеров нет — нет и бокса: таблица занимает столько, сколько просит содержимое, а лишнее,
8
- * как и раньше, уходит в прокрутку области представления контейнера.
7
+ * Размеров нет — нет и бокса: таблица занимает столько, сколько просит содержимое, а лишнее
8
+ * уходит в прокрутку области представления контейнера.
9
9
  *
10
10
  * Проценты работают только по ширине. Между областью представления и таблицей стоит блочная
11
11
  * обёртка элемента (`ElementValueWrapper`) с высотой `auto`, и `height: "100%"` в ней не
@@ -15,6 +15,8 @@ export * from './useChartAxisTitles';
15
15
  export * from './useChartChange';
16
16
  export * from './useChartData';
17
17
  export * from './useConfigDataSources';
18
+ export * from './useConfigStringSources';
19
+ export * from './useDashboardFilterStore';
18
20
  export * from './useDashboardHeader';
19
21
  export * from './useDataSourceLoading';
20
22
  export * from './useDataSources';
@@ -0,0 +1,8 @@
1
+ import { ConfigStringSources } from '../utils/configString/types';
2
+ import { WidgetType } from '../types';
3
+ /**
4
+ * Все источники подстановок строк конфига для виджета `type`: его фильтры (`%`), фильтры и
5
+ * датасорсы дашборда (`$dashboard:`), атрибуты объекта, вид карты и проект.
6
+ * Атрибуты — объекта виджета; строки `DataSource` подменяют их своими при рендере.
7
+ */
8
+ export declare const useConfigStringSources: (type: WidgetType) => ConfigStringSources;
@@ -0,0 +1,9 @@
1
+ import { ConfigFilterStore } from '../utils/configString/types';
2
+ import { WidgetType } from '../types';
3
+ /**
4
+ * Фильтры ближайшего дашборда для `$dashboard:` в строках конфига виджета `type`. На самом
5
+ * дашборде стор не нужен (`undefined`): `$dashboard:name` там равен `%name`.
6
+ *
7
+ * Страница дашборда собирается напрямую из конфига, а не через `useWidgetPage`: тот сам зовёт этот хук.
8
+ */
9
+ export declare const useDashboardFilterStore: (type: WidgetType) => ConfigFilterStore | undefined;
@@ -1,6 +1,6 @@
1
1
  import { RefObject } from 'react';
2
2
  interface UseEqualTileWidthParams {
3
- /** `false` — режим «Растянуть», «В столбец» или старые конфиги без `columns`. */
3
+ /** `false` — режим «Растянуть», «В столбец» или конфиг без `columns`. */
4
4
  enabled: boolean;
5
5
  itemsCount: number;
6
6
  /** Число плиток в ряду: по нему считается ширина ячейки, шире которой плитка быть не может. */
@@ -1,6 +1,9 @@
1
1
  import { ConfigContainerChild, ConfigLayer, WidgetType } from '../types';
2
2
  /**
3
3
  * Generic-параметр `T` — намерение под виджет. Дальнейшая параметризация — отдельная задача.
4
+ *
5
+ * Дефолты фильтров не-дашборда (карточки) с `$dashboard:` приходят уже разрезолвленными из фильтров
6
+ * дашборда. Страница дашборда отдаётся как есть: её `currentPage` редактор пишет обратно в конфиг.
4
7
  */
5
8
  export declare const useWidgetPage: <T extends WidgetType = WidgetType.Dashboard>(type?: T) => {
6
9
  pageIndex: number;
@@ -9,7 +9,7 @@ interface UseWrapperSizeParams {
9
9
  }
10
10
  export interface WrapperRootProps extends BgImageHostProps {
11
11
  id?: string;
12
- /** Дубль `id` для внешних селекторов: раньше его нёс `ElementValueWrapper` вокруг контейнера. */
12
+ /** Дубль `id` для внешних селекторов (`[data-id=…]`). */
13
13
  "data-id"?: string;
14
14
  "data-templatename"?: string;
15
15
  style?: CSSProperties;
@@ -23,8 +23,8 @@ export interface WrapperRootProps extends BgImageHostProps {
23
23
  * Размеры уходят styled-пропом (класс), а не inline-стилем, поэтому перебиваются снаружи
24
24
  * без `!important`. Авторский `style` остаётся inline — у него приоритет по замыслу автора конфига.
25
25
  *
26
- * `data-id` и `$noMargin` раньше жили на внешней обёртке `ElementValueWrapper`; она вешала их
27
- * на второй узел поверх этого корня, дублируя стили, и для таких контейнеров больше не создаётся
26
+ * `data-id` и `$noMargin` живут на самом корне: внешняя обёртка `ElementValueWrapper` повесила бы
27
+ * их на второй узел поверх него, дублируя стили, поэтому для таких контейнеров она не создаётся
28
28
  * (см. `ROOT_OWNING_TEMPLATES`).
29
29
  *
30
30
  * Пропсы хоста фонового слоя (`$hasBgImage`, `$innerPadding`) подмешиваются здесь, а не в каждом
@@ -28,10 +28,9 @@ export declare const noMarginMixin: import('styled-components').FlattenInterpola
28
28
  /**
29
29
  * Обёртка значения элемента.
30
30
  *
31
- * Контейнеры, владеющие своим корнем (`ROOT_OWNING_TEMPLATES`), сюда больше не попадают —
32
- * обёртка дублировала их `data-id`, `data-templatename` и `style` вторым узлом DOM.
33
- * `$sizeTransparent` поэтому работает только на контейнерах, которые ещё не переведены
34
- * на `useContainerRoot`.
31
+ * Контейнеры, владеющие своим корнем (`ROOT_OWNING_TEMPLATES`), сюда не попадают — обёртка
32
+ * продублировала бы их `data-id`, `data-templatename` и `style` вторым узлом DOM.
33
+ * `$sizeTransparent` поэтому работает только на контейнерах без `useContainerRoot`.
35
34
  */
36
35
  export declare const ElementValueWrapper: import('styled-components').StyledComponent<"div", any, {
37
36
  noMargin?: boolean;
@@ -45,8 +44,8 @@ export declare const ElementValueWrapper: import('styled-components').StyledComp
45
44
  * а доля из `options.width` достаётся только телу. Поэтому `id`, `data-templatename`, авторский
46
45
  * `style` и `$sizeCss` живут здесь, а не на теле — см. `useContainerRoot`.
47
46
  *
48
- * Всегда flex-колонка: заголовок и тело раньше были flex-элементами родительского `Container`,
49
- * и блочная обёртка вернула бы схлопывание вертикальных отступов между ними.
47
+ * Всегда flex-колонка: в блочной обёртке вертикальные отступы между заголовком и телом
48
+ * схлопывались бы.
50
49
  */
51
50
  export declare const ContainerRoot: import('styled-components').StyledComponent<"div", any, import('@evergis/uilib-gl').FlexProps & ContainerRootProps, never>;
52
51
  export declare const Container: import('styled-components').StyledComponent<"div", any, import('@evergis/uilib-gl').FlexProps & ContainerRootProps & {
@@ -1,7 +1,6 @@
1
1
  /**
2
- * Стили дашборда. Раньше это был один `Dashboard/styled.ts`; путь импорта (`./styled`) не
3
- * изменился — файл стал папкой, чтобы каждый раздел жил отдельным модулем и укладывался в
4
- * `max-lines`.
2
+ * Стили дашборда. Импортируются одним путём (`./styled`), а внутри разбиты на разделы, чтобы
3
+ * каждый жил отдельным модулем и укладывался в `max-lines`.
5
4
  *
6
5
  * Подмодули импортируют друг друга НАПРЯМУЮ, а не через этот баррель: он реэкспортирует их
7
6
  * всех, и обращение к нему изнутри замкнуло бы цикл — модуль ждал бы сам себя и попал в TDZ.
@@ -8,6 +8,7 @@ import { AttributeType, EqlRequestDc, FeatureDc, OgcGeometryType, PagedFeaturesL
8
8
  import { FeatureAttributeValue, EditGeometryType, ThemeName } from '../../types';
9
9
  import { AttributeFormatConfiguration } from '../../utils/format';
10
10
  import { InnerContainerProps } from './containers/DataSourceInnerContainer/types';
11
+ import { ConfigStringSources } from './utils/configString/types';
11
12
  export * from './componentTypes';
12
13
  export * from './branded';
13
14
  /** Список допустимых типов диаграммы. `as const` даёт runtime-доступ для dropdown-ов. */
@@ -52,8 +53,8 @@ export type ViewMode = (typeof VIEW_MODES)[number];
52
53
  * CSS-длина для `fontSize`/etc. Template literal type ловит грубые ошибки вроде
53
54
  * `fontSize: "fourteen"`, при этом пропускает корректные `"1rem"`, `"14px"`, `"100%"`, ...
54
55
  *
55
- * Применяется как **opt-in** для нового кода; ConfigOptions.fontSize пока остаётся `string`
56
- * ради совместимости с legacy-конфигами.
56
+ * Применяется как **opt-in**; `ConfigOptions.fontSize` остаётся `string`, чтобы принимать
57
+ * конфиги с произвольной строкой размера.
57
58
  */
58
59
  export type CssLength = `${number}rem` | `${number}px` | `${number}em` | `${number}%`;
59
60
  export type DesignToken = `var(--${string})`;
@@ -538,7 +539,23 @@ export interface ConfigMiscOptions {
538
539
  downloadById?: string;
539
540
  parentResourceId?: string;
540
541
  useNotifications?: boolean;
542
+ /**
543
+ * Чьи изменения применяются по серверным уведомлениям. Задаётся в `options` корня
544
+ * конфигурации дашборда: действует на изменения проекта и служит значением по умолчанию
545
+ * для {@link ConfigLayer.notifications} и {@link ConfigDataSource.notifications}.
546
+ */
547
+ notifications?: ConfigNotifications;
541
548
  }
549
+ /**
550
+ * Фильтр серверных уведомлений по автору изменения (`senderName` уведомления):
551
+ * - `"all"` — любые изменения (по умолчанию);
552
+ * - `"my"` — только изменения текущего пользователя;
553
+ * - массив — только изменения перечисленных пользователей. Текущий пользователь неявно
554
+ * не добавляется, `"my"` внутри массива — обычное имя.
555
+ *
556
+ * Уведомление без автора (изменение системной задачи) применяется при любом значении.
557
+ */
558
+ export type ConfigNotifications = "all" | "my" | string[];
542
559
  /**
543
560
  * Flat-объединение всех доменных миксинов. Существующие места, использующие
544
561
  * `Pick<ConfigOptions, ...>`, продолжают работать. Для нового кода предпочтительно делать
@@ -661,6 +678,12 @@ export interface ConfigDataSource {
661
678
  * игнорируется и работает {@link ConfigDataSource.autoSyncLayer}.
662
679
  */
663
680
  autoSyncLayers?: string[];
681
+ /**
682
+ * Чьи изменения перезапрашивают источник по autoSync-уведомлениям. Не задано — берётся
683
+ * {@link ConfigLayer.notifications} слоя из уведомления, затем `options.notifications`
684
+ * корня дашборда. См. {@link ConfigNotifications}.
685
+ */
686
+ notifications?: ConfigNotifications;
664
687
  /**
665
688
  * Задержка перед запросом источника, мс. `0` или отсутствие поля — запрос сразу.
666
689
  *
@@ -768,6 +791,12 @@ export interface ConfigLayer {
768
791
  hiddenAttributes?: string[];
769
792
  customFeatureSelect?: CustomFeatureSelect;
770
793
  disableDrag?: boolean;
794
+ /**
795
+ * Чьи изменения слоя применяются по серверным уведомлениям: конфигурация слоя и его
796
+ * объекты на карте, в таблице и карточке. Не задано — `options.notifications` корня
797
+ * дашборда. См. {@link ConfigNotifications}.
798
+ */
799
+ notifications?: ConfigNotifications;
771
800
  }
772
801
  export interface ConfigTask {
773
802
  name: string;
@@ -926,6 +955,8 @@ export interface GetRenderElementProps extends Omit<ContainerProps, "renderEleme
926
955
  selectedTabId?: string;
927
956
  setSelectedTabId?: (id: string) => void;
928
957
  t?: i18n["t"];
958
+ /** Источники подстановок строк конфига (`useConfigStringSources`). Не заданы — строки выводятся как есть. */
959
+ configStringSources?: ConfigStringSources;
929
960
  }
930
961
  export interface RenderElementProps {
931
962
  id?: string;
@@ -1,9 +1,11 @@
1
- import { ClientFeatureAttribute, ConfigFilter, SelectedFilters, WidgetDataSource } from '../types';
2
1
  import { QueryLayerServiceInfoDc } from '@evergis/api';
3
- export declare const applyQueryFilters: ({ parameters: configParameters, filters: configFilters, selectedFilters, geometry, extent, zoomLevel, projectName, projectAlias, attributes, layerInfo, dataSources, projectDataSources, }: {
2
+ import { ClientFeatureAttribute, ConfigFilter, SelectedFilters, WidgetDataSource } from '../types';
3
+ import { ConfigFilterStore } from './configString/types';
4
+ export declare const applyQueryFilters: ({ parameters: configParameters, filters: configFilters, selectedFilters, dashboard, geometry, extent, zoomLevel, projectName, projectAlias, attributes, layerInfo, dataSources, }: {
4
5
  parameters: Record<string, any>;
5
6
  filters: ConfigFilter[];
6
7
  selectedFilters?: SelectedFilters;
8
+ dashboard?: ConfigFilterStore;
7
9
  geometry?: string;
8
10
  extent?: string;
9
11
  zoomLevel?: number;
@@ -12,5 +14,4 @@ export declare const applyQueryFilters: ({ parameters: configParameters, filters
12
14
  attributes?: ClientFeatureAttribute[];
13
15
  layerInfo?: QueryLayerServiceInfoDc;
14
16
  dataSources: WidgetDataSource[];
15
- projectDataSources?: WidgetDataSource[];
16
17
  }) => Record<string, Record<string, any>>;
@@ -12,7 +12,7 @@ export declare const resolveAxis: (source?: AxisSource) => ConfigAxis;
12
12
  * Источник питает ось значений.
13
13
  *
14
14
  * Отсутствие `axis.type` означает `"y"`: конфиг без явного типа — самый частый случай,
15
- * и раньше такой источник молча выпадал из графика.
15
+ * и такой источник не должен выпадать из графика.
16
16
  */
17
17
  export declare const isValueAxis: (source: AxisSource) => boolean;
18
18
  /** Сторона оси; отсутствие `axis.side` означает `"left"`. */
@@ -0,0 +1,18 @@
1
+ import { QueryLayerServiceConfigurationDc } from '@evergis/api';
2
+ import { ConfigStringSources } from './types';
3
+ export type ConditionEqlParams = {
4
+ eqlParameters?: QueryLayerServiceConfigurationDc["eqlParameters"];
5
+ layerParams?: Record<string, string>;
6
+ };
7
+ /**
8
+ * Одна секция условия: все токены в формате условия. Пустое значение фильтра оставляет токен как
9
+ * есть; пустой атрибут объекта (`{name}`) заменяется пустой строкой.
10
+ */
11
+ export declare const formatConditionSection: (section: string, sources: ConfigStringSources, { isSetParams, ...eql }?: ConditionEqlParams & {
12
+ isSetParams?: boolean;
13
+ }) => string;
14
+ /**
15
+ * Условие слоя: ведущие set-параметры `$(имя=…)` форматируются отдельно (даты без `#'…'`),
16
+ * остаток — по секциям `AND`.
17
+ */
18
+ export declare const formatConditionString: (condition: string, sources: ConfigStringSources, eql?: ConditionEqlParams) => string;
@@ -0,0 +1,16 @@
1
+ import { ConfigStringSegment, ConfigStringSources, ConfigToken } from './types';
2
+ type TokenFormatter = (token: ConfigToken) => string;
3
+ /** Склейка сегментов: токен заменяется своим форматом, незнакомый — остаётся как написан. */
4
+ export declare const joinConfigSegments: (segments: ConfigStringSegment[], formatToken: TokenFormatter) => string;
5
+ /**
6
+ * Значение параметра запроса. Строка-токен целиком уходит сырым значением с типом, а пустой или
7
+ * незнакомый фильтр не уходит вовсе (`undefined`). Токены внутри строки интерполируются текстом.
8
+ */
9
+ export declare const resolveQueryParameter: (value: unknown, sources: ConfigStringSources) => unknown;
10
+ /**
11
+ * Строка конфига для UI (значение элемента, дефолт, подпись). Строка-токен целиком отдаёт сырое
12
+ * значение (число, массив — например, дефолт мультиселекта); пустое — пустая строка. Внутри текста
13
+ * массив склеивается через `", "`. Незнакомый токен (опечатка, литерал `50%off`) остаётся как написан.
14
+ */
15
+ export declare const resolveConfigString: (value: unknown, sources: ConfigStringSources) => unknown;
16
+ export {};
@@ -0,0 +1,13 @@
1
+ import { ConfigFilterStore, ConfigTokenMode, ResolvedConfigToken } from './types';
2
+ type FilterTokenParams = {
3
+ name: string;
4
+ prop?: string;
5
+ store: ConfigFilterStore;
6
+ mode: ConfigTokenMode;
7
+ };
8
+ /**
9
+ * Значение токена фильтра (`%name[.prop]`, `$dashboard:name[.prop]`) из переданного стора.
10
+ * Фильтр, о котором стор ничего не знает, — `known: false`: токен остаётся в строке как есть.
11
+ */
12
+ export declare const getFilterTokenValue: (params: FilterTokenParams) => ResolvedConfigToken;
13
+ export {};
@@ -0,0 +1,10 @@
1
+ export * from './formatConditionString';
2
+ export * from './formatters';
3
+ export * from './getFilterTokenValue';
4
+ export * from './isDashboardReference';
5
+ export * from './referencesFilters';
6
+ export * from './resolveConfigToken';
7
+ export * from './resolveElementStrings';
8
+ export * from './resolveFilterDefaults';
9
+ export * from './tokenizeConfigString';
10
+ export * from './types';
@@ -0,0 +1,2 @@
1
+ /** Строка ссылается на фильтр дашборда (`$dashboard:`). */
2
+ export declare const isDashboardReference: (value: unknown) => value is string;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Строка конфига ссылается на один из фильтров: `%name[.prop]` — на фильтр виджета,
3
+ * `$dashboard:name[.prop]` — на фильтр дашборда. На самом дашборде (`hasDashboardStore = false`)
4
+ * `$dashboard:` — те же фильтры виджета.
5
+ */
6
+ export declare const referencesFilters: ({ value, widgetNames, dashboardNames, hasDashboardStore, }: {
7
+ value: unknown;
8
+ widgetNames: string[];
9
+ dashboardNames: string[];
10
+ hasDashboardStore: boolean;
11
+ }) => boolean;
@@ -0,0 +1,3 @@
1
+ import { ConfigStringSources, ConfigToken, ConfigTokenMode, ResolvedConfigToken } from './types';
2
+ /** Сырое значение токена строки конфига — без форматирования под параметр, условие или текст. */
3
+ export declare const resolveConfigToken: (token: ConfigToken, sources: ConfigStringSources, mode: ConfigTokenMode) => ResolvedConfigToken;
@@ -0,0 +1,8 @@
1
+ import { ConfigContainerChild } from '../../types';
2
+ import { ConfigStringSources } from './types';
3
+ /**
4
+ * Узел конфига с подставленными строками: `value`, `defaultValue` и подписи из
5
+ * {@link CONFIG_STRING_OPTION_KEYS}. Без подстановок узел возвращается тем же объектом —
6
+ * мемоизированные контейнеры не перерисовываются зря.
7
+ */
8
+ export declare const resolveElementStrings: (element: ConfigContainerChild | undefined, sources?: ConfigStringSources) => ConfigContainerChild | undefined;
@@ -0,0 +1,8 @@
1
+ import { ConfigFilter } from '../../types';
2
+ import { ConfigFilterStore } from './types';
3
+ /**
4
+ * Дефолты фильтров виджета из фильтров дашборда: `defaultValue: "$dashboard:year"`. Резолвится
5
+ * только `$dashboard:` — ссылки на собственные фильтры (`%name`) дали бы цикл и остаются как есть.
6
+ * Дефолт живой: пока фильтр виджета не выбран, он следует за дашбордом, ручной выбор его перекрывает.
7
+ */
8
+ export declare const resolveFilterDefaults: (configFilters: ConfigFilter[], dashboard?: ConfigFilterStore) => ConfigFilter[];
@@ -0,0 +1,5 @@
1
+ import { ConfigStringSegment, ConfigToken } from './types';
2
+ /** Разбирает строку конфига на литералы и токены подстановок — в исходном порядке. */
3
+ export declare const tokenizeConfigString: (value: string) => ConfigStringSegment[];
4
+ /** Строка целиком — один токен: тогда значение уходит как есть, с типом (число, массив). */
5
+ export declare const getSingleToken: (segments: ConfigStringSegment[]) => ConfigToken | null;
@@ -0,0 +1,78 @@
1
+ import { AttributeType, QueryLayerServiceInfoDc } from '@evergis/api';
2
+ import { ClientFeatureAttribute, ConfigFilter, SelectedFilters, WidgetDataSource } from '../../types';
3
+ /** Фильтры одного виджета: выбранные значения, их конфиг (дефолты, `relatedDataSource`) и датасорсы. */
4
+ export type ConfigFilterStore = {
5
+ selectedFilters?: SelectedFilters;
6
+ configFilters?: ConfigFilter[];
7
+ dataSources?: WidgetDataSource[];
8
+ };
9
+ /** Всё, откуда строка конфига может взять значение. Префикс токена выбирает стор. */
10
+ export type ConfigStringSources = {
11
+ /** `%name` — фильтры своего виджета (в карточке — фильтры карточки). */
12
+ widget?: ConfigFilterStore;
13
+ /**
14
+ * `$dashboard:` — фильтры и датасорсы ближайшего дашборда. Не задан — берётся `widget` (строка живёт
15
+ * на самом дашборде).
16
+ */
17
+ dashboard?: ConfigFilterStore;
18
+ /** `{name}` и `$card:<слой>:<поле>` — атрибуты текущего объекта. */
19
+ attributes?: ClientFeatureAttribute[];
20
+ layerInfo?: QueryLayerServiceInfoDc;
21
+ geometry?: string;
22
+ extent?: string;
23
+ zoomLevel?: number;
24
+ projectName?: string;
25
+ projectAlias?: string;
26
+ };
27
+ export type ConfigFilterScope = "widget" | "dashboard";
28
+ export type ConfigFilterToken = {
29
+ kind: "filter";
30
+ scope: ConfigFilterScope;
31
+ name: string;
32
+ prop?: string;
33
+ raw: string;
34
+ };
35
+ /** `$card:<слой>:<поле>` — атрибут объекта карточки, если карточка открыта на этом слое. */
36
+ export type ConfigCardToken = {
37
+ kind: "card";
38
+ layerName: string;
39
+ fieldName: string;
40
+ raw: string;
41
+ };
42
+ /**
43
+ * `$dashboard:<датасорс>:<поле>` — поле первой строки датасорса дашборда. Датасорс ищется по имени,
44
+ * затем по `layerName`.
45
+ */
46
+ export type ConfigDataSourceToken = {
47
+ kind: "dataSource";
48
+ dataSourceName: string;
49
+ fieldName: string;
50
+ raw: string;
51
+ };
52
+ export type ConfigAttributeToken = {
53
+ kind: "attribute";
54
+ name: string;
55
+ raw: string;
56
+ };
57
+ export type ConfigToken = ConfigFilterToken | ConfigCardToken | ConfigDataSourceToken | ConfigAttributeToken;
58
+ /** Строка конфига, разобранная на литералы и токены. */
59
+ export type ConfigStringSegment = string | ConfigToken;
60
+ /**
61
+ * Правила значения фильтра:
62
+ * - `value` — параметры запроса и текст UI: `null`/`undefined` падают в дефолт, фильтр может не иметь конфига;
63
+ * - `condition` — условие слоя: пустое значение не подставляется, фильтр обязан быть в конфиге.
64
+ */
65
+ export type ConfigTokenMode = "value" | "condition";
66
+ /** Как системное значение вставляется в условие: строкой в кавычках или числом. */
67
+ export type ConfigSystemFormat = "quoted" | "number";
68
+ export type ResolvedConfigToken = {
69
+ known: false;
70
+ } | {
71
+ known: true;
72
+ value: unknown;
73
+ /** Тип атрибута — решает, нужны ли кавычки в условии. */
74
+ attributeType?: AttributeType;
75
+ /** Дефолт фильтра — скаляр при массивном дефолте уходит в условие списком. */
76
+ defaultValue?: unknown;
77
+ system?: ConfigSystemFormat;
78
+ };
@@ -1,30 +1,13 @@
1
1
  import { QueryLayerServiceConfigurationDc } from '@evergis/api';
2
- import { ClientFeatureAttribute, ConfigFilter, SelectedFilter, SelectedFilters } from '../types';
3
- export declare const applyFiltersToCondition: ({ condition, name, defaultValue, filters, isSingle, isSetParams, configFilter, }: {
4
- condition: string;
5
- name: string;
6
- defaultValue: SelectedFilter["value"];
7
- filters: SelectedFilters;
8
- isSingle?: boolean;
9
- isSetParams?: boolean;
10
- configFilter?: ConfigFilter;
11
- }) => string | number;
12
- export declare const applyVarsToCondition: <T extends string | string[]>({ section, configFilters, filters, attributes, layerParams, eqlParameters, geometry, extent, zoomLevel, projectName, projectAlias, isSetParams, }: Pick<QueryLayerServiceConfigurationDc, "eqlParameters"> & {
13
- section: T;
14
- configFilters: ConfigFilter[];
15
- filters: SelectedFilters;
16
- attributes?: ClientFeatureAttribute[];
17
- layerParams?: Record<string, string>;
18
- geometry?: string;
19
- extent?: string;
20
- zoomLevel?: number;
21
- projectName?: string;
22
- projectAlias?: string;
23
- isSetParams?: boolean;
24
- }) => T;
2
+ import { ClientFeatureAttribute, ConfigFilter, SelectedFilters, WidgetDataSource } from '../types';
3
+ import { ConfigFilterStore } from './configString/types';
25
4
  type FormatDataSourceConditionParams = {
26
5
  configFilters?: ConfigFilter[];
27
6
  filters: SelectedFilters;
7
+ /** Датасорсы виджета — для `%name.prop` через `relatedDataSource` фильтра. */
8
+ dataSources?: WidgetDataSource[];
9
+ /** Фильтры дашборда для `$dashboard:` — когда условие принадлежит карточке. */
10
+ dashboard?: ConfigFilterStore;
28
11
  attributes?: ClientFeatureAttribute[];
29
12
  eqlParameters?: QueryLayerServiceConfigurationDc["eqlParameters"];
30
13
  layerParams?: Record<string, string>;
@@ -34,6 +17,16 @@ type FormatDataSourceConditionParams = {
34
17
  projectName?: string;
35
18
  projectAlias?: string;
36
19
  };
20
+ /** Подстановки в секции условия (строке или массиве секций) — без разбора set-параметров. */
21
+ export declare const applyVarsToCondition: <T extends string | string[]>({ section, isSetParams, ...params }: FormatDataSourceConditionParams & {
22
+ section: T;
23
+ isSetParams?: boolean;
24
+ }) => T;
25
+ /**
26
+ * Условие слоя с подстановками строк конфига: фильтры (`%filter`, `$dashboard:filter`), атрибуты
27
+ * объекта, системные значения карты и проекта, eql-параметры слоя. Пустое значение фильтра
28
+ * оставляет плейсхолдер нетронутым.
29
+ */
37
30
  export declare const formatDataSourceCondition: ({ condition, ...rest }: FormatDataSourceConditionParams & {
38
31
  condition?: string | string[];
39
32
  }) => string | string[];
@@ -0,0 +1,8 @@
1
+ import { ConfigFilter, SelectedFilters } from '../types';
2
+ /** Имена фильтров, чьё выбранное значение изменилось с прошлого снимка. */
3
+ export declare const getChangedFilterNames: (filters: SelectedFilters | undefined, prevFilters: SelectedFilters, configFilters?: ConfigFilter[]) => string[];
4
+ /**
5
+ * Имена фильтров, чей дефолт изменился (`defaultValue: "$dashboard:year"` при смене фильтра дашборда),
6
+ * пока пользователь не выбрал своё значение, — для потребителей это то же, что смена значения.
7
+ */
8
+ export declare const getChangedDefaultNames: (configFilters: ConfigFilter[] | undefined, prevConfigFilters: ConfigFilter[] | undefined, filters: SelectedFilters | undefined) => string[];
@@ -0,0 +1,3 @@
1
+ import { ConfigContainer, ConfigFilter } from '../types';
2
+ /** Фильтры страницы `pageIndex` (с 1) вместе с общими фильтрами конфига; общие перекрывают одноимённые. */
3
+ export declare const getPageFilters: (config: ConfigContainer, pageIndex: number) => ConfigFilter[];