@evergis/react 4.0.140 → 4.0.142

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.
@@ -51,6 +51,18 @@ export declare const ZOOM_FILTER_NAME = "zoom";
51
51
  * перехвачен системной подстановкой — ровно как в случае `geometry`.
52
52
  */
53
53
  export declare const MAP_VIEW_FILTER_NAMES: string[];
54
+ /** Имя системного фильтра «текущий проект» — `%project`, `%project.name`, `%project.alias`. */
55
+ export declare const PROJECT_FILTER_NAME = "project";
56
+ /** Свойство `%project.name` — системное имя проекта. */
57
+ export declare const PROJECT_NAME_PROP = "name";
58
+ /** Свойство `%project.alias` — алиас проекта, при пустом алиасе используется системное имя. */
59
+ export declare const PROJECT_ALIAS_PROP = "alias";
60
+ /**
61
+ * Свойства подстановки проекта в порядке замены: составные формы идут раньше голого плейсхолдера,
62
+ * иначе `%project` съел бы начало `%project.alias`. Пустая строка — голый `%project`, он равен
63
+ * `%project.name`.
64
+ */
65
+ export declare const PROJECT_PROPS: string[];
54
66
  export declare const PROVIDER_PREFIX = "$";
55
67
  export declare enum ProviderPrefix {
56
68
  Card = "card",
@@ -7,6 +7,8 @@ export declare const useGlobalContext: () => {
7
7
  ewktGeometry: string;
8
8
  ewktExtent: string;
9
9
  zoomLevel: number;
10
+ projectName: string;
11
+ projectAlias: string;
10
12
  notification: {
11
13
  add: (item: import('@evergis/uilib-gl').INotificationItem) => void;
12
14
  update: (patch: Partial<import('@evergis/uilib-gl').INotificationItem> & {
@@ -1,12 +1,14 @@
1
1
  import { ClientFeatureAttribute, ConfigFilter, SelectedFilters, WidgetDataSource } from '../types';
2
2
  import { QueryLayerServiceInfoDc } from '@evergis/api';
3
- export declare const applyQueryFilters: ({ parameters: configParameters, filters: configFilters, selectedFilters, geometry, extent, zoomLevel, attributes, layerInfo, dataSources, projectDataSources, }: {
3
+ export declare const applyQueryFilters: ({ parameters: configParameters, filters: configFilters, selectedFilters, geometry, extent, zoomLevel, projectName, projectAlias, attributes, layerInfo, dataSources, projectDataSources, }: {
4
4
  parameters: Record<string, any>;
5
5
  filters: ConfigFilter[];
6
6
  selectedFilters?: SelectedFilters;
7
7
  geometry?: string;
8
8
  extent?: string;
9
9
  zoomLevel?: number;
10
+ projectName?: string;
11
+ projectAlias?: string;
10
12
  attributes?: ClientFeatureAttribute[];
11
13
  layerInfo?: QueryLayerServiceInfoDc;
12
14
  dataSources: WidgetDataSource[];
@@ -9,7 +9,7 @@ export declare const applyFiltersToCondition: ({ condition, name, defaultValue,
9
9
  isSetParams?: boolean;
10
10
  configFilter?: ConfigFilter;
11
11
  }) => string | number;
12
- export declare const applyVarsToCondition: <T extends string | string[]>({ section, configFilters, filters, attributes, layerParams, eqlParameters, geometry, extent, zoomLevel, isSetParams, }: Pick<QueryLayerServiceConfigurationDc, "eqlParameters"> & {
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
13
  section: T;
14
14
  configFilters: ConfigFilter[];
15
15
  filters: SelectedFilters;
@@ -18,6 +18,8 @@ export declare const applyVarsToCondition: <T extends string | string[]>({ secti
18
18
  geometry?: string;
19
19
  extent?: string;
20
20
  zoomLevel?: number;
21
+ projectName?: string;
22
+ projectAlias?: string;
21
23
  isSetParams?: boolean;
22
24
  }) => T;
23
25
  type FormatDataSourceConditionParams = {
@@ -29,6 +31,8 @@ type FormatDataSourceConditionParams = {
29
31
  geometry?: string;
30
32
  extent?: string;
31
33
  zoomLevel?: number;
34
+ projectName?: string;
35
+ projectAlias?: string;
32
36
  };
33
37
  export declare const formatDataSourceCondition: ({ condition, ...rest }: FormatDataSourceConditionParams & {
34
38
  condition?: string | string[];
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Значение системной подстановки текущего проекта. Голый `%project` и `%project.name` дают
3
+ * системное имя, `%project.alias` — алиас с фолбэком на имя: пустой алиас не должен уводить
4
+ * запрос в пустое значение. Чужое свойство (`%project.foo`) не наше — вернём `undefined`,
5
+ * и плейсхолдер останется нетронутым, как у незаполненного фильтра.
6
+ */
7
+ export declare const getProjectValue: ({ prop, projectName, projectAlias, }: {
8
+ prop?: string | null;
9
+ projectName?: string;
10
+ projectAlias?: string;
11
+ }) => string | undefined;
@@ -46,6 +46,7 @@ export * from './getLayerInfoAttribute';
46
46
  export * from './getLayerInfoFromDataSources';
47
47
  export * from './getPagesFromConfig';
48
48
  export * from './getPagesFromProjectInfo';
49
+ export * from './getProjectValue';
49
50
  export * from './getRelatedAttribute';
50
51
  export * from './getRenderElement';
51
52
  export * from './getResourceUrl';
@@ -11,6 +11,10 @@ export type GlobalContextProps = PropsWithChildren<{
11
11
  ewktExtent?: string;
12
12
  /** Целый уровень зума карты — плейсхолдер `%zoom`. */
13
13
  zoomLevel?: number;
14
+ /** Системное имя текущего проекта — плейсхолдеры `%project` и `%project.name`. */
15
+ projectName?: string;
16
+ /** Алиас текущего проекта — плейсхолдер `%project.alias`. */
17
+ projectAlias?: string;
14
18
  themeName?: ThemeName;
15
19
  api?: Api;
16
20
  notification?: {
package/dist/index.js CHANGED
@@ -3371,6 +3371,18 @@ const ZOOM_FILTER_NAME = "zoom";
3371
3371
  * перехвачен системной подстановкой — ровно как в случае `geometry`.
3372
3372
  */
3373
3373
  const MAP_VIEW_FILTER_NAMES = [EXTENT_FILTER_NAME, ZOOM_FILTER_NAME];
3374
+ /** Имя системного фильтра «текущий проект» — `%project`, `%project.name`, `%project.alias`. */
3375
+ const PROJECT_FILTER_NAME = "project";
3376
+ /** Свойство `%project.name` — системное имя проекта. */
3377
+ const PROJECT_NAME_PROP = "name";
3378
+ /** Свойство `%project.alias` — алиас проекта, при пустом алиасе используется системное имя. */
3379
+ const PROJECT_ALIAS_PROP = "alias";
3380
+ /**
3381
+ * Свойства подстановки проекта в порядке замены: составные формы идут раньше голого плейсхолдера,
3382
+ * иначе `%project` съел бы начало `%project.alias`. Пустая строка — голый `%project`, он равен
3383
+ * `%project.name`.
3384
+ */
3385
+ const PROJECT_PROPS = [PROJECT_ALIAS_PROP, PROJECT_NAME_PROP, ""];
3374
3386
  const PROVIDER_PREFIX = "$";
3375
3387
  exports.ProviderPrefix = void 0;
3376
3388
  (function (ProviderPrefix) {
@@ -4270,6 +4282,22 @@ const getDataSourceFilterValue = ({ filterName, filterProp, attributeAlias, data
4270
4282
  return feature?.properties?.[filterProp];
4271
4283
  };
4272
4284
 
4285
+ /**
4286
+ * Значение системной подстановки текущего проекта. Голый `%project` и `%project.name` дают
4287
+ * системное имя, `%project.alias` — алиас с фолбэком на имя: пустой алиас не должен уводить
4288
+ * запрос в пустое значение. Чужое свойство (`%project.foo`) не наше — вернём `undefined`,
4289
+ * и плейсхолдер останется нетронутым, как у незаполненного фильтра.
4290
+ */
4291
+ const getProjectValue = ({ prop, projectName, projectAlias, }) => {
4292
+ if (prop && prop !== PROJECT_NAME_PROP && prop !== PROJECT_ALIAS_PROP) {
4293
+ return undefined;
4294
+ }
4295
+ if (prop === PROJECT_ALIAS_PROP) {
4296
+ return projectAlias || projectName || undefined;
4297
+ }
4298
+ return projectName || undefined;
4299
+ };
4300
+
4273
4301
  const getSelectedFilterValue = (filterName, selectedFilters, defaultValue) => {
4274
4302
  return ((!lodash.isNil(selectedFilters?.[filterName]?.value) &&
4275
4303
  Array.isArray(defaultValue) &&
@@ -4278,7 +4306,7 @@ const getSelectedFilterValue = (filterName, selectedFilters, defaultValue) => {
4278
4306
  : selectedFilters?.[filterName]?.value) ?? defaultValue);
4279
4307
  };
4280
4308
 
4281
- const applyQueryFilters = ({ parameters: configParameters, filters: configFilters, selectedFilters, geometry, extent, zoomLevel, attributes, layerInfo, dataSources, projectDataSources, }) => {
4309
+ const applyQueryFilters = ({ parameters: configParameters, filters: configFilters, selectedFilters, geometry, extent, zoomLevel, projectName, projectAlias, attributes, layerInfo, dataSources, projectDataSources, }) => {
4282
4310
  if (!configParameters) {
4283
4311
  return {};
4284
4312
  }
@@ -4344,6 +4372,18 @@ const applyQueryFilters = ({ parameters: configParameters, filters: configFilter
4344
4372
  [key]: zoomLevel,
4345
4373
  };
4346
4374
  }
4375
+ // Текущий проект: значение приходит из `GlobalContext`, а не из `SelectedFilters`. Резолвим
4376
+ // до веток `.min` / `.max` / `.property`, как экстент и зум, — имя `project` зарезервировано.
4377
+ if (filterName === PROJECT_FILTER_NAME) {
4378
+ const projectValue = getProjectValue({ prop: filterProp, projectName, projectAlias });
4379
+ if (lodash.isNil(projectValue)) {
4380
+ return result;
4381
+ }
4382
+ return {
4383
+ ...result,
4384
+ [key]: projectValue,
4385
+ };
4386
+ }
4347
4387
  if (configParameters[key].endsWith(".max")) {
4348
4388
  return {
4349
4389
  ...result,
@@ -4602,7 +4642,7 @@ const applyFiltersToCondition = ({ condition, name, defaultValue, filters, isSin
4602
4642
  }
4603
4643
  return isSingle && isNumeric(result) ? Number(result) : result;
4604
4644
  };
4605
- const applyVarsToCondition = ({ section, configFilters, filters, attributes, layerParams, eqlParameters, geometry, extent, zoomLevel, isSetParams, }) => {
4645
+ const applyVarsToCondition = ({ section, configFilters, filters, attributes, layerParams, eqlParameters, geometry, extent, zoomLevel, projectName, projectAlias, isSetParams, }) => {
4606
4646
  if (!section?.length)
4607
4647
  return [];
4608
4648
  const isSingle = typeof section === "string";
@@ -4622,6 +4662,15 @@ const applyVarsToCondition = ({ section, configFilters, filters, attributes, lay
4622
4662
  if (!lodash.isNil(zoomLevel)) {
4623
4663
  result[index] = result[index].replace(new RegExp(`${FILTER_PREFIX}${ZOOM_FILTER_NAME}(?![\\w.])`, "g"), String(zoomLevel));
4624
4664
  }
4665
+ // Текущий проект — строковая подстановка, поэтому в кавычках, как `%geometry`. Свойства
4666
+ // заменяются раньше голого плейсхолдера, а граница `(?![\w.])` оставляет фильтрам составные
4667
+ // формы (`%project_id`) и не трогает чужое свойство (`%project.foo`).
4668
+ PROJECT_PROPS.forEach(prop => {
4669
+ const projectValue = getProjectValue({ prop, projectName, projectAlias });
4670
+ if (lodash.isNil(projectValue))
4671
+ return;
4672
+ result[index] = result[index].replace(new RegExp(`${FILTER_PREFIX}${PROJECT_FILTER_NAME}${prop ? `\\.${prop}` : ""}(?![\\w.])`, "g"), `'${projectValue}'`);
4673
+ });
4625
4674
  if (configFilters?.length) {
4626
4675
  configFilters.forEach(filter => {
4627
4676
  result[index] = applyFiltersToCondition({
@@ -4650,7 +4699,7 @@ const applyVarsToCondition = ({ section, configFilters, filters, attributes, lay
4650
4699
  });
4651
4700
  return isSingle ? result?.[0] : result;
4652
4701
  };
4653
- const formatSingleCondition = (condition, { configFilters, filters, attributes, eqlParameters, layerParams, geometry, extent, zoomLevel, }) => {
4702
+ const formatSingleCondition = (condition, { configFilters, filters, attributes, eqlParameters, layerParams, geometry, extent, zoomLevel, projectName, projectAlias, }) => {
4654
4703
  const setParams = condition.match(new RegExp("\\$\\([^)]+\\)", "g"));
4655
4704
  const setParamsSection = applyVarsToCondition({
4656
4705
  section: setParams,
@@ -4662,6 +4711,8 @@ const formatSingleCondition = (condition, { configFilters, filters, attributes,
4662
4711
  geometry,
4663
4712
  extent,
4664
4713
  zoomLevel,
4714
+ projectName,
4715
+ projectAlias,
4665
4716
  isSetParams: true,
4666
4717
  });
4667
4718
  const splitter = " AND ";
@@ -4676,6 +4727,8 @@ const formatSingleCondition = (condition, { configFilters, filters, attributes,
4676
4727
  geometry,
4677
4728
  extent,
4678
4729
  zoomLevel,
4730
+ projectName,
4731
+ projectAlias,
4679
4732
  });
4680
4733
  return setParamsSection?.length && conditionSection.length
4681
4734
  ? [setParamsSection.join(""), conditionSection.join(splitter)].join(" ")
@@ -5533,7 +5586,7 @@ const ServerNotificationsProvider = ({ url, initialized, apiClient, children })
5533
5586
  };
5534
5587
 
5535
5588
  const useGlobalContext = () => {
5536
- const { t, language, themeName, api, ewktGeometry, ewktExtent, zoomLevel, notification } = React.useContext(GlobalContext) || {};
5589
+ const { t, language, themeName, api, ewktGeometry, ewktExtent, zoomLevel, projectName, projectAlias, notification } = React.useContext(GlobalContext) || {};
5537
5590
  const translate = React.useCallback((value, options) => {
5538
5591
  if (t)
5539
5592
  return t(value, options);
@@ -5547,8 +5600,21 @@ const useGlobalContext = () => {
5547
5600
  ewktGeometry,
5548
5601
  ewktExtent,
5549
5602
  zoomLevel,
5603
+ projectName,
5604
+ projectAlias,
5550
5605
  notification,
5551
- }), [language, translate, api, ewktGeometry, ewktExtent, zoomLevel, themeName, notification]);
5606
+ }), [
5607
+ language,
5608
+ translate,
5609
+ api,
5610
+ ewktGeometry,
5611
+ ewktExtent,
5612
+ zoomLevel,
5613
+ projectName,
5614
+ projectAlias,
5615
+ themeName,
5616
+ notification,
5617
+ ]);
5552
5618
  };
5553
5619
 
5554
5620
  const GRID_TILE_SIZE = "4.5rem";
@@ -6250,7 +6316,6 @@ const useMapImages = ({ images }) => {
6250
6316
  const { map, loaded: mapLoaded } = useMapContext();
6251
6317
  const [loaded, setLoaded] = React.useState(false);
6252
6318
  const [errors, setErrors] = React.useState({});
6253
- const loadedImagesRef = React.useRef(new Set());
6254
6319
  const previouslyLoadedImages = React.useRef([]);
6255
6320
  const hasImage = React.useCallback((name) => {
6256
6321
  if (!map?.current) {
@@ -6264,7 +6329,6 @@ const useMapImages = ({ images }) => {
6264
6329
  }
6265
6330
  if (map.current.hasImage(name)) {
6266
6331
  map.current.removeImage(name);
6267
- loadedImagesRef.current.delete(name);
6268
6332
  }
6269
6333
  }, [map]);
6270
6334
  const addImage = React.useCallback(async (config) => {
@@ -6285,7 +6349,6 @@ const useMapImages = ({ images }) => {
6285
6349
  sdf,
6286
6350
  pixelRatio,
6287
6351
  });
6288
- loadedImagesRef.current.add(config.name);
6289
6352
  }
6290
6353
  catch (error) {
6291
6354
  const message = error instanceof Error ? error.message : "Unknown error";
@@ -6301,7 +6364,6 @@ const useMapImages = ({ images }) => {
6301
6364
  sdf,
6302
6365
  pixelRatio,
6303
6366
  });
6304
- loadedImagesRef.current.add(config.name);
6305
6367
  }
6306
6368
  catch (error) {
6307
6369
  const message = error instanceof Error ? error.message : "Unknown error";
@@ -6318,7 +6380,6 @@ const useMapImages = ({ images }) => {
6318
6380
  sdf,
6319
6381
  pixelRatio,
6320
6382
  });
6321
- loadedImagesRef.current.add(config.name);
6322
6383
  resolve();
6323
6384
  }
6324
6385
  }).catch(error => {
@@ -6359,16 +6420,19 @@ const useMapImages = ({ images }) => {
6359
6420
  if (!mapLoaded) {
6360
6421
  return;
6361
6422
  }
6362
- map.current.on("styleimagemissing", async (e) => {
6363
- const missingImage = images.find(item => item.name === e.id);
6364
- if (missingImage && !map.current.hasImage(e.id)) {
6423
+ map.current.on("style.load", async () => {
6424
+ if (previouslyLoadedImages.current.length === 0) {
6425
+ return;
6426
+ }
6427
+ const loadPromises = previouslyLoadedImages.current.map(async (config) => {
6365
6428
  try {
6366
- await addImage(missingImage);
6429
+ await addImage(config);
6367
6430
  }
6368
6431
  catch {
6369
6432
  // Ошибка уже записана в errors
6370
6433
  }
6371
- }
6434
+ });
6435
+ await Promise.all(loadPromises);
6372
6436
  });
6373
6437
  }, [mapLoaded]);
6374
6438
  return { loaded, errors, addImage, removeImage, hasImage };
@@ -7395,7 +7459,7 @@ const useDataSourceLoading = (type) => {
7395
7459
 
7396
7460
  /* eslint-disable max-lines */
7397
7461
  const useDataSources = ({ type: widgetType, config, attributes, filters, layerParams, eqlParameters, }) => {
7398
- const { ewktGeometry, ewktExtent, zoomLevel, api } = useGlobalContext();
7462
+ const { ewktGeometry, ewktExtent, zoomLevel, projectName, projectAlias, api } = useGlobalContext();
7399
7463
  const { dataSources, layerInfo } = useWidgetContext(widgetType);
7400
7464
  const { dataSources: projectDataSources } = useWidgetContext(exports.WidgetType.Dashboard);
7401
7465
  const { filters: configFilters, dataSources: configDataSources } = config || {};
@@ -7425,6 +7489,8 @@ const useDataSources = ({ type: widgetType, config, attributes, filters, layerPa
7425
7489
  geometry: ewktGeometry,
7426
7490
  extent: ewktExtent,
7427
7491
  zoomLevel,
7492
+ projectName,
7493
+ projectAlias,
7428
7494
  layerInfo,
7429
7495
  dataSources,
7430
7496
  projectDataSources,
@@ -7501,6 +7567,8 @@ const useDataSources = ({ type: widgetType, config, attributes, filters, layerPa
7501
7567
  geometry: ewktGeometry,
7502
7568
  extent: ewktExtent,
7503
7569
  zoomLevel,
7570
+ projectName,
7571
+ projectAlias,
7504
7572
  attributes,
7505
7573
  layerParams,
7506
7574
  eqlParameters,
@@ -7524,6 +7592,8 @@ const useDataSources = ({ type: widgetType, config, attributes, filters, layerPa
7524
7592
  ewktGeometry,
7525
7593
  ewktExtent,
7526
7594
  zoomLevel,
7595
+ projectName,
7596
+ projectAlias,
7527
7597
  api,
7528
7598
  attributes,
7529
7599
  layerParams,
@@ -19405,6 +19475,10 @@ exports.OneColumnContainer = OneColumnContainer;
19405
19475
  exports.PIE_CHART_TOOLTIP_STYLE = PIE_CHART_TOOLTIP_STYLE;
19406
19476
  exports.POLL_SUBTASK_INTERVAL_MS = POLL_SUBTASK_INTERVAL_MS;
19407
19477
  exports.POLL_SUBTASK_TIMEOUT_MS = POLL_SUBTASK_TIMEOUT_MS;
19478
+ exports.PROJECT_ALIAS_PROP = PROJECT_ALIAS_PROP;
19479
+ exports.PROJECT_FILTER_NAME = PROJECT_FILTER_NAME;
19480
+ exports.PROJECT_NAME_PROP = PROJECT_NAME_PROP;
19481
+ exports.PROJECT_PROPS = PROJECT_PROPS;
19408
19482
  exports.PROVIDER_PREFIX = PROVIDER_PREFIX;
19409
19483
  exports.PageNavigator = PageNavigator;
19410
19484
  exports.PageTitle = PageTitle;
@@ -19536,6 +19610,7 @@ exports.getLayoutChildren = getLayoutChildren;
19536
19610
  exports.getMapViewDataSources = getMapViewDataSources;
19537
19611
  exports.getPagesFromConfig = getPagesFromConfig;
19538
19612
  exports.getPagesFromProjectInfo = getPagesFromProjectInfo;
19613
+ exports.getProjectValue = getProjectValue;
19539
19614
  exports.getProxyService = getProxyService;
19540
19615
  exports.getRelatedAttribute = getRelatedAttribute;
19541
19616
  exports.getRenderElement = getRenderElement;