@evergis/react 4.0.0 → 4.0.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.
@@ -4,7 +4,6 @@ export declare const useDashboardHeader: () => {
4
4
  icon: string | import("react/jsx-runtime").JSX.Element;
5
5
  title: import('react').ReactNode;
6
6
  tooltip: import("react/jsx-runtime").JSX.Element;
7
- description: import('react').ReactNode;
8
7
  themeName: import('../../..').ThemeName;
9
- renderElement: import('..').RenderElementFunction;
8
+ onClickLogo: () => void;
10
9
  };
@@ -8,7 +8,7 @@ export declare const useDataSources: ({ type: widgetType, config, attributes, fi
8
8
  layerParams?: Record<string, string>;
9
9
  eqlParameters?: QueryLayerServiceConfigurationDc["eqlParameters"];
10
10
  }) => {
11
- getDataSourcePromises: ({ ds, query, parameters, layerName, limit, condition, url, resourceId }: ConfigDataSource, newFilters?: SelectedFilters, offset?: number) => Promise<EqlDataSource | PagedFeaturesListDc>;
11
+ getDataSourcePromises: ({ ds, query, parameters, layerName, limit, condition, url, resourceId, fileName, methodName }: ConfigDataSource, newFilters?: SelectedFilters, offset?: number) => Promise<EqlDataSource | PagedFeaturesListDc>;
12
12
  getUpdatingDataSources: () => ConfigDataSource[];
13
13
  getUpdatedDataSources: (responses: DataSourcePromise[], currentDataSources: ConfigDataSource[], otherDataSources: FetchedDataSource[]) => any;
14
14
  zoomToLayersExtent: (layers: Array<{
@@ -150,6 +150,7 @@ export interface ConfigOptions {
150
150
  baseMapSettings?: Record<string, BaseMapSettings>;
151
151
  expandedLayers?: boolean;
152
152
  modalId?: string;
153
+ url?: string;
153
154
  }
154
155
  export interface ConfigDataSource {
155
156
  name: string;
@@ -162,6 +163,8 @@ export interface ConfigDataSource {
162
163
  query?: string;
163
164
  parameters?: EqlRequestDc["parameters"];
164
165
  resourceId?: string;
166
+ fileName?: string;
167
+ methodName?: string;
165
168
  url?: string;
166
169
  type?: string;
167
170
  autoSyncLayer?: boolean;
package/dist/index.js CHANGED
@@ -3955,8 +3955,13 @@ const useFetchWithAuth = (url, transform, cleanup) => {
3955
3955
  });
3956
3956
  }, [url]);
3957
3957
  React.useEffect(() => {
3958
- fetchData();
3959
- }, [fetchData]);
3958
+ if (url) {
3959
+ fetchData();
3960
+ }
3961
+ else {
3962
+ setData(null);
3963
+ }
3964
+ }, [url]);
3960
3965
  React.useEffect(() => () => {
3961
3966
  if (data !== null)
3962
3967
  cleanupRef.current?.(data);
@@ -7779,10 +7784,9 @@ const PageTitleContainer = styled(uilibGl.Flex) `
7779
7784
  `;
7780
7785
 
7781
7786
  const DashboardDefaultHeader = React.memo(() => {
7782
- const { title, pageId, image, icon, tooltip, themeName } = useDashboardHeader();
7787
+ const { title, pageId, image, icon, tooltip, themeName, onClickLogo } = useDashboardHeader();
7783
7788
  const { toggleLayersVisibility, components: { ProjectPanelMenu, ProjectPagesMenu }, } = useWidgetContext();
7784
- const backgroundImage = useFetchImageWithAuth(image ? getResourceUrl(image) : null);
7785
- return (jsxRuntime.jsxs(DefaultHeaderContainer, { image: backgroundImage ?? undefined, isDark: themeName === exports.ThemeName.Dark, children: [!pageId && jsxRuntime.jsx(uilibGl.LinearProgress, {}), jsxRuntime.jsxs(uilibGl.Flex, { column: true, gap: "1rem", children: [jsxRuntime.jsx(uilibGl.FlexSpan, { children: jsxRuntime.jsxs(TopContainer, { children: [jsxRuntime.jsx(LogoContainer, { children: icon }), jsxRuntime.jsx(TopContainerButtons, { children: jsxRuntime.jsx(ProjectPanelMenu, {}) })] }) }), jsxRuntime.jsx(uilibGl.FlexSpan, { children: jsxRuntime.jsx(uilibGl.Flex, { column: true, gap: "0.25rem", children: jsxRuntime.jsx(uilibGl.FlexSpan, { children: jsxRuntime.jsxs(uilibGl.Flex, { alignItems: "center", children: [jsxRuntime.jsxs(PageTitleContainer, { children: [jsxRuntime.jsx(uilibGl.Tooltip, { arrow: true, content: tooltip, children: ref => (jsxRuntime.jsx(PageTitle, { ref: ref, onClick: toggleLayersVisibility, children: title })) }), jsxRuntime.jsx(ProjectPagesMenu, {})] }), jsxRuntime.jsx(uilibGl.FlexSpan, { children: jsxRuntime.jsx(Pagination, {}) })] }) }) }) })] })] }));
7789
+ return (jsxRuntime.jsxs(DefaultHeaderContainer, { image: image, isDark: themeName === exports.ThemeName.Dark, children: [!pageId && jsxRuntime.jsx(uilibGl.LinearProgress, {}), jsxRuntime.jsxs(uilibGl.Flex, { column: true, gap: "1rem", children: [jsxRuntime.jsx(uilibGl.FlexSpan, { children: jsxRuntime.jsxs(TopContainer, { children: [jsxRuntime.jsx(LogoContainer, { onClick: onClickLogo, children: icon }), jsxRuntime.jsx(TopContainerButtons, { children: jsxRuntime.jsx(ProjectPanelMenu, {}) })] }) }), jsxRuntime.jsx(uilibGl.FlexSpan, { children: jsxRuntime.jsx(uilibGl.Flex, { column: true, gap: "0.25rem", children: jsxRuntime.jsx(uilibGl.FlexSpan, { children: jsxRuntime.jsxs(uilibGl.Flex, { alignItems: "center", children: [jsxRuntime.jsxs(PageTitleContainer, { children: [jsxRuntime.jsx(uilibGl.Tooltip, { arrow: true, content: tooltip, children: ref => (jsxRuntime.jsx(PageTitle, { ref: ref, onClick: toggleLayersVisibility, children: title })) }), jsxRuntime.jsx(ProjectPagesMenu, {})] }), jsxRuntime.jsx(uilibGl.FlexSpan, { children: jsxRuntime.jsx(Pagination, {}) })] }) }) }) })] })] }));
7786
7790
  });
7787
7791
 
7788
7792
  const HeaderFrontView = styled(uilibGl.Flex) `
@@ -8518,8 +8522,10 @@ const ElementIcon = React.memo(({ type, elementConfig }) => {
8518
8522
  const { attributes } = useWidgetContext(type);
8519
8523
  const { value, attributeName, options, style } = elementConfig || {};
8520
8524
  const { fontSize, fontColor } = options || {};
8521
- const iconValue = React.useMemo(() => (attributeName ? attributes?.find(item => item.name === attributeName)?.value : value), [attributeName, attributes, value]);
8522
- return jsxRuntime.jsx(StyledIcon, { kind: iconValue, fontSize: fontSize, fontColor: fontColor, style: style });
8525
+ const iconValue = React.useMemo(() => attributeName
8526
+ ? attributes?.find(item => item.name === attributeName)?.value
8527
+ : value, [attributeName, attributes, value]);
8528
+ return (jsxRuntime.jsx(StyledIcon, { kind: iconValue, fontSize: fontSize, fontColor: fontColor, style: style }));
8523
8529
  });
8524
8530
 
8525
8531
  const ElementImage = React.memo(({ type, elementConfig }) => {
@@ -9108,10 +9114,10 @@ const ElementUploader = React.memo(({ elementConfig, type }) => {
9108
9114
  const [files, setFiles] = React.useState([]);
9109
9115
  const refInput = React.useRef();
9110
9116
  const { id, style, options } = elementConfig || {};
9111
- const { fileExtensions = DEFAULT_FILE_EXTENSIONS, multiSelect, parentResourceId, icon, title, filterName } = options || {};
9117
+ const { fileExtensions = DEFAULT_FILE_EXTENSIONS, multiSelect, parentResourceId, icon, title, filterName, } = options || {};
9112
9118
  const onUpload = React.useCallback(async (input) => {
9113
- const files = Array.isArray(input) ? input : [input];
9114
- const response = await Promise.all(files.map(file => {
9119
+ const newFiles = Array.isArray(input) ? input : [input];
9120
+ const response = await Promise.all(newFiles.map(file => {
9115
9121
  return api.file.upload(file, true, parentResourceId || "", file.name);
9116
9122
  }));
9117
9123
  const uploadedFiles = response.map(item => ({
@@ -9119,28 +9125,29 @@ const ElementUploader = React.memo(({ elementConfig, type }) => {
9119
9125
  id: item.resourceId,
9120
9126
  done: true,
9121
9127
  }));
9122
- setFiles(currentFiles => ([...uploadedFiles, ...currentFiles]));
9123
- }, [parentResourceId]);
9124
- const onDelete = React.useCallback(async (id) => {
9125
- const index = files.findIndex(file => file.id === id);
9128
+ setFiles(currentFiles => [...uploadedFiles, ...currentFiles]);
9129
+ }, [api.file, parentResourceId]);
9130
+ const onDelete = React.useCallback(async (deleteId) => {
9131
+ const index = files.findIndex(file => file.id === deleteId);
9126
9132
  if (index === -1)
9127
9133
  return;
9128
9134
  const resourceId = files[index].id;
9129
9135
  await api.file.deleteResource({ resourceId });
9130
- setFiles(currentFiles => currentFiles.filter(({ id }) => id !== resourceId));
9131
- }, [files]);
9136
+ setFiles(currentFiles => currentFiles.filter(file => file.id !== resourceId));
9137
+ }, [api.file, files]);
9132
9138
  const renderTitle = React.useMemo(() => {
9133
9139
  if (files.length)
9134
9140
  return null;
9135
- return (jsxRuntime.jsxs(UploaderTitle, { children: [jsxRuntime.jsx(uilibGl.Icon, { kind: icon || "upload" }), jsxRuntime.jsx("div", { children: title ?? t("uploadTitle", {
9136
- ns: "dashboard",
9137
- defaultValue: "Перетащите файл сюда или нажмите, чтобы выбрать",
9138
- }) })] }));
9141
+ return (jsxRuntime.jsxs(UploaderTitle, { children: [jsxRuntime.jsx(uilibGl.Icon, { kind: icon || "upload" }), jsxRuntime.jsx("div", { children: title ??
9142
+ t("uploadTitle", {
9143
+ ns: "dashboard",
9144
+ defaultValue: "Перетащите файл сюда или нажмите, чтобы выбрать",
9145
+ }) })] }));
9139
9146
  }, [icon, t, title, files.length]);
9140
9147
  React.useEffect(() => {
9141
9148
  if (!filterName)
9142
9149
  return;
9143
- changeFilters({ [filterName]: { value: files.map(({ id }) => id) } });
9150
+ changeFilters({ [filterName]: { value: files.map(file => file.id) } });
9144
9151
  }, [files]);
9145
9152
  return (jsxRuntime.jsx(UploaderContainer, { id: id, style: style, children: jsxRuntime.jsx("div", { children: jsxRuntime.jsx(uilibGl.Uploader, { currentRef: refInput, title: renderTitle, accept: fileExtensions, width: "100%", fileItems: files, isMultiple: multiSelect, onUpload: onUpload, onDelete: onDelete }) }) }));
9146
9153
  });
@@ -10582,7 +10589,7 @@ const useChartData = ({ element, type }) => {
10582
10589
  const dataSource = configDataSources.find(({ name }) => name === dataSourceName);
10583
10590
  const layerInfo = layerInfos?.find(item => item?.name === dataSource?.layerName);
10584
10591
  const featureDataSource = getDataSource(dataSourceName, dataSources);
10585
- const hasLayerInfo = !!layerInfo || !!featureDataSource?.attributeDefinition;
10592
+ const hasLayerInfo = !!layerInfo || !!featureDataSource?.attributeDefinition || !!featureDataSource?.features?.length;
10586
10593
  return {
10587
10594
  items: hasLayerInfo
10588
10595
  ? getDataFromRelatedFeatures({
@@ -10634,7 +10641,7 @@ const useChartData = ({ element, type }) => {
10634
10641
  };
10635
10642
 
10636
10643
  const useHeaderRender = (elementConfig, type = exports.WidgetType.Dashboard) => {
10637
- const { layerInfo, attributes, expandedContainers, selectedTabId, setSelectedTabId } = useWidgetContext(type);
10644
+ const { layerInfo, attributes, expandedContainers, selectedTabId, setSelectedTabId, } = useWidgetContext(type);
10638
10645
  const { config } = useWidgetConfig(type);
10639
10646
  const { pageIndex } = useWidgetPage(type);
10640
10647
  return React.useMemo(() => getRenderElement({
@@ -10646,7 +10653,16 @@ const useHeaderRender = (elementConfig, type = exports.WidgetType.Dashboard) =>
10646
10653
  selectedTabId,
10647
10654
  setSelectedTabId,
10648
10655
  pageIndex,
10649
- }), [config, elementConfig, attributes, layerInfo, expandedContainers, selectedTabId, setSelectedTabId, pageIndex]);
10656
+ }), [
10657
+ config,
10658
+ elementConfig,
10659
+ attributes,
10660
+ layerInfo,
10661
+ expandedContainers,
10662
+ selectedTabId,
10663
+ setSelectedTabId,
10664
+ pageIndex,
10665
+ ]);
10650
10666
  };
10651
10667
 
10652
10668
  const useDashboardHeader = () => {
@@ -10655,21 +10671,30 @@ const useDashboardHeader = () => {
10655
10671
  const { currentPage } = useWidgetPage();
10656
10672
  const { alias, name } = projectInfo || {};
10657
10673
  const { id: pageId, header } = currentPage || {};
10674
+ const { children, options } = header || {};
10675
+ const { url } = options || {};
10658
10676
  const renderElement = useHeaderRender(header);
10659
- const image = React.useMemo(() => (header?.children?.some(({ id }) => id === "image") ? renderElement({ id: "image", wrap: false }) : null), [header?.children, renderElement]);
10660
- const icon = React.useMemo(() => header?.children?.some(({ id }) => id === "icon") ? (renderElement({ id: "icon", wrap: false })) : (jsxRuntime.jsx(uilibGl.Icon, { kind: "logo", style: { width: "2rem", height: "2rem" } })), [header?.children, renderElement]);
10661
- const title = React.useMemo(() => header?.children?.some(({ id }) => id === "title") ? renderElement({ id: "title" }) : currentPage?.options?.title, [header?.children, renderElement, currentPage?.options?.title]);
10677
+ const image = React.useMemo(() => children?.some(({ id }) => id === "image")
10678
+ ? renderElement({ id: "image", wrap: false })
10679
+ : null, [children, renderElement]);
10680
+ const icon = React.useMemo(() => children?.some(({ id }) => id === "icon") ? (renderElement({ id: "icon", wrap: false })) : (jsxRuntime.jsx(uilibGl.Icon, { kind: "logo", style: { width: "2rem", height: "2rem" } })), [children, renderElement]);
10681
+ const title = React.useMemo(() => children?.some(({ id }) => id === "title")
10682
+ ? renderElement({ id: "title" })
10683
+ : currentPage?.options?.title, [children, renderElement, currentPage?.options?.title]);
10662
10684
  const tooltip = React.useMemo(() => (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("span", { children: alias || name }), jsxRuntime.jsx("span", { style: { opacity: 0.54, marginLeft: "0.5rem" }, children: title })] })), [alias, name, title]);
10663
- const description = React.useMemo(() => (header?.children?.some(({ id }) => id === "description") ? renderElement({ id: "description" }) : ""), [header?.children, renderElement]);
10685
+ const onClickLogo = React.useCallback(() => {
10686
+ if (!url)
10687
+ return;
10688
+ window.open(url);
10689
+ }, [url]);
10664
10690
  return {
10665
10691
  pageId,
10666
10692
  image,
10667
10693
  icon,
10668
10694
  title,
10669
10695
  tooltip,
10670
- description,
10671
10696
  themeName,
10672
- renderElement,
10697
+ onClickLogo,
10673
10698
  };
10674
10699
  };
10675
10700
 
@@ -10678,7 +10703,7 @@ const useDataSources = ({ type: widgetType, config, attributes, filters, layerPa
10678
10703
  const { dataSources } = useWidgetContext(widgetType);
10679
10704
  const { filters: configFilters, dataSources: configDataSources } = config || {};
10680
10705
  const prevFilters = React.useRef({});
10681
- const getDataSourcePromises = React.useCallback(async ({ ds, query, parameters, layerName, limit, condition, url, resourceId }, newFilters, offset = 0) => {
10706
+ const getDataSourcePromises = React.useCallback(async ({ ds, query, parameters, layerName, limit, condition, url, resourceId, fileName, methodName }, newFilters, offset = 0) => {
10682
10707
  const selectedFilters = {
10683
10708
  ...(filters || {}),
10684
10709
  ...(newFilters || {}),
@@ -10691,12 +10716,14 @@ const useDataSources = ({ type: widgetType, config, attributes, filters, layerPa
10691
10716
  method: "get",
10692
10717
  resourceId,
10693
10718
  parameters,
10719
+ ...(fileName && { fileName }),
10720
+ ...(methodName && { methodName }),
10694
10721
  }
10695
10722
  });
10696
- return {
10697
- items: response.result.items,
10698
- attributeDefinition: null,
10699
- };
10723
+ if (response.error) {
10724
+ throw new Error(response.error.message);
10725
+ }
10726
+ return response.result;
10700
10727
  }
10701
10728
  const newParams = applyQueryFilters({
10702
10729
  parameters,
@@ -10776,10 +10803,12 @@ const useDataSources = ({ type: widgetType, config, attributes, filters, layerPa
10776
10803
  const newDataSources = JSON.parse(JSON.stringify([...currentDataSources, ...otherDataSources]));
10777
10804
  responses.forEach((response, index) => {
10778
10805
  const isQueryDataSource = !lodash.isNil(currentDataSources[index].query) ||
10779
- !!currentDataSources[index].url ||
10780
- !!currentDataSources[index].resourceId;
10806
+ !!currentDataSources[index].url;
10807
+ const isPythonDataSource = !!currentDataSources[index].resourceId;
10781
10808
  newDataSources[index].layerName = currentDataSources[index].layerName;
10782
- const items = response.status === "rejected" ? null : response.value?.features || response.items;
10809
+ const items = response.status === "rejected"
10810
+ ? null
10811
+ : response.value?.features || response.value?.items;
10783
10812
  newDataSources[index].features =
10784
10813
  response.status === "rejected"
10785
10814
  ? null
@@ -10787,10 +10816,11 @@ const useDataSources = ({ type: widgetType, config, attributes, filters, layerPa
10787
10816
  ? items?.map((item, itemIndex) => ({
10788
10817
  id: itemIndex + 1,
10789
10818
  attributes: item.attributes,
10819
+ properties: item.properties || item.attributes,
10790
10820
  }))
10791
10821
  : items;
10792
10822
  newDataSources[index].attributeDefinition =
10793
- response.status === "rejected" || !isQueryDataSource
10823
+ response.status === "rejected" || (!isQueryDataSource && !isPythonDataSource)
10794
10824
  ? null
10795
10825
  : response.value.attributeDefinition;
10796
10826
  });