@evergis/react 3.1.13 → 3.1.15
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.
- package/dist/components/Dashboard/components/DashboardHeader/index.d.ts +3 -0
- package/dist/components/Dashboard/components/FeatureCardButtons/index.d.ts +2 -0
- package/dist/components/Dashboard/components/FeatureCardHeader/index.d.ts +2 -0
- package/dist/components/Dashboard/components/FeatureCardTitle/index.d.ts +5 -0
- package/dist/components/Dashboard/components/Pagination/index.d.ts +1 -1
- package/dist/components/Dashboard/components/index.d.ts +4 -0
- package/dist/components/Dashboard/headers/DashboardDefaultHeader/index.d.ts +3 -0
- package/dist/components/Dashboard/headers/DashboardDefaultHeader/styled.d.ts +8 -0
- package/dist/components/Dashboard/headers/FeatureCardDefaultHeader/components/HeaderTitle.d.ts +4 -0
- package/dist/components/Dashboard/headers/FeatureCardDefaultHeader/index.d.ts +5 -0
- package/dist/components/Dashboard/headers/FeatureCardDefaultHeader/styled.d.ts +12 -0
- package/dist/components/Dashboard/headers/FeatureCardGradientHeader/index.d.ts +3 -0
- package/dist/components/Dashboard/headers/FeatureCardGradientHeader/styled.d.ts +4 -0
- package/dist/components/Dashboard/headers/FeatureCardIconHeader/index.d.ts +3 -0
- package/dist/components/Dashboard/headers/FeatureCardIconHeader/styled.d.ts +6 -0
- package/dist/components/Dashboard/headers/FeatureCardSlideshowHeader/index.d.ts +3 -0
- package/dist/components/Dashboard/headers/FeatureCardSlideshowHeader/styled.d.ts +8 -0
- package/dist/components/Dashboard/headers/index.d.ts +7 -0
- package/dist/components/Dashboard/hooks/index.d.ts +1 -0
- package/dist/components/Dashboard/hooks/useDashboardHeader.d.ts +2 -2
- package/dist/components/Dashboard/hooks/useGlobalContext.d.ts +0 -1
- package/dist/components/Dashboard/hooks/useHeaderRender.d.ts +2 -0
- package/dist/components/Dashboard/hooks/useWidgetContext.d.ts +8 -0
- package/dist/components/Dashboard/index.d.ts +1 -0
- package/dist/components/Dashboard/styled.d.ts +1 -0
- package/dist/components/Dashboard/utils/getDashboardHeader.d.ts +2 -0
- package/dist/components/Dashboard/utils/getFeatureCardHeader.d.ts +2 -0
- package/dist/components/Dashboard/utils/index.d.ts +2 -0
- package/dist/components/LayerIcon/index.d.ts +5 -0
- package/dist/components/LayerIcon/styled.d.ts +2 -0
- package/dist/components/LayerTree/types.d.ts +0 -2
- package/dist/components/index.d.ts +1 -0
- package/dist/contexts/DashboardContext/types.d.ts +8 -2
- package/dist/contexts/FeatureCardContext/types.d.ts +3 -1
- package/dist/contexts/GlobalContext/types.d.ts +1 -3
- package/dist/index.js +1349 -714
- package/dist/index.js.map +1 -1
- package/dist/react.esm.js +1051 -441
- package/dist/react.esm.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var jsxRuntime = require('react/jsx-runtime');
|
|
4
4
|
var uilibGl = require('@evergis/uilib-gl');
|
|
5
|
-
var
|
|
5
|
+
var React = require('react');
|
|
6
6
|
var styled = require('styled-components');
|
|
7
7
|
var charts = require('@evergis/charts');
|
|
8
8
|
var api = require('@evergis/api');
|
|
@@ -19,7 +19,7 @@ var turf = require('@turf/turf');
|
|
|
19
19
|
var MapGL = require('react-map-gl/mapbox');
|
|
20
20
|
require('@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css');
|
|
21
21
|
require('mapbox-gl/dist/mapbox-gl.css');
|
|
22
|
-
var react
|
|
22
|
+
var react = require('swiper/react');
|
|
23
23
|
|
|
24
24
|
const AddFeatureButton = ({ title, icon = "feature_add" /* , layerName, geometryType*/ }) => {
|
|
25
25
|
// const [, handleAddFeature] = useFeatureCreator(layerName, geometryType);
|
|
@@ -3684,31 +3684,31 @@ const isLayerService = (value) => isObject(value) && "name" in value;
|
|
|
3684
3684
|
|
|
3685
3685
|
const isNumeric = (number) => !isNaN(parseFloat(number)) && isFinite(number);
|
|
3686
3686
|
|
|
3687
|
-
const ConfigContext =
|
|
3688
|
-
const ConfigProvider =
|
|
3687
|
+
const ConfigContext = React.createContext({});
|
|
3688
|
+
const ConfigProvider = React.memo(({ children, config }) => {
|
|
3689
3689
|
return jsxRuntime.jsx(ConfigContext.Provider, { value: { config }, children: children });
|
|
3690
3690
|
});
|
|
3691
3691
|
|
|
3692
|
-
const DashboardContext =
|
|
3693
|
-
const DashboardProvider =
|
|
3692
|
+
const DashboardContext = React.createContext({});
|
|
3693
|
+
const DashboardProvider = React.memo(({ children, ...props }) => {
|
|
3694
3694
|
return jsxRuntime.jsx(DashboardContext.Provider, { value: props, children: children });
|
|
3695
3695
|
});
|
|
3696
3696
|
|
|
3697
|
-
const FeatureCardContext =
|
|
3698
|
-
const FeatureCardProvider =
|
|
3697
|
+
const FeatureCardContext = React.createContext(null);
|
|
3698
|
+
const FeatureCardProvider = React.memo(({ settings, children }) => jsxRuntime.jsx(FeatureCardContext.Provider, { value: settings, children: children }));
|
|
3699
3699
|
|
|
3700
|
-
const GlobalContext =
|
|
3701
|
-
const GlobalProvider =
|
|
3700
|
+
const GlobalContext = React.createContext({});
|
|
3701
|
+
const GlobalProvider = React.memo(({ children, ...props }) => {
|
|
3702
3702
|
return jsxRuntime.jsx(GlobalContext.Provider, { value: props, children: children });
|
|
3703
3703
|
});
|
|
3704
3704
|
|
|
3705
|
-
const MapContext =
|
|
3705
|
+
const MapContext = React.createContext({});
|
|
3706
3706
|
|
|
3707
3707
|
const MapProvider = ({ basemapItems, defaultBasemap, children }) => {
|
|
3708
|
-
const map =
|
|
3709
|
-
const draw =
|
|
3710
|
-
const [loaded, setLoaded] =
|
|
3711
|
-
const [basemapName, setBasemapName] =
|
|
3708
|
+
const map = React.useRef();
|
|
3709
|
+
const draw = React.useRef();
|
|
3710
|
+
const [loaded, setLoaded] = React.useState(false);
|
|
3711
|
+
const [basemapName, setBasemapName] = React.useState(defaultBasemap);
|
|
3712
3712
|
return (jsxRuntime.jsx(MapContext.Provider, { value: {
|
|
3713
3713
|
map,
|
|
3714
3714
|
draw,
|
|
@@ -3727,12 +3727,12 @@ exports.BaseMapTheme = void 0;
|
|
|
3727
3727
|
BaseMapTheme["Dark"] = "dark";
|
|
3728
3728
|
})(exports.BaseMapTheme || (exports.BaseMapTheme = {}));
|
|
3729
3729
|
|
|
3730
|
-
const ServerNotificationsContext =
|
|
3730
|
+
const ServerNotificationsContext = React.createContext({});
|
|
3731
3731
|
|
|
3732
3732
|
const useServerNotifications = (url, initialized) => {
|
|
3733
|
-
const hubConnection =
|
|
3734
|
-
const [connection, setConnection] =
|
|
3735
|
-
|
|
3733
|
+
const hubConnection = React.useRef(null);
|
|
3734
|
+
const [connection, setConnection] = React.useState(null);
|
|
3735
|
+
React.useEffect(() => {
|
|
3736
3736
|
if (!initialized) {
|
|
3737
3737
|
return;
|
|
3738
3738
|
}
|
|
@@ -3748,7 +3748,7 @@ const useServerNotifications = (url, initialized) => {
|
|
|
3748
3748
|
.catch(err => console.info("Ошибка:", err))
|
|
3749
3749
|
.finally(() => setConnection(hubConnection.current));
|
|
3750
3750
|
}, [initialized]); // eslint-disable-line
|
|
3751
|
-
|
|
3751
|
+
React.useEffect(() => {
|
|
3752
3752
|
if (!connection || connection.state !== "Connected") {
|
|
3753
3753
|
return;
|
|
3754
3754
|
}
|
|
@@ -3762,7 +3762,7 @@ const useServerNotifications = (url, initialized) => {
|
|
|
3762
3762
|
|
|
3763
3763
|
const ServerNotificationsProvider = ({ url, initialized, children }) => {
|
|
3764
3764
|
const connection = useServerNotifications(url, initialized);
|
|
3765
|
-
const addSubscription =
|
|
3765
|
+
const addSubscription = React.useCallback(async (payload) => {
|
|
3766
3766
|
if (!connection || connection.state !== "Connected" || !payload) {
|
|
3767
3767
|
return;
|
|
3768
3768
|
}
|
|
@@ -3776,7 +3776,7 @@ const ServerNotificationsProvider = ({ url, initialized, children }) => {
|
|
|
3776
3776
|
return Promise.resolve(null);
|
|
3777
3777
|
}
|
|
3778
3778
|
}, [connection]);
|
|
3779
|
-
const updateSubscription =
|
|
3779
|
+
const updateSubscription = React.useCallback(async (id, payload) => {
|
|
3780
3780
|
if (!connection || connection.state !== "Connected" || !id || !payload) {
|
|
3781
3781
|
return;
|
|
3782
3782
|
}
|
|
@@ -3787,7 +3787,7 @@ const ServerNotificationsProvider = ({ url, initialized, children }) => {
|
|
|
3787
3787
|
console.info(`Ошибка обновления подписки ${id}:`, err);
|
|
3788
3788
|
}
|
|
3789
3789
|
}, [connection]);
|
|
3790
|
-
const unsubscribeById =
|
|
3790
|
+
const unsubscribeById = React.useCallback(async (id) => {
|
|
3791
3791
|
if (!connection || connection.state !== "Connected" || !id) {
|
|
3792
3792
|
return;
|
|
3793
3793
|
}
|
|
@@ -3802,8 +3802,8 @@ const ServerNotificationsProvider = ({ url, initialized, children }) => {
|
|
|
3802
3802
|
};
|
|
3803
3803
|
|
|
3804
3804
|
const useWidgetContext = (type = exports.WidgetType.Dashboard) => {
|
|
3805
|
-
const { projectInfo, updateProject, layerInfos, geometryFilter, dashboardLayers, setDashboardLayer, pageIndex: projectPageIndex, selectedTabId: projectSelectedTabId, setSelectedTabId: setProjectSelectedTabId, dataSources: projectDataSources, loading: projectLoading, filters: projectFilters, changeFilters: projectChangeFilters, expandContainer: projectExpandContainer, expandedContainers: projectExpandedContainers, nextPage: projectNextPage, prevPage: projectPrevPage, changePage: projectChangePage, } =
|
|
3806
|
-
const { layerInfo, attributes, pageIndex: featurePageIndex, selectedTabId: featureSelectedTabId, setSelectedTabId: setFeatureSelectedTabId, dataSources: featureDataSources, loading: featureLoading, filters: featureFilters, changeFilters: featureChangeFilters, expandContainer: featureExpandContainer, expandedContainers: featureExpandedContainers, nextPage: featureNextPage, prevPage: featurePrevPage, changePage: featureChangePage, } =
|
|
3805
|
+
const { projectInfo, updateProject, layerInfos, geometryFilter, dashboardLayers, setDashboardLayer, components: dashboardComponents, pageIndex: projectPageIndex, selectedTabId: projectSelectedTabId, setSelectedTabId: setProjectSelectedTabId, dataSources: projectDataSources, loading: projectLoading, filters: projectFilters, changeFilters: projectChangeFilters, expandContainer: projectExpandContainer, expandedContainers: projectExpandedContainers, nextPage: projectNextPage, prevPage: projectPrevPage, changePage: projectChangePage, } = React.useContext(DashboardContext) || {};
|
|
3806
|
+
const { layerInfo, attributes, feature, closeFeatureCard, pageIndex: featurePageIndex, selectedTabId: featureSelectedTabId, setSelectedTabId: setFeatureSelectedTabId, dataSources: featureDataSources, loading: featureLoading, filters: featureFilters, changeFilters: featureChangeFilters, expandContainer: featureExpandContainer, expandedContainers: featureExpandedContainers, nextPage: featureNextPage, prevPage: featurePrevPage, changePage: featureChangePage, } = React.useContext(FeatureCardContext) || {};
|
|
3807
3807
|
return {
|
|
3808
3808
|
projectInfo,
|
|
3809
3809
|
layerInfos,
|
|
@@ -3813,6 +3813,9 @@ const useWidgetContext = (type = exports.WidgetType.Dashboard) => {
|
|
|
3813
3813
|
geometryFilter,
|
|
3814
3814
|
layerInfo,
|
|
3815
3815
|
attributes,
|
|
3816
|
+
feature,
|
|
3817
|
+
closeFeatureCard,
|
|
3818
|
+
components: dashboardComponents,
|
|
3816
3819
|
isLoading: type === exports.WidgetType.Dashboard ? projectLoading : featureLoading,
|
|
3817
3820
|
pageIndex: type === exports.WidgetType.Dashboard ? projectPageIndex : featurePageIndex,
|
|
3818
3821
|
filters: type === exports.WidgetType.Dashboard ? projectFilters : featureFilters,
|
|
@@ -3829,15 +3832,14 @@ const useWidgetContext = (type = exports.WidgetType.Dashboard) => {
|
|
|
3829
3832
|
};
|
|
3830
3833
|
|
|
3831
3834
|
const useGlobalContext = () => {
|
|
3832
|
-
const { t, language, themeName, api, ewktGeometry
|
|
3833
|
-
return
|
|
3835
|
+
const { t, language, themeName, api, ewktGeometry } = React.useContext(GlobalContext) || {};
|
|
3836
|
+
return React.useMemo(() => ({
|
|
3834
3837
|
t,
|
|
3835
3838
|
language,
|
|
3836
3839
|
themeName,
|
|
3837
3840
|
api,
|
|
3838
3841
|
ewktGeometry,
|
|
3839
|
-
|
|
3840
|
-
}), [language, t, api, ewktGeometry, themeName, LayerItemComponent]);
|
|
3842
|
+
}), [language, t, api, ewktGeometry, themeName]);
|
|
3841
3843
|
};
|
|
3842
3844
|
|
|
3843
3845
|
const HEIGHT_OFFSET = 20;
|
|
@@ -3920,12 +3922,12 @@ const useChartChange = ({ dataSources, chartId, width, height, relatedAttributes
|
|
|
3920
3922
|
const { t } = useGlobalContext();
|
|
3921
3923
|
const { layerInfos } = useWidgetContext();
|
|
3922
3924
|
const strokeColors = relatedAttributes.filter(({ chartAxis }) => chartAxis === "y").map(({ axisColor }) => axisColor);
|
|
3923
|
-
const ref =
|
|
3925
|
+
const ref = React.useRef({
|
|
3924
3926
|
path: null,
|
|
3925
3927
|
area: null,
|
|
3926
3928
|
points: [],
|
|
3927
3929
|
});
|
|
3928
|
-
const onChange =
|
|
3930
|
+
const onChange = React.useCallback((range) => {
|
|
3929
3931
|
const { path, area, points } = ref.current;
|
|
3930
3932
|
let filteredPoints = [...points];
|
|
3931
3933
|
if (range) {
|
|
@@ -3937,7 +3939,7 @@ const useChartChange = ({ dataSources, chartId, width, height, relatedAttributes
|
|
|
3937
3939
|
path && path.attr("d", lineGenerator(filteredPoints));
|
|
3938
3940
|
area && area.attr("d", areaGenerator(height)(filteredPoints));
|
|
3939
3941
|
}, [height, width]);
|
|
3940
|
-
const customize =
|
|
3942
|
+
const customize = React.useCallback(({ svg }) => {
|
|
3941
3943
|
svg.style("overflow", "visible");
|
|
3942
3944
|
svg
|
|
3943
3945
|
.selectAll(`.${charts.lineChartClassNames.lineChartXScaleGlobal} line,
|
|
@@ -4708,7 +4710,7 @@ const customStyles = [
|
|
|
4708
4710
|
];
|
|
4709
4711
|
|
|
4710
4712
|
const useMapContext = () => {
|
|
4711
|
-
return
|
|
4713
|
+
return React.useContext(MapContext);
|
|
4712
4714
|
};
|
|
4713
4715
|
|
|
4714
4716
|
const draw = new MapboxDraw({
|
|
@@ -4722,14 +4724,14 @@ const draw = new MapboxDraw({
|
|
|
4722
4724
|
});
|
|
4723
4725
|
const useMapDraw = (triggerDeps = []) => {
|
|
4724
4726
|
const { map, draw: drawContext, loaded, basemapName } = useMapContext();
|
|
4725
|
-
|
|
4727
|
+
React.useEffect(() => {
|
|
4726
4728
|
if (!loaded || !map.current) {
|
|
4727
4729
|
return;
|
|
4728
4730
|
}
|
|
4729
4731
|
drawContext.current = draw;
|
|
4730
4732
|
map.current.addControl(drawContext.current);
|
|
4731
4733
|
}, [loaded]); // eslint-disable-line
|
|
4732
|
-
|
|
4734
|
+
React.useEffect(() => {
|
|
4733
4735
|
if (map.current && map.current.hasControl(drawContext.current)) {
|
|
4734
4736
|
map.current.removeControl(drawContext.current);
|
|
4735
4737
|
map.current.addControl(drawContext.current);
|
|
@@ -4739,7 +4741,7 @@ const useMapDraw = (triggerDeps = []) => {
|
|
|
4739
4741
|
|
|
4740
4742
|
const useRedrawLayer = () => {
|
|
4741
4743
|
const { map } = useMapContext();
|
|
4742
|
-
return
|
|
4744
|
+
return React.useCallback((layerName) => {
|
|
4743
4745
|
const layerTileSource = map.current.getSource(layerName);
|
|
4744
4746
|
layerTileSource.setTiles(layerTileSource.tiles);
|
|
4745
4747
|
}, [map]);
|
|
@@ -4802,7 +4804,7 @@ const convertSpToTurfFeature = (geometry) => {
|
|
|
4802
4804
|
|
|
4803
4805
|
const useZoomToFeatures = () => {
|
|
4804
4806
|
const { map } = useMapContext();
|
|
4805
|
-
return
|
|
4807
|
+
return React.useCallback((features, padding) => {
|
|
4806
4808
|
if (!features) {
|
|
4807
4809
|
return;
|
|
4808
4810
|
}
|
|
@@ -4816,7 +4818,7 @@ const useZoomToFeatures = () => {
|
|
|
4816
4818
|
|
|
4817
4819
|
const useZoomToPoint = () => {
|
|
4818
4820
|
const { map } = useMapContext();
|
|
4819
|
-
return
|
|
4821
|
+
return React.useCallback((options, callback) => {
|
|
4820
4822
|
if (map.current) {
|
|
4821
4823
|
if (callback) {
|
|
4822
4824
|
map.current.once("moveend", () => {
|
|
@@ -4833,8 +4835,8 @@ const useZoomToPoint = () => {
|
|
|
4833
4835
|
|
|
4834
4836
|
const useLayerParams = (layer) => {
|
|
4835
4837
|
const { api } = useGlobalContext();
|
|
4836
|
-
const [layerParams, setLayerParams] =
|
|
4837
|
-
|
|
4838
|
+
const [layerParams, setLayerParams] = React.useState({});
|
|
4839
|
+
React.useEffect(() => {
|
|
4838
4840
|
if (layer?.type !== "QueryLayerService") {
|
|
4839
4841
|
return;
|
|
4840
4842
|
}
|
|
@@ -4847,27 +4849,27 @@ const useLayerParams = (layer) => {
|
|
|
4847
4849
|
};
|
|
4848
4850
|
|
|
4849
4851
|
const useServerNotificationsContext = () => {
|
|
4850
|
-
return
|
|
4852
|
+
return React.useContext(ServerNotificationsContext);
|
|
4851
4853
|
};
|
|
4852
4854
|
|
|
4853
4855
|
const useDebouncedCallback = (interval) => {
|
|
4854
|
-
return
|
|
4856
|
+
return React.useMemo(() => debounce((cb) => {
|
|
4855
4857
|
cb();
|
|
4856
4858
|
}, interval), [interval]);
|
|
4857
4859
|
};
|
|
4858
4860
|
|
|
4859
4861
|
const useToggle = (initial) => {
|
|
4860
|
-
const [state, setState] =
|
|
4861
|
-
const toggle =
|
|
4862
|
+
const [state, setState] = React.useState(initial !== undefined ? initial : false);
|
|
4863
|
+
const toggle = React.useCallback(() => setState(!state), [state]);
|
|
4862
4864
|
return [state, toggle, setState];
|
|
4863
4865
|
};
|
|
4864
4866
|
|
|
4865
4867
|
const DEBOUNCE_DELAY = 144;
|
|
4866
4868
|
const useWindowResize = (callback, delay) => {
|
|
4867
|
-
const debounceCallback =
|
|
4869
|
+
const debounceCallback = React.useMemo(() => {
|
|
4868
4870
|
return callback ? debounce(callback, delay || DEBOUNCE_DELAY) : undefined;
|
|
4869
4871
|
}, [callback, delay]);
|
|
4870
|
-
|
|
4872
|
+
React.useEffect(() => {
|
|
4871
4873
|
debounceCallback && window.addEventListener("resize", debounceCallback);
|
|
4872
4874
|
return () => debounceCallback && window.removeEventListener("resize", debounceCallback);
|
|
4873
4875
|
}, [debounceCallback]);
|
|
@@ -4875,8 +4877,8 @@ const useWindowResize = (callback, delay) => {
|
|
|
4875
4877
|
|
|
4876
4878
|
const useLayerGroupMenu = () => {
|
|
4877
4879
|
const [isMenuOpen, toggleMenu] = useToggle(false);
|
|
4878
|
-
const options =
|
|
4879
|
-
const selectOption =
|
|
4880
|
+
const options = React.useMemo(() => [], []);
|
|
4881
|
+
const selectOption = React.useCallback(() => {
|
|
4880
4882
|
// ...
|
|
4881
4883
|
}, [toggleMenu]);
|
|
4882
4884
|
return {
|
|
@@ -4891,7 +4893,7 @@ const LayerGroup = ({ group, onlyMainTools }) => {
|
|
|
4891
4893
|
const { projectInfo, updateProject } = useWidgetContext();
|
|
4892
4894
|
const { pageIndex } = useWidgetPage();
|
|
4893
4895
|
const { isMenuOpen, toggleMenu, options, selectOption } = useLayerGroupMenu();
|
|
4894
|
-
const onToggleExpand =
|
|
4896
|
+
const onToggleExpand = React.useCallback((name, isExpanded) => {
|
|
4895
4897
|
if (!projectInfo) {
|
|
4896
4898
|
return;
|
|
4897
4899
|
}
|
|
@@ -4900,7 +4902,7 @@ const LayerGroup = ({ group, onlyMainTools }) => {
|
|
|
4900
4902
|
page.layers = findAnd.changeProps(projectInfo.content.items, { name }, { isExpanded });
|
|
4901
4903
|
updateProject(newProjectInfo);
|
|
4902
4904
|
}, [pageIndex, projectInfo, updateProject]);
|
|
4903
|
-
const onToggleVisibility =
|
|
4905
|
+
const onToggleVisibility = React.useCallback((name, isVisible) => {
|
|
4904
4906
|
if (!projectInfo) {
|
|
4905
4907
|
return;
|
|
4906
4908
|
}
|
|
@@ -4944,11 +4946,11 @@ const treeNodesToProjectItems = (currentProjectItems, treeNodes) => {
|
|
|
4944
4946
|
return combineProjectItems(treeNodes);
|
|
4945
4947
|
};
|
|
4946
4948
|
|
|
4947
|
-
const LayerTree = ({ layers,
|
|
4948
|
-
const { projectInfo, updateProject } = useWidgetContext();
|
|
4949
|
+
const LayerTree = ({ layers, onlyMainTools }) => {
|
|
4950
|
+
const { projectInfo, updateProject, components: { LayerItem } } = useWidgetContext();
|
|
4949
4951
|
const { pageIndex } = useWidgetPage();
|
|
4950
|
-
const nodes =
|
|
4951
|
-
const onUpdate =
|
|
4952
|
+
const nodes = React.useMemo(() => layers?.map(layer => createTreeNode(layer, LayerItem, onlyMainTools)), [LayerItem, layers, onlyMainTools]);
|
|
4953
|
+
const onUpdate = React.useCallback((updatedNodes) => {
|
|
4952
4954
|
const newProjectInfo = JSON.parse(JSON.stringify(projectInfo));
|
|
4953
4955
|
const page = getPagesFromProjectInfo(newProjectInfo)?.[pageIndex - 1];
|
|
4954
4956
|
if (!page) {
|
|
@@ -5229,6 +5231,18 @@ const AttributeLabel = styled(uilibGl.Description) `
|
|
|
5229
5231
|
margin-bottom: ${({ forCheckbox }) => (forCheckbox ? "0.75rem" : "0.25rem")} !important;
|
|
5230
5232
|
padding-left: ${({ isEdit }) => (isEdit ? "0.5rem" : "0")};
|
|
5231
5233
|
`;
|
|
5234
|
+
const FeatureControls = styled(uilibGl.Flex) `
|
|
5235
|
+
align-items: center;
|
|
5236
|
+
gap: 1rem;
|
|
5237
|
+
flex-wrap: nowrap;
|
|
5238
|
+
position: relative;
|
|
5239
|
+
flex-shrink: 0;
|
|
5240
|
+
|
|
5241
|
+
button {
|
|
5242
|
+
padding: 0;
|
|
5243
|
+
width: auto;
|
|
5244
|
+
}
|
|
5245
|
+
`;
|
|
5232
5246
|
|
|
5233
5247
|
const getAttributeByName = (attributeName, attributes) => {
|
|
5234
5248
|
return Array.isArray(attributeName)
|
|
@@ -5254,7 +5268,7 @@ const formatElementValue = ({ t, value, elementConfig, attributes, wrap, }) => {
|
|
|
5254
5268
|
: valueOrDefault;
|
|
5255
5269
|
if (!wrap)
|
|
5256
5270
|
return resultValue;
|
|
5257
|
-
return (jsxRuntime.jsxs(
|
|
5271
|
+
return (jsxRuntime.jsxs(React.Fragment, { children: [tagView ? (jsxRuntime.jsx(DashboardChip$1, { text: resultValue, "$bgColor": bgColor, "$fontColor": fontColor, "$fontSize": fontSize, "$radius": radius, style: style })) : (jsxRuntime.jsx(ElementValueWrapper, { "data-id": id, "data-templatename": templateName, style: style, children: resultValue })), withDivider && jsxRuntime.jsx(uilibGl.Divider, {})] }, id));
|
|
5258
5272
|
};
|
|
5259
5273
|
|
|
5260
5274
|
const getAttributeValue = (element, attributes) => {
|
|
@@ -5265,7 +5279,7 @@ const getAttributeValue = (element, attributes) => {
|
|
|
5265
5279
|
return jsxRuntime.jsx(DashboardCheckbox, { title: attribute.alias || attribute.name, checked: attribute.value });
|
|
5266
5280
|
}
|
|
5267
5281
|
if (Array.isArray(element?.attributeName)) {
|
|
5268
|
-
const concatAttributes = element.attributeName.map((attributeName) => attributes
|
|
5282
|
+
const concatAttributes = element.attributeName.map((attributeName) => attributes?.find(({ name }) => name === attributeName)?.value || "");
|
|
5269
5283
|
value = concatAttributes.join(separator || ", ");
|
|
5270
5284
|
}
|
|
5271
5285
|
else {
|
|
@@ -5287,7 +5301,7 @@ const getChartMarkers = (items, markers) => {
|
|
|
5287
5301
|
})) || []);
|
|
5288
5302
|
};
|
|
5289
5303
|
|
|
5290
|
-
const ContainersGroupContainer =
|
|
5304
|
+
const ContainersGroupContainer = React.memo(({ elementConfig, type, renderElement }) => {
|
|
5291
5305
|
const { expandedContainers } = useWidgetContext(type);
|
|
5292
5306
|
const { id, children, options, style } = elementConfig || {};
|
|
5293
5307
|
const { column, expandable, expanded } = options || {};
|
|
@@ -5296,7 +5310,7 @@ const ContainersGroupContainer = react.memo(({ elementConfig, type, renderElemen
|
|
|
5296
5310
|
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsx(Container, { style: style, isColumn: isColumn, children: jsxRuntime.jsx(ContainerChildren, { items: children, elementConfig: elementConfig, isColumn: isColumn, isMain: id?.startsWith(CONFIG_PAGE_ID), renderElement: renderElement }) }))] }));
|
|
5297
5311
|
});
|
|
5298
5312
|
|
|
5299
|
-
const OneColumnContainer =
|
|
5313
|
+
const OneColumnContainer = React.memo(({ elementConfig, renderElement }) => {
|
|
5300
5314
|
const { options, style } = elementConfig || {};
|
|
5301
5315
|
const { innerTemplateStyle, hideEmpty } = options || {};
|
|
5302
5316
|
const value = renderElement({ id: "value" });
|
|
@@ -5306,10 +5320,10 @@ const OneColumnContainer = react.memo(({ elementConfig, renderElement }) => {
|
|
|
5306
5320
|
return (jsxRuntime.jsxs(Container, { style: innerTemplateStyle || style, children: [jsxRuntime.jsxs(ContainerAlias, { hasBottomMargin: true, children: [renderElement({ id: "alias" }), renderElement({ id: "tooltip" })] }), jsxRuntime.jsxs(ContainerValue, { children: [value, hasUnits && jsxRuntime.jsx(ContainerUnits, { children: renderElement({ id: "units" }) })] })] }));
|
|
5307
5321
|
});
|
|
5308
5322
|
|
|
5309
|
-
const TwoColumnContainer =
|
|
5323
|
+
const TwoColumnContainer = React.memo(({ config, elementConfig, type, renderElement }) => {
|
|
5310
5324
|
const { selectedTabId, layerInfo, attributes } = useWidgetContext(type);
|
|
5311
5325
|
const { attributes: renderAttributes } = elementConfig?.options || {};
|
|
5312
|
-
const renderContainer =
|
|
5326
|
+
const renderContainer = React.useCallback((element, attribute) => {
|
|
5313
5327
|
const { options, style, children } = element || {};
|
|
5314
5328
|
const { hideEmpty, innerTemplateStyle } = options || {};
|
|
5315
5329
|
const hasUnits = children?.some(({ id }) => id === "units");
|
|
@@ -5359,7 +5373,7 @@ const InnerContainerWrapper = styled.div `
|
|
|
5359
5373
|
opacity: ${({ hasAnyFilter, isFiltered }) => (isFiltered ? 1 : hasAnyFilter ? FILTERED_VALUE_OPACITY / 100 : 1)};
|
|
5360
5374
|
`;
|
|
5361
5375
|
|
|
5362
|
-
const DataSourceInnerContainer =
|
|
5376
|
+
const DataSourceInnerContainer = React.memo(({ config, elementConfig, feature, maxValue, type, index, innerComponent }) => {
|
|
5363
5377
|
const { t } = useGlobalContext();
|
|
5364
5378
|
const { expandedContainers, selectedTabId, setSelectedTabId, dataSources } = useWidgetContext(type);
|
|
5365
5379
|
const { pageIndex, currentPage } = useWidgetPage(type);
|
|
@@ -5371,12 +5385,12 @@ const DataSourceInnerContainer = react.memo(({ config, elementConfig, feature, m
|
|
|
5371
5385
|
});
|
|
5372
5386
|
const { options, children } = elementConfig || {};
|
|
5373
5387
|
const { relatedDataSource, filterName, column } = options || {};
|
|
5374
|
-
const aliasElement =
|
|
5375
|
-
const valueElement =
|
|
5376
|
-
const aliasAttribute =
|
|
5388
|
+
const aliasElement = React.useMemo(() => children?.find(({ id }) => id === "alias"), [children]);
|
|
5389
|
+
const valueElement = React.useMemo(() => children?.find(({ id }) => id === "value"), [children]);
|
|
5390
|
+
const aliasAttribute = React.useMemo(() => (aliasElement ? attributes?.find(({ name }) => name === aliasElement.attributeName) : null), [aliasElement, attributes]);
|
|
5377
5391
|
const value = aliasAttribute?.value;
|
|
5378
5392
|
const InnerContainer = innerComponent;
|
|
5379
|
-
const data =
|
|
5393
|
+
const data = React.useMemo(() => getDataFromRelatedFeatures({
|
|
5380
5394
|
t,
|
|
5381
5395
|
config: elementConfig,
|
|
5382
5396
|
filters: currentPage?.filters,
|
|
@@ -5399,7 +5413,7 @@ const DataSourceInnerContainer = react.memo(({ config, elementConfig, feature, m
|
|
|
5399
5413
|
valueElement?.attributeName
|
|
5400
5414
|
]);
|
|
5401
5415
|
const { hasAnyFilter, isFiltered, onFilter } = useFeatureFilters(type, filterName, data);
|
|
5402
|
-
const render =
|
|
5416
|
+
const render = React.useMemo(() => getRenderElement({
|
|
5403
5417
|
config,
|
|
5404
5418
|
elementConfig,
|
|
5405
5419
|
attributes,
|
|
@@ -5530,7 +5544,7 @@ const ProgressTotal = styled(uilibGl.Flex) `
|
|
|
5530
5544
|
margin-top: 1rem;
|
|
5531
5545
|
`;
|
|
5532
5546
|
|
|
5533
|
-
const DataSourceProgressContainer =
|
|
5547
|
+
const DataSourceProgressContainer = React.memo(({ config, elementConfig, type, innerComponent, renderElement }) => {
|
|
5534
5548
|
const { t } = useGlobalContext();
|
|
5535
5549
|
const { dataSources, expandedContainers } = useWidgetContext(type);
|
|
5536
5550
|
const { dataSource, layerInfo } = useRelatedDataSourceAttributes({
|
|
@@ -5544,17 +5558,17 @@ const DataSourceProgressContainer = react.memo(({ config, elementConfig, type, i
|
|
|
5544
5558
|
const valueElement = children?.find(item => item.id === "value");
|
|
5545
5559
|
const unitsElement = children?.find(item => item.id === "units");
|
|
5546
5560
|
const { sliceItems, checkIsSliced, showMore, onShowMore } = useShownOtherItems(options);
|
|
5547
|
-
const totalUnits =
|
|
5561
|
+
const totalUnits = React.useMemo(() => unitsElement?.type === "attributeUnits"
|
|
5548
5562
|
? attributes?.find(({ attributeName }) => attributeName === unitsElement.attributeName)?.stringFormat
|
|
5549
5563
|
?.unitsLabel
|
|
5550
5564
|
: dataSource?.features?.[0]?.attributes[unitsElement?.attributeName], [attributes, dataSource?.features, unitsElement?.attributeName, unitsElement?.type]);
|
|
5551
|
-
const totalValue =
|
|
5565
|
+
const totalValue = React.useMemo(() => {
|
|
5552
5566
|
const attribute = attributes?.find(({ attributeName }) => attributeName === valueElement?.attributeName);
|
|
5553
5567
|
const { type: attributeType, stringFormat } = attribute || {};
|
|
5554
5568
|
const result = dataSource?.features?.reduce((total, feature) => total + feature.attributes[valueElement?.attributeName], 0);
|
|
5555
5569
|
return formatAttributeValue({ t, type: attributeType, value: result, stringFormat, noUnits: !!unitsElement?.type });
|
|
5556
5570
|
}, [attributes, dataSource?.features, unitsElement?.type, valueElement?.attributeName]);
|
|
5557
|
-
const currentMaxValue =
|
|
5571
|
+
const currentMaxValue = React.useMemo(() => {
|
|
5558
5572
|
if (typeof maxValue === "string") {
|
|
5559
5573
|
return dataSource?.features?.[0]?.attributes[maxValue];
|
|
5560
5574
|
}
|
|
@@ -5570,7 +5584,7 @@ const DataSourceProgressContainer = react.memo(({ config, elementConfig, type, i
|
|
|
5570
5584
|
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), !isVisible ? null : dataSource ? (jsxRuntime.jsxs(DataSourceProgressContainerWrapper, { children: [sliceItems(dataSource?.features)?.map((feature, index) => (jsxRuntime.jsx(DataSourceInnerContainer, { type: type, index: index, feature: feature, config: config, elementConfig: elementConfig, maxValue: currentMaxValue, innerComponent: innerComponent }, index))), checkIsSliced(dataSource?.features) && (jsxRuntime.jsx(ContainerToggler, { toggled: showMore, onClick: onShowMore, children: showMore ? t("hide", { ns: "dashboard" }) : t("showAll", { ns: "dashboard" }) })), showTotal && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(uilibGl.Divider, {}), jsxRuntime.jsxs(ProgressTotal, { children: [jsxRuntime.jsx(ProgressTotalTitle, { children: t("total", { ns: "dashboard" }) }), jsxRuntime.jsxs(ProgressValue, { children: [totalValue, jsxRuntime.jsx(ProgressUnits, { children: totalUnits })] })] })] }))] })) : (jsxRuntime.jsx(ContainerLoading, {})), jsxRuntime.jsx(HiddenTitleItems, { elementConfig: elementConfig, config: config, type: type })] }));
|
|
5571
5585
|
});
|
|
5572
5586
|
|
|
5573
|
-
const ProgressContainer =
|
|
5587
|
+
const ProgressContainer = React.memo(({ type, elementConfig, feature, maxValue, index, renderElement }) => {
|
|
5574
5588
|
const { t } = useGlobalContext();
|
|
5575
5589
|
const { dataSources } = useWidgetContext(type);
|
|
5576
5590
|
const { attributes } = useRelatedDataSourceAttributes({
|
|
@@ -5588,23 +5602,23 @@ const ProgressContainer = react.memo(({ type, elementConfig, feature, maxValue,
|
|
|
5588
5602
|
const value = !lodash.isNil(valueAttribute?.value) ? +valueAttribute.value : +valueElement.value || 0;
|
|
5589
5603
|
const currentMaxValue = (maxValue || optionMaxValue);
|
|
5590
5604
|
const width = `${Math.min(100, (value / currentMaxValue) * 100).toFixed(2)}%`;
|
|
5591
|
-
const renderTooltipAlias =
|
|
5605
|
+
const renderTooltipAlias = React.useMemo(() => renderElement({
|
|
5592
5606
|
id: "alias",
|
|
5593
5607
|
wrap: false
|
|
5594
5608
|
}), [renderElement]);
|
|
5595
|
-
const renderTooltipValue =
|
|
5609
|
+
const renderTooltipValue = React.useMemo(() => renderElement({
|
|
5596
5610
|
id: "value",
|
|
5597
5611
|
wrap: false
|
|
5598
5612
|
}), [renderElement]);
|
|
5599
|
-
const renderAlias =
|
|
5600
|
-
const renderValue =
|
|
5601
|
-
const renderIcon =
|
|
5613
|
+
const renderAlias = React.useMemo(() => renderElement({ id: "alias" }), [renderElement]);
|
|
5614
|
+
const renderValue = React.useMemo(() => renderElement({ id: "value" }), [renderElement]);
|
|
5615
|
+
const renderIcon = React.useMemo(() => renderElement({
|
|
5602
5616
|
id: "icon",
|
|
5603
5617
|
wrap: false
|
|
5604
5618
|
}), [renderElement]);
|
|
5605
|
-
const renderTooltip =
|
|
5606
|
-
const color =
|
|
5607
|
-
? attributes
|
|
5619
|
+
const renderTooltip = React.useMemo(() => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ProgressTooltipAlias, { children: renderTooltipAlias }), jsxRuntime.jsxs(ProgressTooltipValueContainer, { children: [jsxRuntime.jsx(ProgressTooltipValue, { children: renderTooltipValue }), jsxRuntime.jsx(ProgressTooltipValueOf, { children: t("of", { ns: "dashboard" }) }), jsxRuntime.jsx("div", { children: formatAttributeValue({ t, type: valueType, value: currentMaxValue, stringFormat }) })] })] })), [currentMaxValue, renderTooltipAlias, renderTooltipValue, stringFormat, t, valueType]);
|
|
5620
|
+
const color = React.useMemo(() => colorAttribute
|
|
5621
|
+
? attributes?.find(({ name }) => name === colorAttribute)?.value
|
|
5608
5622
|
: colors?.[index] || bgColor, [attributes, bgColor, colorAttribute, colors, index]);
|
|
5609
5623
|
return (jsxRuntime.jsx(uilibGl.Tooltip, { content: renderTooltip, placement: "top", arrow: true, children: ref => (jsxRuntime.jsxs(ProgressContainerWrapper, { ref: ref, style: innerTemplateStyle || style, children: [renderIcon && jsxRuntime.jsx(ProgressIcon, { children: renderIcon }), jsxRuntime.jsxs(ProgressContent, { children: [!hideTitle && (jsxRuntime.jsxs(ProgressAlias, { children: [jsxRuntime.jsx("div", { children: renderAlias }), jsxRuntime.jsxs(ProgressValue, { children: [renderValue, unitsElement && jsxRuntime.jsx(ProgressUnits, { children: renderElement({ id: "units" }) })] })] })), jsxRuntime.jsxs(ProgressBarContainer, { innerValue: innerValue, children: [jsxRuntime.jsx(ProgressBarWrapper, { children: jsxRuntime.jsx(ProgressBar, { "$width": width, "$color": color }) }), !!(hideTitle || innerValue) && jsxRuntime.jsx(ProgressInnerValue, { children: renderValue })] })] })] })) }));
|
|
5610
5624
|
});
|
|
@@ -5787,29 +5801,29 @@ const TooltipContainer = styled.div `
|
|
|
5787
5801
|
}
|
|
5788
5802
|
`;
|
|
5789
5803
|
|
|
5790
|
-
const FiltersContainer =
|
|
5804
|
+
const FiltersContainer = React.memo(({ elementConfig, config, type, renderElement }) => {
|
|
5791
5805
|
const { filters, dataSources, expandedContainers } = useWidgetContext(type);
|
|
5792
5806
|
const { currentPage } = useWidgetPage(type);
|
|
5793
5807
|
const { filters: configFilters } = currentPage;
|
|
5794
5808
|
const { id, style, options } = elementConfig || {};
|
|
5795
5809
|
const { padding, bgColor, fontColor, fontSize, expandable, expanded } = options || {};
|
|
5796
|
-
const isLoading =
|
|
5797
|
-
const filterItems =
|
|
5798
|
-
const renderFilter =
|
|
5810
|
+
const isLoading = React.useMemo(() => checkIsLoading(dataSources, config, configFilters), [configFilters, config, dataSources]);
|
|
5811
|
+
const filterItems = React.useMemo(() => elementConfig?.children?.filter(child => child.options?.filterName), [elementConfig?.children]);
|
|
5812
|
+
const renderFilter = React.useCallback((filter, index) => {
|
|
5799
5813
|
const FilterComponent = getFilterComponent(filter.type);
|
|
5800
5814
|
return jsxRuntime.jsx(FilterComponent, { type: type, filter: filter, config: config, elementConfig: filter }, index);
|
|
5801
5815
|
}, [config, type]);
|
|
5802
5816
|
const isVisible = isVisibleContainer(id, expandable, expanded, expandedContainers);
|
|
5803
|
-
const selectedItems =
|
|
5817
|
+
const selectedItems = React.useMemo(() => getFilterSelectedItems(filterItems, filters, configFilters), [configFilters, filters, filterItems]);
|
|
5804
5818
|
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(uilibGl.Flex, { mb: !isVisible && selectedItems.length ? "2rem" : 0, children: jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }) }), isLoading && jsxRuntime.jsx(ContainerLoading, {}), !isLoading && isVisible && (jsxRuntime.jsx(FiltersContainerWrapper, { style: style, "$padding": padding, "$bgColor": bgColor, "$fontSize": fontSize, "$fontColor": fontColor, children: filterItems?.map(renderFilter) })), jsxRuntime.jsx(HiddenTitleItems, { elementConfig: elementConfig, config: config, type: type, filter: filterItems[0].options?.filterName })] }));
|
|
5805
5819
|
});
|
|
5806
5820
|
|
|
5807
|
-
const DefaultAttributesContainer =
|
|
5821
|
+
const DefaultAttributesContainer = React.memo(({ type, renderElement }) => {
|
|
5808
5822
|
const { attributes } = useWidgetContext(type);
|
|
5809
5823
|
return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: attributes?.map(({ name }) => (jsxRuntime.jsx(Container, { children: renderElement({ id: name }) }, name))) }));
|
|
5810
5824
|
});
|
|
5811
5825
|
|
|
5812
|
-
const ChartContainer =
|
|
5826
|
+
const ChartContainer = React.memo(({ elementConfig, isVisible, type, renderElement }) => {
|
|
5813
5827
|
const { options, children } = elementConfig || {};
|
|
5814
5828
|
const { twoColumns, hideEmpty } = options || {};
|
|
5815
5829
|
const aliasElement = children.find(({ id }) => id === "alias");
|
|
@@ -5827,17 +5841,17 @@ const ChartContainer = react.memo(({ elementConfig, isVisible, type, renderEleme
|
|
|
5827
5841
|
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsxs(Container, { isColumn: true, children: [aliasElement && jsxRuntime.jsx(ContainerAlias, { hasBottomMargin: true, children: renderElement({ id: "alias" }) }), jsxRuntime.jsx(ContainerValue, { column: !twoColumns, alignItems: "center", children: hasItems ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ContainerChart, { children: renderElement({ id: "chart" }) }), jsxRuntime.jsx(ContainerLegend, { children: renderElement({ id: "legend" }) })] })) : (jsxRuntime.jsx(jsxRuntime.Fragment, { children: "\u2014" })) })] }))] }));
|
|
5828
5842
|
});
|
|
5829
5843
|
|
|
5830
|
-
const PagesContainer =
|
|
5844
|
+
const PagesContainer = React.memo(({ type }) => {
|
|
5831
5845
|
const { config } = useWidgetConfig(type);
|
|
5832
5846
|
const { pageIndex, currentPage } = useWidgetPage(type);
|
|
5833
5847
|
const { selectedTabId, setSelectedTabId, expandedContainers, attributes } = useWidgetContext(type);
|
|
5834
5848
|
const { options } = config || {};
|
|
5835
5849
|
const { column } = options || {};
|
|
5836
5850
|
const isColumn = column === undefined || column;
|
|
5837
|
-
const filteredChildren =
|
|
5851
|
+
const filteredChildren = React.useMemo(() => !selectedTabId
|
|
5838
5852
|
? currentPage.children
|
|
5839
5853
|
: currentPage.children.filter(item => !item.options?.tabId || item.options.tabId === selectedTabId), [currentPage.children, selectedTabId]);
|
|
5840
|
-
const renderElement =
|
|
5854
|
+
const renderElement = React.useMemo(() => getRenderElement({
|
|
5841
5855
|
type,
|
|
5842
5856
|
config,
|
|
5843
5857
|
elementConfig: currentPage,
|
|
@@ -5860,11 +5874,11 @@ const PagesContainer = react.memo(({ type }) => {
|
|
|
5860
5874
|
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: config, type: type, renderElement: renderElement }), jsxRuntime.jsx(Container, { isColumn: isColumn, isMain: true, children: jsxRuntime.jsx(ContainerChildren, { items: filteredChildren, isMain: true, renderElement: renderElement }) })] }));
|
|
5861
5875
|
});
|
|
5862
5876
|
|
|
5863
|
-
const TwoColumnsInnerContainer =
|
|
5877
|
+
const TwoColumnsInnerContainer = React.memo(({ renderElement }) => {
|
|
5864
5878
|
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs(TwoColumnContainerWrapper, { children: [jsxRuntime.jsxs(Container, { children: [jsxRuntime.jsx(ContainerAlias, { children: renderElement({ id: "firstAlias" }) }), jsxRuntime.jsx(ContainerValue, { big: true, children: renderElement({ id: "firstValue" }) })] }), jsxRuntime.jsxs(Container, { children: [jsxRuntime.jsx(ContainerAlias, { children: renderElement({ id: "secondAlias" }) }), jsxRuntime.jsx(ContainerValue, { big: true, children: renderElement({ id: "secondValue" }) })] })] }), renderElement({ id: "thirdContainer" })] }));
|
|
5865
5879
|
});
|
|
5866
5880
|
|
|
5867
|
-
const ImageContainerBg = styled.div `
|
|
5881
|
+
const ImageContainerBg$1 = styled.div `
|
|
5868
5882
|
position: absolute;
|
|
5869
5883
|
top: 0;
|
|
5870
5884
|
bottom: 0;
|
|
@@ -5924,9 +5938,9 @@ const ImageContainerWrapper = styled(uilibGl.Flex) `
|
|
|
5924
5938
|
}
|
|
5925
5939
|
`;
|
|
5926
5940
|
|
|
5927
|
-
const ImageContainer =
|
|
5941
|
+
const ImageContainer = React.memo(({ elementConfig, renderElement }) => {
|
|
5928
5942
|
const { style } = elementConfig || {};
|
|
5929
|
-
return (jsxRuntime.jsxs(ImageContainerWrapper, { style: style, children: [jsxRuntime.jsx(ImageContainerTitle, { children: renderElement({ id: "alias" }) }), jsxRuntime.jsx(ImageContainerText, { children: renderElement({ id: "text" }) }), renderElement({ id: "button" }), jsxRuntime.jsx(ImageContainerBg, { children: renderElement({ id: "image" }) })] }));
|
|
5943
|
+
return (jsxRuntime.jsxs(ImageContainerWrapper, { style: style, children: [jsxRuntime.jsx(ImageContainerTitle, { children: renderElement({ id: "alias" }) }), jsxRuntime.jsx(ImageContainerText, { children: renderElement({ id: "text" }) }), renderElement({ id: "button" }), jsxRuntime.jsx(ImageContainerBg$1, { children: renderElement({ id: "image" }) })] }));
|
|
5930
5944
|
});
|
|
5931
5945
|
|
|
5932
5946
|
const IconContainerWrapper = styled(uilibGl.Flex) `
|
|
@@ -5977,16 +5991,16 @@ const IconContainerText = styled.div `
|
|
|
5977
5991
|
color: ${({ theme: { palette } }) => palette.textSecondary};
|
|
5978
5992
|
`;
|
|
5979
5993
|
|
|
5980
|
-
const IconContainer =
|
|
5994
|
+
const IconContainer = React.memo(({ elementConfig, renderElement }) => {
|
|
5981
5995
|
return (jsxRuntime.jsxs(IconContainerWrapper, { style: elementConfig?.style, children: [jsxRuntime.jsxs(IconContainerHeaderWrapper, { children: [jsxRuntime.jsxs(IconContainerHeader, { children: [renderElement({ id: "icon" }), jsxRuntime.jsx(IconContainerTitle, { children: renderElement({ id: "alias" }) })] }), renderElement({ id: "link" })] }), jsxRuntime.jsx(IconContainerText, { children: renderElement({ id: "text" }) })] }));
|
|
5982
5996
|
});
|
|
5983
5997
|
|
|
5984
|
-
const DataSourceContainer =
|
|
5998
|
+
const DataSourceContainer = React.memo(({ config, elementConfig, type, innerComponent, renderElement }) => {
|
|
5985
5999
|
const { dataSources, expandedContainers } = useWidgetContext(type);
|
|
5986
6000
|
const { id, style, options } = elementConfig || {};
|
|
5987
6001
|
const { column = true, relatedDataSource, expandable, expanded } = options || {};
|
|
5988
6002
|
const isVisible = isVisibleContainer(id, expandable, expanded, expandedContainers);
|
|
5989
|
-
const dataSource =
|
|
6003
|
+
const dataSource = React.useMemo(() => dataSources?.find(({ name }) => name === relatedDataSource), [dataSources, relatedDataSource]);
|
|
5990
6004
|
if (!relatedDataSource)
|
|
5991
6005
|
return null;
|
|
5992
6006
|
if (dataSource && !dataSource.features) {
|
|
@@ -6075,26 +6089,26 @@ const ContainerTitle = styled(uilibGl.Flex) `
|
|
|
6075
6089
|
`}
|
|
6076
6090
|
`;
|
|
6077
6091
|
|
|
6078
|
-
const TitleContainer =
|
|
6092
|
+
const TitleContainer = React.memo(({ containerId, templateName, layerNames, fontColor, expandable, expanded, isVisible, elementConfig, renderElement, type, }) => {
|
|
6079
6093
|
const { expandContainer, expandedContainers, setDashboardLayer } = useWidgetContext(type);
|
|
6080
6094
|
const [layersVisibility, toggleVisibility] = useToggle(true);
|
|
6081
6095
|
const { palette } = styled.useTheme();
|
|
6082
6096
|
const { style, options } = elementConfig || {};
|
|
6083
6097
|
const { simple } = options || {};
|
|
6084
6098
|
const isLayers = templateName === exports.ContainerTemplate.Layers;
|
|
6085
|
-
const onClick =
|
|
6099
|
+
const onClick = React.useCallback(() => {
|
|
6086
6100
|
if (!expandable)
|
|
6087
6101
|
return;
|
|
6088
6102
|
expandContainer(containerId, expanded);
|
|
6089
6103
|
}, [containerId, expandContainer, expandable, expanded]);
|
|
6090
|
-
const onToggleVisibility =
|
|
6104
|
+
const onToggleVisibility = React.useCallback(() => {
|
|
6091
6105
|
toggleVisibility();
|
|
6092
6106
|
layerNames?.forEach(layerName => {
|
|
6093
6107
|
setDashboardLayer({ name: layerName, isVisible: !layersVisibility });
|
|
6094
6108
|
});
|
|
6095
6109
|
}, [layerNames, layersVisibility, setDashboardLayer, toggleVisibility]);
|
|
6096
|
-
const renderVisibility =
|
|
6097
|
-
const renderToggler =
|
|
6110
|
+
const renderVisibility = React.useMemo(() => isLayers && (jsxRuntime.jsx(uilibGl.FlexSpan, { mr: "-1rem", children: jsxRuntime.jsx(uilibGl.IconToggle, { kind: layersVisibility ? "password_show" : "password_hide", className: "feature-visible", isSelected: layersVisibility, onClick: onToggleVisibility }) })), [isLayers, layersVisibility, onToggleVisibility]);
|
|
6111
|
+
const renderToggler = React.useMemo(() => !!containerId &&
|
|
6098
6112
|
expandable && (jsxRuntime.jsx("div", { children: jsxRuntime.jsx(uilibGl.LegendToggler, { color: palette.icon, toggled: expandedContainers?.[containerId] !== undefined ? expandedContainers[containerId] : expanded, onClick: onClick }) })), [containerId, expandable, expanded, expandedContainers, onClick, palette.icon]);
|
|
6099
6113
|
return (jsxRuntime.jsx(Container, { isTitle: isVisible, style: style, children: jsxRuntime.jsxs(ContainerTitle, { simple: simple, children: [jsxRuntime.jsxs(ContainerIconTitle, { fontColor: fontColor, children: [renderElement({ id: "titleIcon", wrap: false }), renderElement({ id: "title" }), isLayers && renderToggler] }), !isLayers && renderToggler, renderVisibility] }) }));
|
|
6100
6114
|
});
|
|
@@ -6104,11 +6118,11 @@ const ContainerDivider = styled(uilibGl.Divider) `
|
|
|
6104
6118
|
border-color: ${({ theme: { palette }, $bgColor }) => $bgColor || palette.elementDeep};
|
|
6105
6119
|
`;
|
|
6106
6120
|
|
|
6107
|
-
const DividerContainer =
|
|
6121
|
+
const DividerContainer = React.memo(({ elementConfig, config }) => {
|
|
6108
6122
|
return (jsxRuntime.jsx(Container, { style: elementConfig?.style, children: jsxRuntime.jsx(ContainerDivider, { "$bgColor": config?.options?.bgColor }) }));
|
|
6109
6123
|
});
|
|
6110
6124
|
|
|
6111
|
-
const SlideshowContainer =
|
|
6125
|
+
const SlideshowContainer = React.memo(({ config, elementConfig, type }) => {
|
|
6112
6126
|
const { pageIndex, expandedContainers, selectedTabId, setSelectedTabId, dataSources } = useWidgetContext(type);
|
|
6113
6127
|
const { attributes, layerInfo } = useRelatedDataSourceAttributes({
|
|
6114
6128
|
type,
|
|
@@ -6118,7 +6132,7 @@ const SlideshowContainer = react.memo(({ config, elementConfig, type }) => {
|
|
|
6118
6132
|
const { id, options } = elementConfig || {};
|
|
6119
6133
|
const { expandable, expanded } = options || {};
|
|
6120
6134
|
const isVisible = isVisibleContainer(id, expandable, expanded, expandedContainers);
|
|
6121
|
-
const render =
|
|
6135
|
+
const render = React.useMemo(() => getRenderElement({
|
|
6122
6136
|
config,
|
|
6123
6137
|
elementConfig,
|
|
6124
6138
|
attributes,
|
|
@@ -6146,7 +6160,7 @@ const SlideshowContainer = react.memo(({ config, elementConfig, type }) => {
|
|
|
6146
6160
|
}) })] }))] }));
|
|
6147
6161
|
});
|
|
6148
6162
|
|
|
6149
|
-
const CameraContainer =
|
|
6163
|
+
const CameraContainer = React.memo(({ elementConfig, type, renderElement }) => {
|
|
6150
6164
|
const { expandedContainers } = useWidgetContext(type);
|
|
6151
6165
|
const { id, options, style } = elementConfig || {};
|
|
6152
6166
|
const { expandable, expanded } = options || {};
|
|
@@ -6232,28 +6246,28 @@ const SwiperContainer = styled.div `
|
|
|
6232
6246
|
}
|
|
6233
6247
|
`;
|
|
6234
6248
|
|
|
6235
|
-
const TabsContainer =
|
|
6249
|
+
const TabsContainer = React.memo(({ elementConfig, type }) => {
|
|
6236
6250
|
const { palette } = styled.useTheme();
|
|
6237
6251
|
const { selectedTabId, setSelectedTabId } = useWidgetContext(type);
|
|
6238
6252
|
const { options, style, children: tabs } = elementConfig || {};
|
|
6239
6253
|
const { radius, column, bgColor, noBg, onlyIcon, shownItems, maxLength = 12 } = options || {};
|
|
6240
|
-
const renderIcon =
|
|
6254
|
+
const renderIcon = React.useCallback((icon, active) => {
|
|
6241
6255
|
if (!icon)
|
|
6242
6256
|
return null;
|
|
6243
6257
|
if (!icon.includes("."))
|
|
6244
6258
|
return jsxRuntime.jsx(uilibGl.Icon, { kind: icon });
|
|
6245
6259
|
return icon.endsWith(".svg") ? (jsxRuntime.jsx(SvgImage, { url: icon, width: 16, fontColor: active ? palette.textContrast : palette.textSecondary })) : (jsxRuntime.jsx("img", { src: icon, alt: "" }));
|
|
6246
6260
|
}, [palette.textContrast, palette.textSecondary]);
|
|
6247
|
-
const onClick =
|
|
6261
|
+
const onClick = React.useCallback((id) => {
|
|
6248
6262
|
setSelectedTabId(id);
|
|
6249
6263
|
window.location.hash = `#${id}`;
|
|
6250
6264
|
}, [setSelectedTabId]);
|
|
6251
|
-
|
|
6265
|
+
React.useEffect(() => {
|
|
6252
6266
|
if (!selectedTabId) {
|
|
6253
6267
|
setSelectedTabId(tabs[0].id);
|
|
6254
6268
|
}
|
|
6255
6269
|
}, []);
|
|
6256
|
-
return (jsxRuntime.jsx(SwiperContainer, { style: style, children: jsxRuntime.jsx(react
|
|
6270
|
+
return (jsxRuntime.jsx(SwiperContainer, { style: style, children: jsxRuntime.jsx(react.Swiper, { spaceBetween: 0, slidesPerView: shownItems || 2, children: tabs.map(({ id, value, options: tabOptions }) => (jsxRuntime.jsxs(react.SwiperSlide, { children: [jsxRuntime.jsxs(TabContainer, { href: `#${id}`, active: selectedTabId === id, column: column, bgColor: bgColor, noBg: noBg, radius: radius, onlyIcon: onlyIcon, hasIcon: !!tabOptions?.icon, onClick: () => onClick(id), children: [renderIcon(tabOptions?.icon, selectedTabId === id), !onlyIcon && (jsxRuntime.jsx(TabValue, { children: jsxRuntime.jsx(TextTrim, { maxLength: maxLength, children: value }) }))] }), jsxRuntime.jsx(TabAnchor, { id: id })] }, id))) }) }));
|
|
6257
6271
|
});
|
|
6258
6272
|
|
|
6259
6273
|
const RoundedBackgroundContainerWrapper = styled(uilibGl.Flex) `
|
|
@@ -6328,7 +6342,7 @@ const RoundedBackgroundContainerWrapper = styled(uilibGl.Flex) `
|
|
|
6328
6342
|
`;
|
|
6329
6343
|
|
|
6330
6344
|
const ALIAS_DEFAULT_MAX_LENGTH = 28;
|
|
6331
|
-
const RoundedBackgroundContainer =
|
|
6345
|
+
const RoundedBackgroundContainer = React.memo(({ type, elementConfig, feature, renderElement }) => {
|
|
6332
6346
|
const { dataSources } = useWidgetContext(type);
|
|
6333
6347
|
const { attributes } = useRelatedDataSourceAttributes({
|
|
6334
6348
|
type,
|
|
@@ -6342,13 +6356,13 @@ const RoundedBackgroundContainer = react.memo(({ type, elementConfig, feature, r
|
|
|
6342
6356
|
const unitsElement = children?.find(({ id }) => id === "units");
|
|
6343
6357
|
const valueElement = children?.find(({ id }) => id === "value");
|
|
6344
6358
|
const value = renderElement({ id: "value" });
|
|
6345
|
-
const color =
|
|
6359
|
+
const color = React.useMemo(() => attributes?.find(({ name }) => name === colorAttribute)?.value || fontColor, [attributes, colorAttribute, fontColor]);
|
|
6346
6360
|
if (!value && hideEmpty)
|
|
6347
6361
|
return null;
|
|
6348
6362
|
return (jsxRuntime.jsxs(RoundedBackgroundContainerWrapper, { style: innerTemplateStyle || style, "$center": center, "$color": color, "$inlineUnits": inlineUnits, "$bigIcon": bigIcon, children: [renderElement({ id: "icon", wrap: false }), jsxRuntime.jsxs(ContainerValue, { style: valueElement?.style, big: true, children: [value, !!unitsElement && (jsxRuntime.jsx(ContainerUnits, { style: unitsElement?.style, children: renderElement({ id: "units" }) }))] }), jsxRuntime.jsx(ContainerAlias, { style: aliasElement?.style, children: jsxRuntime.jsx(TextTrim, { maxLength: maxLength || ALIAS_DEFAULT_MAX_LENGTH, children: renderElement({ id: "alias", wrap: false }) }) })] }));
|
|
6349
6363
|
});
|
|
6350
6364
|
|
|
6351
|
-
const AddFeatureContainer =
|
|
6365
|
+
const AddFeatureContainer = React.memo(({ elementConfig }) => {
|
|
6352
6366
|
const { children, style } = elementConfig || {};
|
|
6353
6367
|
return (jsxRuntime.jsx(Container, { style: style, children: children
|
|
6354
6368
|
.filter(({ type }) => type === "button")
|
|
@@ -6371,21 +6385,20 @@ const LayersContainerWrapper = styled(Container) `
|
|
|
6371
6385
|
}
|
|
6372
6386
|
`;
|
|
6373
6387
|
|
|
6374
|
-
const LayersContainer =
|
|
6375
|
-
const { LayerItemComponent } = useGlobalContext();
|
|
6388
|
+
const LayersContainer = React.memo(({ type, elementConfig, renderElement }) => {
|
|
6376
6389
|
const { expandedContainers } = useWidgetContext(type);
|
|
6377
6390
|
const { currentPage } = useWidgetPage(type);
|
|
6378
6391
|
const { id, options, style } = elementConfig || {};
|
|
6379
6392
|
const { layerNames, expandable, expanded } = options || {};
|
|
6380
6393
|
const isVisible = isVisibleContainer(id, expandable, expanded, expandedContainers);
|
|
6381
|
-
const layers =
|
|
6394
|
+
const layers = React.useMemo(() => {
|
|
6382
6395
|
if (!currentPage?.layers)
|
|
6383
6396
|
return [];
|
|
6384
6397
|
if (!layerNames?.length)
|
|
6385
6398
|
return currentPage.layers;
|
|
6386
6399
|
return currentPage.layers.filter(({ name }) => layerNames.includes(name));
|
|
6387
6400
|
}, [currentPage?.layers, layerNames]);
|
|
6388
|
-
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsx(LayersContainerWrapper, { style: style, children: jsxRuntime.jsx(LayerTree, { layers: layers,
|
|
6401
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsx(LayersContainerWrapper, { style: style, children: jsxRuntime.jsx(LayerTree, { layers: layers, onlyMainTools: true }) }))] }));
|
|
6389
6402
|
});
|
|
6390
6403
|
|
|
6391
6404
|
const containerComponents = {
|
|
@@ -6414,198 +6427,521 @@ const containerComponents = {
|
|
|
6414
6427
|
|
|
6415
6428
|
const getContainerComponent = (innerTemplateName) => innerTemplateName ? containerComponents[innerTemplateName] || containerComponents.default : null;
|
|
6416
6429
|
|
|
6417
|
-
const getDataFromAttributes = (t, config, attributes) => {
|
|
6418
|
-
const colors = config?.options?.colors || FEATURE_CARD_DEFAULT_COLORS;
|
|
6419
|
-
const data = config?.children?.map(({ attributeName }, index) => {
|
|
6420
|
-
const attribute = attributes?.find(({ name }) => name === attributeName);
|
|
6421
|
-
return {
|
|
6422
|
-
name: attribute?.name || "",
|
|
6423
|
-
value: attribute ? Number(attribute.value) : 0,
|
|
6424
|
-
color: colors[index] || FEATURE_CARD_OTHER_COLOR
|
|
6425
|
-
};
|
|
6426
|
-
});
|
|
6427
|
-
if (config?.options?.orderByValue) {
|
|
6428
|
-
data.sort((a, b) => b.value - a.value);
|
|
6429
|
-
}
|
|
6430
|
-
const isOtherSliced = config?.options?.otherItems && config.options.otherItems < data.length;
|
|
6431
|
-
if (!isOtherSliced)
|
|
6432
|
-
return data;
|
|
6433
|
-
const otherValue = data
|
|
6434
|
-
.slice(0, config?.options?.otherItems)
|
|
6435
|
-
.reduce((prev, { value }) => prev + value, 0);
|
|
6436
|
-
return [
|
|
6437
|
-
...data?.slice(0, config.options?.otherItems),
|
|
6438
|
-
{
|
|
6439
|
-
name: t("other", { ns: "dashboard" }),
|
|
6440
|
-
color: FEATURE_CARD_OTHER_COLOR,
|
|
6441
|
-
value: Number(otherValue)
|
|
6442
|
-
}
|
|
6443
|
-
];
|
|
6444
|
-
};
|
|
6445
|
-
|
|
6446
|
-
const getDataFromRelatedFeatures = ({ t, config, filters, relatedConfig, dataSource, layerInfo }) => {
|
|
6447
|
-
if (!dataSource || !dataSource?.features?.length) {
|
|
6448
|
-
return [];
|
|
6449
|
-
}
|
|
6450
|
-
const { colors } = config.options;
|
|
6451
|
-
const layerDefinition = getLayerDefinition(layerInfo);
|
|
6452
|
-
let data = JSON.parse(JSON.stringify(dataSource?.features));
|
|
6453
|
-
const sortAttribute = config?.options?.orderByValue
|
|
6454
|
-
? relatedConfig.attributeName
|
|
6455
|
-
: config?.options?.orderByTitle
|
|
6456
|
-
? relatedConfig.attributeTitle
|
|
6457
|
-
: null;
|
|
6458
|
-
if (sortAttribute) {
|
|
6459
|
-
data.sort((a, b) => b.attributes[sortAttribute] - a.attributes[sortAttribute]);
|
|
6460
|
-
}
|
|
6461
|
-
const isOtherSliced = config?.options?.otherItems && config.options.otherItems < data.length;
|
|
6462
|
-
const otherValue = isOtherSliced
|
|
6463
|
-
? data
|
|
6464
|
-
.slice(config.options.otherItems)
|
|
6465
|
-
.reduce((prev, { attributes }) => prev + attributes[relatedConfig.attributeName], 0)
|
|
6466
|
-
: null;
|
|
6467
|
-
if (isOtherSliced) {
|
|
6468
|
-
data = data.slice(0, config?.options?.otherItems);
|
|
6469
|
-
}
|
|
6470
|
-
const gradientArray = relatedConfig.chartAxis && colors?.length < data.length
|
|
6471
|
-
? new Gradient()
|
|
6472
|
-
.setColorGradient(colors[0], colors[colors.length - 1])
|
|
6473
|
-
.setMidpoint(data.length)
|
|
6474
|
-
.getColors()
|
|
6475
|
-
: colors;
|
|
6476
|
-
const filter = getConfigFilter(relatedConfig?.filterName, filters);
|
|
6477
|
-
const result = data.reduce((acc, feature, index) => {
|
|
6478
|
-
if (relatedConfig?.filterName && !filter) {
|
|
6479
|
-
return acc;
|
|
6480
|
-
}
|
|
6481
|
-
const attributeName = feature.attributes[relatedConfig.attributeName];
|
|
6482
|
-
const attributeTitle = feature.attributes[relatedConfig.attributeTitle];
|
|
6483
|
-
const attributeColor = feature.attributes[relatedConfig.attributeColor];
|
|
6484
|
-
return [
|
|
6485
|
-
...acc,
|
|
6486
|
-
{
|
|
6487
|
-
name: formatAttributeValue({
|
|
6488
|
-
t,
|
|
6489
|
-
type: layerDefinition.attributes[relatedConfig.attributeTitle]?.type,
|
|
6490
|
-
value: attributeTitle,
|
|
6491
|
-
stringFormat: layerDefinition.attributes[relatedConfig.attributeTitle]?.stringFormat
|
|
6492
|
-
}),
|
|
6493
|
-
value: attributeName === null ? null : Number(attributeName),
|
|
6494
|
-
color: attributeColor || gradientArray?.[index] || FEATURE_CARD_OTHER_COLOR,
|
|
6495
|
-
min: filter?.attributeMin ? feature.attributes[filter.attributeMin] : null,
|
|
6496
|
-
max: filter?.attributeMin ? feature.attributes[filter.attributeMax] : null
|
|
6497
|
-
}
|
|
6498
|
-
];
|
|
6499
|
-
}, []);
|
|
6500
|
-
if (isOtherSliced) {
|
|
6501
|
-
result.push({
|
|
6502
|
-
name: t("other", { ns: "dashboard" }),
|
|
6503
|
-
color: FEATURE_CARD_OTHER_COLOR,
|
|
6504
|
-
value: Number(otherValue)
|
|
6505
|
-
});
|
|
6506
|
-
}
|
|
6507
|
-
return result;
|
|
6508
|
-
};
|
|
6509
|
-
|
|
6510
|
-
const getDefaultConfig = ({ title, defaultTitle, items, baseMapName, position, resolution, srid, }) => {
|
|
6511
|
-
const dashboardConfiguration = JSON.parse(JSON.stringify(DEFAULT_DASHBOARD_CONFIG));
|
|
6512
|
-
const defaultPages = JSON.parse(JSON.stringify(DEFAULT_PAGES_CONFIG));
|
|
6513
|
-
const defaultPage = createConfigPage({ title, baseMapName, position, resolution, defaultTitle });
|
|
6514
|
-
if (items?.length) {
|
|
6515
|
-
const contentItems = items.map(item => createConfigLayer(item.name));
|
|
6516
|
-
defaultPage.layers.push(...contentItems);
|
|
6517
|
-
}
|
|
6518
|
-
defaultPages.children.push(defaultPage);
|
|
6519
|
-
dashboardConfiguration.children.push(defaultPages);
|
|
6520
|
-
return dashboardConfiguration;
|
|
6521
|
-
};
|
|
6522
|
-
|
|
6523
|
-
const ElementImage = react.memo(({ type, elementConfig }) => {
|
|
6524
|
-
const { attributes } = useWidgetContext(type);
|
|
6525
|
-
const { value, attributeName, options } = elementConfig || {};
|
|
6526
|
-
const { width } = options || {};
|
|
6527
|
-
const firstImage = react.useMemo(() => {
|
|
6528
|
-
if (value) {
|
|
6529
|
-
return value.toString();
|
|
6530
|
-
}
|
|
6531
|
-
if (!attributeName || Array.isArray(attributeName)) {
|
|
6532
|
-
return null;
|
|
6533
|
-
}
|
|
6534
|
-
const attribute = attributes.find(item => item.name === attributeName);
|
|
6535
|
-
return attribute?.value?.split(";")?.[0];
|
|
6536
|
-
}, [attributeName, attributes, value]);
|
|
6537
|
-
return firstImage ? jsxRuntime.jsx("img", { src: firstImage, alt: firstImage, width: width }) : null;
|
|
6538
|
-
});
|
|
6539
|
-
|
|
6540
|
-
const SmallPreviewContainer$1 = styled.div `
|
|
6541
|
-
width: 100%;
|
|
6542
|
-
height: 100%;
|
|
6543
|
-
`;
|
|
6430
|
+
var img$3 = "data:image/png;base64,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";
|
|
6544
6431
|
|
|
6545
|
-
const
|
|
6546
|
-
|
|
6547
|
-
|
|
6548
|
-
|
|
6432
|
+
const getMaskColor = (isDark) => (isDark ? "0, 0, 0" : "255, 255, 255");
|
|
6433
|
+
const DefaultHeaderContainer = styled(uilibGl.Flex) `
|
|
6434
|
+
flex-direction: column;
|
|
6435
|
+
position: relative;
|
|
6436
|
+
flex-shrink: 0;
|
|
6437
|
+
min-height: 8.375rem;
|
|
6438
|
+
margin-bottom: -1.5rem;
|
|
6439
|
+
padding: 1.5rem 1.5rem 0;
|
|
6440
|
+
border-top-left-radius: 0.5rem;
|
|
6441
|
+
border-top-right-radius: 0.5rem;
|
|
6442
|
+
overflow: hidden;
|
|
6549
6443
|
|
|
6550
|
-
|
|
6551
|
-
|
|
6444
|
+
> * {
|
|
6445
|
+
z-index: 1;
|
|
6446
|
+
}
|
|
6552
6447
|
|
|
6553
|
-
|
|
6448
|
+
&::before {
|
|
6449
|
+
content: "";
|
|
6450
|
+
position: absolute;
|
|
6451
|
+
top: 0;
|
|
6452
|
+
left: 0;
|
|
6554
6453
|
width: 100%;
|
|
6454
|
+
height: 100%;
|
|
6455
|
+
|
|
6456
|
+
${({ image, isDark }) => image
|
|
6457
|
+
? styled.css `
|
|
6458
|
+
background: url(${image}) 0 0 no-repeat;
|
|
6459
|
+
background-size: cover;
|
|
6460
|
+
`
|
|
6461
|
+
: styled.css `
|
|
6462
|
+
background: url(${img$3}) 50% 0 no-repeat;
|
|
6463
|
+
opacity: ${isDark ? 1 : 0.5};
|
|
6464
|
+
`}
|
|
6555
6465
|
}
|
|
6556
|
-
`;
|
|
6557
|
-
const LinearProgressContainer = styled(uilibGl.Flex) `
|
|
6558
|
-
align-items: center;
|
|
6559
|
-
justify-content: center;
|
|
6560
|
-
min-height: inherit;
|
|
6561
6466
|
|
|
6467
|
+
${({ image, isDark }) => image &&
|
|
6468
|
+
styled.css `
|
|
6469
|
+
&::before {
|
|
6470
|
+
-webkit-mask-image: linear-gradient(
|
|
6471
|
+
to bottom,
|
|
6472
|
+
rgba(${getMaskColor(isDark)}, 1),
|
|
6473
|
+
rgba(${getMaskColor(isDark)}, 0)
|
|
6474
|
+
);
|
|
6475
|
+
mask-image: linear-gradient(to bottom, rgba(${getMaskColor(isDark)}, 1), rgba(${getMaskColor(isDark)}, 0));
|
|
6476
|
+
}
|
|
6477
|
+
`}
|
|
6562
6478
|
${uilibGl.LinearProgress} {
|
|
6563
|
-
|
|
6479
|
+
position: absolute;
|
|
6480
|
+
top: 0;
|
|
6481
|
+
left: 0;
|
|
6564
6482
|
}
|
|
6565
6483
|
`;
|
|
6566
|
-
const
|
|
6567
|
-
|
|
6484
|
+
const TopContainer = styled(uilibGl.Flex) `
|
|
6485
|
+
z-index: 1;
|
|
6486
|
+
position: relative;
|
|
6487
|
+
justify-content: space-between;
|
|
6488
|
+
flex-wrap: nowrap;
|
|
6489
|
+
width: 100%;
|
|
6490
|
+
align-items: flex-start;
|
|
6491
|
+
`;
|
|
6492
|
+
const TopContainerButtons = styled(uilibGl.Flex) `
|
|
6568
6493
|
align-items: center;
|
|
6494
|
+
width: auto;
|
|
6495
|
+
margin-right: -0.5rem;
|
|
6569
6496
|
|
|
6570
|
-
|
|
6571
|
-
width:
|
|
6572
|
-
height:
|
|
6497
|
+
button {
|
|
6498
|
+
width: auto;
|
|
6499
|
+
height: 1rem;
|
|
6500
|
+
padding: 0 0.5rem;
|
|
6501
|
+
}
|
|
6502
|
+
`;
|
|
6503
|
+
const LogoContainer = styled(uilibGl.Flex) `
|
|
6504
|
+
max-width: calc(100% - 1.4rem);
|
|
6505
|
+
flex-grow: 1;
|
|
6506
|
+
font-size: 0;
|
|
6573
6507
|
|
|
6574
|
-
|
|
6575
|
-
|
|
6576
|
-
color: ${({ theme: { palette } }) => palette.elementDeep};
|
|
6577
|
-
}
|
|
6508
|
+
& > span::after {
|
|
6509
|
+
font-size: 2rem;
|
|
6578
6510
|
}
|
|
6579
6511
|
|
|
6580
|
-
|
|
6581
|
-
|
|
6582
|
-
color: ${({ theme: { palette } }) => palette.textDisabled};
|
|
6512
|
+
img {
|
|
6513
|
+
max-height: 1.875rem;
|
|
6583
6514
|
}
|
|
6584
6515
|
`;
|
|
6585
|
-
const
|
|
6586
|
-
|
|
6587
|
-
|
|
6588
|
-
|
|
6589
|
-
|
|
6590
|
-
|
|
6591
|
-
|
|
6592
|
-
|
|
6593
|
-
|
|
6594
|
-
|
|
6516
|
+
const PageTitle = styled(uilibGl.H2) `
|
|
6517
|
+
display: -webkit-box;
|
|
6518
|
+
-webkit-line-clamp: 3;
|
|
6519
|
+
-webkit-box-orient: vertical;
|
|
6520
|
+
overflow: hidden;
|
|
6521
|
+
margin: 0;
|
|
6522
|
+
font-size: 1.25rem;
|
|
6523
|
+
font-weight: 600;
|
|
6524
|
+
pointer-events: initial;
|
|
6525
|
+
font-family: "Nunito Sans", serif;
|
|
6526
|
+
`;
|
|
6527
|
+
|
|
6528
|
+
exports.ThemeName = void 0;
|
|
6529
|
+
(function (ThemeName) {
|
|
6530
|
+
ThemeName["Light"] = "light";
|
|
6531
|
+
ThemeName["Dark"] = "dark";
|
|
6532
|
+
})(exports.ThemeName || (exports.ThemeName = {}));
|
|
6533
|
+
|
|
6534
|
+
exports.TmsType = void 0;
|
|
6535
|
+
(function (TmsType) {
|
|
6536
|
+
TmsType["WMS"] = "WMS";
|
|
6537
|
+
TmsType["TMS"] = "TMS";
|
|
6538
|
+
TmsType["ArcGIS"] = "ArcGIS";
|
|
6539
|
+
})(exports.TmsType || (exports.TmsType = {}));
|
|
6540
|
+
exports.EditGeometryType = void 0;
|
|
6541
|
+
(function (EditGeometryType) {
|
|
6542
|
+
EditGeometryType["Raster"] = "raster";
|
|
6543
|
+
})(exports.EditGeometryType || (exports.EditGeometryType = {}));
|
|
6544
|
+
|
|
6545
|
+
const DashboardDefaultHeader = React.memo(() => {
|
|
6546
|
+
const { components: { ProjectCatalogMenu, ProjectPanelMenu, ProjectPagesMenu }, } = useWidgetContext();
|
|
6547
|
+
const { pageId, image, icon, tooltip, themeName } = useDashboardHeader();
|
|
6548
|
+
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, { children: icon }), jsxRuntime.jsxs(TopContainerButtons, { children: [jsxRuntime.jsx(ProjectCatalogMenu, {}), 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.jsx(uilibGl.FlexSpan, { flexGrow: 1, children: jsxRuntime.jsx(uilibGl.Tooltip, { arrow: true, content: tooltip, children: ref => (jsxRuntime.jsx(PageTitle, { ref: ref, children: jsxRuntime.jsx(ProjectPagesMenu, {}) })) }) }), jsxRuntime.jsx(uilibGl.FlexSpan, { children: jsxRuntime.jsx(Pagination, {}) })] }) }) }) })] })] }));
|
|
6549
|
+
});
|
|
6550
|
+
|
|
6551
|
+
const HeaderFrontView = styled(uilibGl.Flex) `
|
|
6552
|
+
z-index: 10;
|
|
6553
|
+
position: relative;
|
|
6554
|
+
justify-content: space-between;
|
|
6555
|
+
align-items: ${({ isDefault }) => (isDefault ? "center" : "flex-start")};
|
|
6556
|
+
width: 100%;
|
|
6557
|
+
font: ${({ theme: { fonts } }) => fonts.subtitle};
|
|
6558
|
+
`;
|
|
6559
|
+
const HeaderContainer = styled(uilibGl.FlexSpan) `
|
|
6560
|
+
display: flex;
|
|
6561
|
+
flex-grow: 1;
|
|
6562
|
+
flex-wrap: nowrap;
|
|
6563
|
+
width: calc(100% - 48px);
|
|
6564
|
+
`;
|
|
6565
|
+
const FeatureTitleContainer = styled.div `
|
|
6566
|
+
display: -webkit-box;
|
|
6567
|
+
max-width: 100%;
|
|
6568
|
+
width: 100%;
|
|
6569
|
+
margin: 0.5rem 0;
|
|
6570
|
+
-webkit-line-clamp: 2;
|
|
6571
|
+
-webkit-box-orient: vertical;
|
|
6572
|
+
overflow: hidden;
|
|
6573
|
+
text-overflow: ellipsis;
|
|
6574
|
+
color: ${({ theme: { palette } }) => palette.textPrimary};
|
|
6595
6575
|
|
|
6596
|
-
|
|
6597
|
-
|
|
6598
|
-
|
|
6576
|
+
& > ${uilibGl.FlexSpan} {
|
|
6577
|
+
cursor: ${({ clickable }) => clickable && "pointer"};
|
|
6578
|
+
|
|
6579
|
+
&:hover {
|
|
6580
|
+
color: ${({ clickable, theme: { palette } }) => clickable && palette.primary};
|
|
6581
|
+
}
|
|
6599
6582
|
}
|
|
6600
6583
|
`;
|
|
6601
|
-
const
|
|
6602
|
-
|
|
6603
|
-
|
|
6604
|
-
|
|
6605
|
-
|
|
6584
|
+
const LayerDescription = styled(uilibGl.Description) `
|
|
6585
|
+
width: calc(100% - 4rem);
|
|
6586
|
+
display: -webkit-box;
|
|
6587
|
+
-webkit-line-clamp: 2;
|
|
6588
|
+
-webkit-box-orient: vertical;
|
|
6589
|
+
overflow: hidden;
|
|
6590
|
+
text-overflow: ellipsis;
|
|
6591
|
+
`;
|
|
6592
|
+
const HeaderTitleContainer = styled(uilibGl.Flex) `
|
|
6593
|
+
flex-direction: column;
|
|
6606
6594
|
width: 100%;
|
|
6607
|
-
|
|
6608
|
-
|
|
6595
|
+
`;
|
|
6596
|
+
const RowHeaderMixin = styled.css `
|
|
6597
|
+
&&& {
|
|
6598
|
+
min-height: auto;
|
|
6599
|
+
|
|
6600
|
+
${FeatureTitleContainer}, ${LayerDescription} {
|
|
6601
|
+
text-align: left;
|
|
6602
|
+
}
|
|
6603
|
+
}
|
|
6604
|
+
|
|
6605
|
+
${HeaderContainer} {
|
|
6606
|
+
flex-direction: row;
|
|
6607
|
+
}
|
|
6608
|
+
|
|
6609
|
+
${FeatureTitleContainer} {
|
|
6610
|
+
max-width: calc(100% - 3.8rem);
|
|
6611
|
+
}
|
|
6612
|
+
`;
|
|
6613
|
+
const Header = styled(uilibGl.Flex) `
|
|
6614
|
+
z-index: 1;
|
|
6615
|
+
position: relative;
|
|
6616
|
+
top: 0;
|
|
6617
|
+
flex-shrink: 0;
|
|
6618
|
+
overflow: hidden;
|
|
6619
|
+
padding: 0.5rem;
|
|
6620
|
+
|
|
6621
|
+
${HeaderContainer} {
|
|
6622
|
+
flex-direction: column;
|
|
6623
|
+
}
|
|
6624
|
+
|
|
6625
|
+
${({ $isRow }) => $isRow && RowHeaderMixin};
|
|
6626
|
+
`;
|
|
6627
|
+
|
|
6628
|
+
const HeaderTitle = ({ noFeature }) => {
|
|
6629
|
+
const { t } = useGlobalContext();
|
|
6630
|
+
const { attributes, layerInfo, feature } = useWidgetContext(exports.WidgetType.FeatureCard);
|
|
6631
|
+
const zoomToFeatures = useZoomToFeatures();
|
|
6632
|
+
const { alias, name, layerDefinition } = layerInfo || {};
|
|
6633
|
+
const resultDescription = alias || name || "";
|
|
6634
|
+
const resultTitle = React.useMemo(() => {
|
|
6635
|
+
const layerDefinitionAttribute = layerDefinition && attributes?.length
|
|
6636
|
+
? attributes.find(item => item.name === layerDefinition.titleAttribute)
|
|
6637
|
+
: null;
|
|
6638
|
+
const layerDefinitionTitle = layerDefinition?.titleAttribute && layerDefinitionAttribute?.value
|
|
6639
|
+
? layerDefinitionAttribute.value
|
|
6640
|
+
: null;
|
|
6641
|
+
return ((!!layerDefinitionTitle &&
|
|
6642
|
+
formatAttributeValue({
|
|
6643
|
+
t,
|
|
6644
|
+
type: layerDefinitionAttribute.type,
|
|
6645
|
+
value: layerDefinitionTitle,
|
|
6646
|
+
stringFormat: layerDefinitionAttribute.stringFormat,
|
|
6647
|
+
})) ||
|
|
6648
|
+
feature?.id);
|
|
6649
|
+
}, [attributes, feature, layerDefinition]);
|
|
6650
|
+
return (jsxRuntime.jsxs(HeaderTitleContainer, { children: [noFeature ? (jsxRuntime.jsx(FeatureTitleContainer, { children: t("noObjectFound", { ns: "dashboard" }) })) : (jsxRuntime.jsx(FeatureTitleContainer, { clickable: true, children: jsxRuntime.jsx(uilibGl.Tooltip, { arrow: true, placement: "top", content: t("zoomToFeature", { ns: "dashboard" }), delay: [600, 0], children: ref => (jsxRuntime.jsx(uilibGl.FlexSpan, { ref: ref, onClick: () => zoomToFeatures([feature]), children: resultTitle })) }) })), jsxRuntime.jsx(LayerDescription, { title: resultDescription, children: resultDescription })] }));
|
|
6651
|
+
};
|
|
6652
|
+
|
|
6653
|
+
const LayerIconContainer = styled.div `
|
|
6654
|
+
display: flex;
|
|
6655
|
+
align-items: center;
|
|
6656
|
+
margin-right: 0.75rem;
|
|
6657
|
+
`;
|
|
6658
|
+
const AlertIconContainer = styled(uilibGl.Flex) `
|
|
6659
|
+
align-items: center;
|
|
6660
|
+
justify-content: center;
|
|
6661
|
+
width: 2rem;
|
|
6662
|
+
height: 2rem;
|
|
6663
|
+
|
|
6664
|
+
${uilibGl.Icon} {
|
|
6665
|
+
:after {
|
|
6666
|
+
color: ${({ theme: { palette } }) => palette.error};
|
|
6667
|
+
}
|
|
6668
|
+
}
|
|
6669
|
+
`;
|
|
6670
|
+
|
|
6671
|
+
var img$2 = "data:image/svg+xml,%3csvg width='32' height='32' viewBox='0 0 32 32' fill='none' xmlns='http://www.w3.org/2000/svg'%3e %3crect width='32' height='32' fill='transparent'/%3e %3cpath d='M20.248 9.67787C18.5318 8.04035 15.9473 7.54977 13.7024 8.43543C11.4576 9.32109 9.99566 11.4081 10 13.721C10 18.2894 16 24 16 24C16 24 22 18.2894 22 13.721C22.0028 12.2054 21.3726 10.7509 20.248 9.67787Z' fill='url(%23paint0_linear_6459_10338)'/%3e %3ccircle cx='16' cy='14' r='2' fill='white'/%3e %3cdefs%3e %3clinearGradient id='paint0_linear_6459_10338' x1='10' y1='8' x2='25.36' y2='19.52' gradientUnits='userSpaceOnUse'%3e %3cstop stop-color='%230084D6'/%3e %3cstop offset='0.489583' stop-color='%230084D6'/%3e %3cstop offset='0.489683' stop-color='%2305A9FF'/%3e %3cstop offset='0.921875' stop-color='%2305A9FF'/%3e %3c/linearGradient%3e %3c/defs%3e%3c/svg%3e";
|
|
6672
|
+
|
|
6673
|
+
var img$1 = "data:image/svg+xml,%3csvg width='32' height='32' viewBox='0 0 32 32' fill='none' xmlns='http://www.w3.org/2000/svg'%3e %3crect width='32' height='32' fill='transparent'/%3e %3cpath d='M4 17.9574H10.1538L13.5385 12L18.4615 20L22 13.8723H28' stroke='url(%23paint0_linear_6459_10369)' stroke-width='2' stroke-linejoin='round'/%3e %3cdefs%3e %3clinearGradient id='paint0_linear_6459_10369' x1='4' y1='9.54167' x2='28.7229' y2='20.1484' gradientUnits='userSpaceOnUse'%3e %3cstop offset='0.525942' stop-color='%2306AAFF'/%3e %3cstop offset='0.526042' stop-color='%230184D7'/%3e %3c/linearGradient%3e %3c/defs%3e%3c/svg%3e";
|
|
6674
|
+
|
|
6675
|
+
var img = "data:image/svg+xml,%3csvg width='32' height='32' viewBox='0 0 32 32' fill='none' xmlns='http://www.w3.org/2000/svg'%3e %3crect width='32' height='32' fill='transparent'/%3e %3crect x='8' y='8' width='16' height='16' rx='2' fill='url(%23paint0_linear_6459_10399)'/%3e %3cdefs%3e %3clinearGradient id='paint0_linear_6459_10399' x1='8' y1='8' x2='24' y2='24' gradientUnits='userSpaceOnUse'%3e %3cstop stop-color='%230084D6'/%3e %3cstop offset='0.489583' stop-color='%230084D6'/%3e %3cstop offset='0.489683' stop-color='%2305A9FF'/%3e %3cstop offset='0.921875' stop-color='%2305A9FF'/%3e %3c/linearGradient%3e %3c/defs%3e%3c/svg%3e";
|
|
6676
|
+
|
|
6677
|
+
const LayerIcon = ({ layerInfo }) => {
|
|
6678
|
+
const renderSymbol = React.useMemo(() => {
|
|
6679
|
+
if (!layerInfo.geometryType) {
|
|
6680
|
+
return (jsxRuntime.jsx(AlertIconContainer, { children: jsxRuntime.jsx(uilibGl.Icon, { kind: "warning" }) }));
|
|
6681
|
+
}
|
|
6682
|
+
switch (layerInfo.geometryType) {
|
|
6683
|
+
case api.GeometryType.Polyline:
|
|
6684
|
+
return jsxRuntime.jsx("img", { src: img$1, alt: "" });
|
|
6685
|
+
case api.GeometryType.Polygon:
|
|
6686
|
+
return jsxRuntime.jsx("img", { src: img, alt: "" });
|
|
6687
|
+
case api.GeometryType.Point:
|
|
6688
|
+
default:
|
|
6689
|
+
return jsxRuntime.jsx("img", { src: img$2, alt: "" });
|
|
6690
|
+
}
|
|
6691
|
+
}, [layerInfo.geometryType]);
|
|
6692
|
+
return jsxRuntime.jsx(LayerIconContainer, { children: renderSymbol });
|
|
6693
|
+
};
|
|
6694
|
+
|
|
6695
|
+
const FeatureCardDefaultHeader = ({ noFeature }) => {
|
|
6696
|
+
const { layerInfo } = useWidgetContext(exports.WidgetType.FeatureCard);
|
|
6697
|
+
return (jsxRuntime.jsx(Header, { "$isRow": true, children: jsxRuntime.jsxs(HeaderFrontView, { isDefault: true, children: [jsxRuntime.jsxs(HeaderContainer, { children: [!!layerInfo?.name && jsxRuntime.jsx(LayerIcon, { layerInfo: layerInfo }), jsxRuntime.jsx(HeaderTitle, { noFeature: noFeature })] }), jsxRuntime.jsx(FeatureCardButtons, {})] }) }));
|
|
6698
|
+
};
|
|
6699
|
+
|
|
6700
|
+
const HeaderFontColorMixin$1 = styled.css `
|
|
6701
|
+
${HeaderTitleContainer}, ${LayerDescription} {
|
|
6702
|
+
color: ${({ $fontColor }) => $fontColor};
|
|
6703
|
+
}
|
|
6704
|
+
`;
|
|
6705
|
+
const HeaderWrapperMixin$1 = styled.css `
|
|
6706
|
+
padding: 0.5rem 0.5rem 0;
|
|
6707
|
+
|
|
6708
|
+
${Header} {
|
|
6709
|
+
min-height: 5.25rem;
|
|
6710
|
+
}
|
|
6711
|
+
|
|
6712
|
+
${HeaderContainer} {
|
|
6713
|
+
max-width: 100%;
|
|
6714
|
+
width: 100%;
|
|
6715
|
+
}
|
|
6716
|
+
|
|
6717
|
+
${FeatureControls} {
|
|
6718
|
+
max-width: calc(100% - 2rem);
|
|
6719
|
+
width: calc(100% - 2rem);
|
|
6720
|
+
margin-top: -0.5rem;
|
|
6721
|
+
padding-top: 1rem;
|
|
6722
|
+
border-radius: ${({ theme: { borderRadius } }) => borderRadius.medium};
|
|
6723
|
+
}
|
|
6724
|
+
|
|
6725
|
+
${({ $fontColor }) => !!$fontColor && HeaderFontColorMixin$1};
|
|
6726
|
+
`;
|
|
6727
|
+
const GradientHeaderWrapper = styled.div `
|
|
6728
|
+
${Header} {
|
|
6729
|
+
background: ${({ $bgColor }) => $bgColor || "radial-gradient(129.21% 133.22% at 51.94% 0%, #e8fffe 9.48%, #5fcaff 100%)"};
|
|
6730
|
+
}
|
|
6731
|
+
|
|
6732
|
+
${HeaderContainer} {
|
|
6733
|
+
align-items: center;
|
|
6734
|
+
}
|
|
6735
|
+
|
|
6736
|
+
${HeaderTitleContainer} {
|
|
6737
|
+
margin-left: 0;
|
|
6738
|
+
text-align: center;
|
|
6739
|
+
}
|
|
6740
|
+
|
|
6741
|
+
${FeatureTitleContainer} {
|
|
6742
|
+
text-align: center;
|
|
6743
|
+
}
|
|
6744
|
+
|
|
6745
|
+
${LayerDescription} {
|
|
6746
|
+
text-align: center;
|
|
6747
|
+
}
|
|
6748
|
+
|
|
6749
|
+
${HeaderWrapperMixin$1};
|
|
6750
|
+
`;
|
|
6751
|
+
|
|
6752
|
+
const FeatureCardGradientHeader = ({ isRow }) => {
|
|
6753
|
+
const { layerInfo } = useWidgetContext(exports.WidgetType.FeatureCard);
|
|
6754
|
+
const { config } = useWidgetConfig(exports.WidgetType.FeatureCard);
|
|
6755
|
+
const { header, options } = config || {};
|
|
6756
|
+
const renderElement = useHeaderRender(header);
|
|
6757
|
+
return (jsxRuntime.jsx(GradientHeaderWrapper, { "$fontColor": options?.fontColor, "$bgColor": options?.bgColor, children: jsxRuntime.jsx(uilibGl.ThemeProvider, { theme: uilibGl.defaultTheme, children: jsxRuntime.jsx(Header, { "$isRow": isRow, children: jsxRuntime.jsxs(HeaderFrontView, { children: [jsxRuntime.jsxs(HeaderContainer, { children: [jsxRuntime.jsx(LayerIcon, { layerInfo: layerInfo }), jsxRuntime.jsx(FeatureCardTitle, { title: renderElement({
|
|
6758
|
+
id: "title",
|
|
6759
|
+
wrap: false,
|
|
6760
|
+
}), description: renderElement({
|
|
6761
|
+
id: "description",
|
|
6762
|
+
wrap: false,
|
|
6763
|
+
}) })] }), jsxRuntime.jsx(FeatureCardButtons, {})] }) }) }) }));
|
|
6764
|
+
};
|
|
6765
|
+
|
|
6766
|
+
const HeaderFontColorMixin = styled.css `
|
|
6767
|
+
${HeaderTitleContainer}, ${LayerDescription} {
|
|
6768
|
+
color: ${({ $fontColor }) => $fontColor};
|
|
6769
|
+
}
|
|
6770
|
+
`;
|
|
6771
|
+
const HeaderWrapperMixin = styled.css `
|
|
6772
|
+
padding: 0.5rem 0.5rem 0;
|
|
6773
|
+
|
|
6774
|
+
${Header} {
|
|
6775
|
+
min-height: 5.25rem;
|
|
6776
|
+
}
|
|
6777
|
+
|
|
6778
|
+
${HeaderContainer} {
|
|
6779
|
+
max-width: 100%;
|
|
6780
|
+
width: 100%;
|
|
6781
|
+
}
|
|
6782
|
+
|
|
6783
|
+
${FeatureControls} {
|
|
6784
|
+
max-width: calc(100% - 2rem);
|
|
6785
|
+
width: calc(100% - 2rem);
|
|
6786
|
+
margin-top: -0.5rem;
|
|
6787
|
+
padding-top: 1rem;
|
|
6788
|
+
border-radius: ${({ theme: { borderRadius } }) => borderRadius.medium};
|
|
6789
|
+
}
|
|
6790
|
+
|
|
6791
|
+
${({ $fontColor }) => !!$fontColor && HeaderFontColorMixin};
|
|
6792
|
+
`;
|
|
6793
|
+
const HeaderIcon = styled(uilibGl.Flex) `
|
|
6794
|
+
position: absolute;
|
|
6795
|
+
top: 0;
|
|
6796
|
+
right: 0;
|
|
6797
|
+
justify-content: flex-end;
|
|
6798
|
+
align-items: center;
|
|
6799
|
+
min-width: 7.5rem;
|
|
6800
|
+
height: 100%;
|
|
6801
|
+
|
|
6802
|
+
span[kind]:after {
|
|
6803
|
+
font-size: 7.5rem;
|
|
6804
|
+
}
|
|
6805
|
+
|
|
6806
|
+
span[kind]:after,
|
|
6807
|
+
path,
|
|
6808
|
+
line,
|
|
6809
|
+
circle {
|
|
6810
|
+
fill: rgba(255, 255, 255, 0.36);
|
|
6811
|
+
}
|
|
6812
|
+
|
|
6813
|
+
&& > * {
|
|
6814
|
+
display: flex;
|
|
6815
|
+
align-items: center;
|
|
6816
|
+
height: 100%;
|
|
6817
|
+
}
|
|
6818
|
+
`;
|
|
6819
|
+
const BigIconHeaderMixin = styled.css `
|
|
6820
|
+
${HeaderIcon} {
|
|
6821
|
+
min-width: 14rem;
|
|
6822
|
+
right: -3rem;
|
|
6823
|
+
|
|
6824
|
+
span[kind]:after {
|
|
6825
|
+
font-size: 14rem;
|
|
6826
|
+
}
|
|
6827
|
+
}
|
|
6828
|
+
`;
|
|
6829
|
+
const IconHeaderWrapper = styled.div `
|
|
6830
|
+
${Header} {
|
|
6831
|
+
width: calc(100% + 3rem);
|
|
6832
|
+
margin: -1.5rem -1.5rem 0 -1.5rem;
|
|
6833
|
+
padding: 1.5rem;
|
|
6834
|
+
border-top-left-radius: 0.5rem;
|
|
6835
|
+
border-top-right-radius: 0.5rem;
|
|
6836
|
+
background: ${({ $bgColor }) => $bgColor || "linear-gradient(96.55deg, #FFFCD3 0%, #B4DC47 100%)"};
|
|
6837
|
+
}
|
|
6838
|
+
|
|
6839
|
+
${HeaderWrapperMixin};
|
|
6840
|
+
|
|
6841
|
+
${({ $bigIcon }) => $bigIcon && BigIconHeaderMixin};
|
|
6842
|
+
`;
|
|
6843
|
+
|
|
6844
|
+
const FeatureCardIconHeader = ({ isRow }) => {
|
|
6845
|
+
const { layerInfo } = useWidgetContext(exports.WidgetType.FeatureCard);
|
|
6846
|
+
const { config } = useWidgetConfig(exports.WidgetType.FeatureCard);
|
|
6847
|
+
const { header, options } = config || {};
|
|
6848
|
+
const renderElement = useHeaderRender(header);
|
|
6849
|
+
return (jsxRuntime.jsx(IconHeaderWrapper, { "$fontColor": options?.fontColor, "$bgColor": options?.bgColor, "$bigIcon": options?.bigIcon, children: jsxRuntime.jsx(uilibGl.ThemeProvider, { theme: uilibGl.defaultTheme, children: jsxRuntime.jsxs(Header, { "$isRow": isRow, children: [jsxRuntime.jsxs(HeaderFrontView, { children: [jsxRuntime.jsxs(HeaderContainer, { children: [jsxRuntime.jsx(LayerIcon, { layerInfo: layerInfo }), jsxRuntime.jsx(FeatureCardTitle, { title: renderElement({
|
|
6850
|
+
id: "title",
|
|
6851
|
+
wrap: false,
|
|
6852
|
+
}), description: renderElement({
|
|
6853
|
+
id: "description",
|
|
6854
|
+
wrap: false,
|
|
6855
|
+
}) })] }), jsxRuntime.jsx(FeatureCardButtons, {})] }), jsxRuntime.jsx(HeaderIcon, { children: renderElement({
|
|
6856
|
+
id: "icon",
|
|
6857
|
+
wrap: false,
|
|
6858
|
+
}) })] }) }) }));
|
|
6859
|
+
};
|
|
6860
|
+
|
|
6861
|
+
const ImageContainerButton = styled(uilibGl.FlatButton) `
|
|
6862
|
+
min-height: 1.5rem;
|
|
6863
|
+
border-radius: ${({ theme: { borderRadius } }) => borderRadius.large};
|
|
6864
|
+
background-color: ${({ theme: { palette } }) => palette.primary};
|
|
6865
|
+
text-transform: none;
|
|
6866
|
+
|
|
6867
|
+
:hover {
|
|
6868
|
+
background-color: ${({ theme: { palette } }) => palette.primaryDeep};
|
|
6869
|
+
}
|
|
6870
|
+
`;
|
|
6871
|
+
|
|
6872
|
+
const ElementButton = React.memo(({ type, elementConfig }) => {
|
|
6873
|
+
const { attributes } = useWidgetContext(type);
|
|
6874
|
+
const attribute = getAttributeByName(elementConfig?.attributeName, attributes);
|
|
6875
|
+
const link = attribute?.value;
|
|
6876
|
+
if (!link || typeof link !== "string")
|
|
6877
|
+
return null;
|
|
6878
|
+
return (jsxRuntime.jsx(ImageContainerButton, { onClick: () => window.open(attribute?.value), children: elementConfig.value || "" }));
|
|
6879
|
+
});
|
|
6880
|
+
|
|
6881
|
+
const AttributeGalleryContainer = styled.div `
|
|
6882
|
+
&& {
|
|
6883
|
+
width: calc(100% + 3rem);
|
|
6884
|
+
}
|
|
6885
|
+
|
|
6886
|
+
min-height: 12.625rem;
|
|
6887
|
+
background-color: ${({ theme: { palette } }) => palette.element};
|
|
6888
|
+
|
|
6889
|
+
img {
|
|
6890
|
+
width: 100%;
|
|
6891
|
+
}
|
|
6892
|
+
`;
|
|
6893
|
+
const LinearProgressContainer = styled(uilibGl.Flex) `
|
|
6894
|
+
align-items: center;
|
|
6895
|
+
justify-content: center;
|
|
6896
|
+
min-height: inherit;
|
|
6897
|
+
|
|
6898
|
+
${uilibGl.LinearProgress} {
|
|
6899
|
+
max-width: 4rem;
|
|
6900
|
+
}
|
|
6901
|
+
`;
|
|
6902
|
+
const NoLiveSnapshotContainer = styled(uilibGl.Flex) `
|
|
6903
|
+
flex-direction: column;
|
|
6904
|
+
align-items: center;
|
|
6905
|
+
|
|
6906
|
+
span[kind="alert"] {
|
|
6907
|
+
width: 2rem;
|
|
6908
|
+
height: 2rem;
|
|
6909
|
+
|
|
6910
|
+
&:after {
|
|
6911
|
+
font-size: 2rem;
|
|
6912
|
+
color: ${({ theme: { palette } }) => palette.elementDeep};
|
|
6913
|
+
}
|
|
6914
|
+
}
|
|
6915
|
+
|
|
6916
|
+
${uilibGl.Description} {
|
|
6917
|
+
font-size: 0.75rem;
|
|
6918
|
+
color: ${({ theme: { palette } }) => palette.textDisabled};
|
|
6919
|
+
}
|
|
6920
|
+
`;
|
|
6921
|
+
const SmallPreviewControl = styled(uilibGl.IconButton) `
|
|
6922
|
+
cursor: ${({ $isDisabled }) => ($isDisabled ? "default" : "pointer")};
|
|
6923
|
+
z-index: 3;
|
|
6924
|
+
position: absolute;
|
|
6925
|
+
top: 50%;
|
|
6926
|
+
width: 2.5rem;
|
|
6927
|
+
height: 2.5rem;
|
|
6928
|
+
margin-top: -1.25rem;
|
|
6929
|
+
background-color: rgba(61, 61, 61, 0.8);
|
|
6930
|
+
border-radius: ${({ theme: { borderRadius } }) => borderRadius.smallest};
|
|
6931
|
+
|
|
6932
|
+
span:after {
|
|
6933
|
+
color: ${({ $isDisabled }) => ($isDisabled ? "rgba(255, 255, 255, 0.28)" : "rgba(255, 255, 255, 1)")};
|
|
6934
|
+
transition: color ${uilibGl.transition.hover};
|
|
6935
|
+
}
|
|
6936
|
+
`;
|
|
6937
|
+
const SmallPreviewCounter = styled(uilibGl.Flex) `
|
|
6938
|
+
z-index: 3;
|
|
6939
|
+
position: absolute;
|
|
6940
|
+
bottom: 0.625rem;
|
|
6941
|
+
left: 0;
|
|
6942
|
+
width: 100%;
|
|
6943
|
+
height: 1rem;
|
|
6944
|
+
justify-content: center;
|
|
6609
6945
|
|
|
6610
6946
|
> div {
|
|
6611
6947
|
background-color: rgba(61, 61, 61, 0.8);
|
|
@@ -6651,7 +6987,7 @@ const imgSlideShowMixin = styled.css `
|
|
|
6651
6987
|
}
|
|
6652
6988
|
}
|
|
6653
6989
|
`;
|
|
6654
|
-
const SmallPreviewContainer = styled.div `
|
|
6990
|
+
const SmallPreviewContainer$1 = styled.div `
|
|
6655
6991
|
cursor: ${({ onClick }) => (onClick ? "pointer" : "default")};
|
|
6656
6992
|
position: relative;
|
|
6657
6993
|
width: 100%;
|
|
@@ -6669,230 +7005,61 @@ const SmallPreviewContainer = styled.div `
|
|
|
6669
7005
|
transition: opacity ${uilibGl.transition.hover};
|
|
6670
7006
|
}
|
|
6671
7007
|
|
|
6672
|
-
&:hover {
|
|
6673
|
-
${SmallPreviewControl}, ${SmallPreviewCounter} {
|
|
6674
|
-
opacity: 1;
|
|
6675
|
-
}
|
|
6676
|
-
}
|
|
6677
|
-
|
|
6678
|
-
img {
|
|
6679
|
-
z-index: 0;
|
|
6680
|
-
cursor: pointer;
|
|
6681
|
-
position: absolute;
|
|
6682
|
-
top: 0;
|
|
6683
|
-
left: 0;
|
|
6684
|
-
width: 100%;
|
|
6685
|
-
height: 100%;
|
|
6686
|
-
min-height: inherit;
|
|
6687
|
-
object-position: center;
|
|
6688
|
-
object-fit: cover;
|
|
6689
|
-
|
|
6690
|
-
&:nth-child(${({ currentIndex }) => currentIndex}) {
|
|
6691
|
-
z-index: 1;
|
|
6692
|
-
}
|
|
6693
|
-
|
|
6694
|
-
${({ prevIndex, currentIndex }) => prevIndex !== currentIndex && imgSlideShowMixin}
|
|
6695
|
-
}
|
|
6696
|
-
`;
|
|
6697
|
-
const SmallPreviewImages = styled.div ``;
|
|
6698
|
-
|
|
6699
|
-
const SmallPreview = ({ images, totalCount, currentIndex, isLoading, setCurrentIndex, onClick, onNextPage }) => {
|
|
6700
|
-
const { t } = useGlobalContext();
|
|
6701
|
-
const [prevIndex, setPrevIndex] = react.useState(currentIndex + 1);
|
|
6702
|
-
const isPrevDisabled = currentIndex === 0;
|
|
6703
|
-
const total = totalCount || images?.length || 0;
|
|
6704
|
-
const isNextDisabled = currentIndex === total - 1;
|
|
6705
|
-
const prev = react.useCallback(() => {
|
|
6706
|
-
if (isPrevDisabled)
|
|
6707
|
-
return;
|
|
6708
|
-
setPrevIndex(currentIndex);
|
|
6709
|
-
setCurrentIndex(currentIndex - 1);
|
|
6710
|
-
}, [currentIndex, isPrevDisabled, setCurrentIndex]);
|
|
6711
|
-
const next = react.useCallback(() => {
|
|
6712
|
-
if (isNextDisabled)
|
|
6713
|
-
return;
|
|
6714
|
-
setPrevIndex(currentIndex);
|
|
6715
|
-
setCurrentIndex(currentIndex + 1);
|
|
6716
|
-
if (currentIndex === images.length) {
|
|
6717
|
-
onNextPage();
|
|
6718
|
-
}
|
|
6719
|
-
}, [currentIndex, images, isNextDisabled, onNextPage, setCurrentIndex]);
|
|
6720
|
-
return (jsxRuntime.jsxs(SmallPreviewContainer, { currentIndex: currentIndex + 1, prevIndex: prevIndex + 1, children: [isLoading && jsxRuntime.jsx(uilibGl.LinearProgress, {}), images.length > 1 && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(SmallPreviewLeft, { "$isDisabled": isPrevDisabled, onClick: prev }), jsxRuntime.jsx(SmallPreviewRight, { "$isDisabled": isNextDisabled, onClick: next }), jsxRuntime.jsx(SmallPreviewCounter, { children: jsxRuntime.jsxs("div", { children: [currentIndex + 1, " ", t("of", { ns: "dashboard" }), " ", total] }) })] })), jsxRuntime.jsx(SmallPreviewImages, { onClick: onClick, children: images.map(image => (jsxRuntime.jsx("img", { src: image.src, alt: "" }, image.src))) })] }));
|
|
6721
|
-
};
|
|
6722
|
-
|
|
6723
|
-
const ElementSlideshow = ({ elementConfig, type, renderElement }) => {
|
|
6724
|
-
const { expandedContainers, dataSources, attributes } = useWidgetContext(type);
|
|
6725
|
-
const [currentIndex, setCurrentIndex] = react.useState(0);
|
|
6726
|
-
const [isOpenGallery, toggleGallery] = useToggle();
|
|
6727
|
-
const { id, options, attributeName } = elementConfig || {};
|
|
6728
|
-
const { expandable, expanded, relatedDataSource } = options || {};
|
|
6729
|
-
const isVisible = isVisibleContainer(id, expandable, expanded, expandedContainers);
|
|
6730
|
-
const images = react.useMemo(() => {
|
|
6731
|
-
const dataSource = relatedDataSource ? dataSources?.find(({ name }) => name === relatedDataSource) : null;
|
|
6732
|
-
const array = dataSource
|
|
6733
|
-
? dataSource.features.map(feature => feature.attributes[attributeName])
|
|
6734
|
-
: getSlideshowImages({
|
|
6735
|
-
element: elementConfig,
|
|
6736
|
-
attribute: attributes.find(({ name }) => name === attributeName),
|
|
6737
|
-
});
|
|
6738
|
-
return (array?.map(image => ({
|
|
6739
|
-
src: image,
|
|
6740
|
-
fileName: image,
|
|
6741
|
-
})) || []);
|
|
6742
|
-
}, [attributeName, attributes, dataSources, elementConfig, relatedDataSource]);
|
|
6743
|
-
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsxs(SmallPreviewContainer$1, { children: [jsxRuntime.jsx(SmallPreview, { images: images, currentIndex: currentIndex, setCurrentIndex: setCurrentIndex, onClick: toggleGallery }), isOpenGallery && (jsxRuntime.jsx(uilibGl.Preview, { images: images,
|
|
6744
|
-
// currentIndex={currentIndex}
|
|
6745
|
-
// totalCount={images.length}
|
|
6746
|
-
isOpen: isOpenGallery, onClose: toggleGallery }))] }))] }));
|
|
6747
|
-
};
|
|
6748
|
-
|
|
6749
|
-
const ElementSvg = react.memo(({ type, elementConfig }) => {
|
|
6750
|
-
const { layerInfo, attributes } = useWidgetContext(type);
|
|
6751
|
-
const { options } = elementConfig || {};
|
|
6752
|
-
const { width, height, fontColor } = options || {};
|
|
6753
|
-
return (jsxRuntime.jsx(SvgImage, { url: getSvgUrl({ elementConfig, layerInfo, attributes }), width: width, height: height, fontColor: fontColor }));
|
|
6754
|
-
});
|
|
6755
|
-
|
|
6756
|
-
const StyledIconFontSizeMixin = styled.css `
|
|
6757
|
-
height: ${({ fontSize }) => `${fontSize}px`};
|
|
6758
|
-
|
|
6759
|
-
&&:after {
|
|
6760
|
-
font-size: ${({ fontSize }) => `${fontSize}px`};
|
|
6761
|
-
}
|
|
6762
|
-
`;
|
|
6763
|
-
const StyledIconFontColorMixin = styled.css `
|
|
6764
|
-
&&:after {
|
|
6765
|
-
color: ${({ fontColor }) => fontColor};
|
|
6766
|
-
}
|
|
6767
|
-
`;
|
|
6768
|
-
const StyledIcon = styled(uilibGl.Icon) `
|
|
6769
|
-
${({ fontSize }) => !!fontSize && StyledIconFontSizeMixin};
|
|
6770
|
-
${({ fontColor }) => !!fontColor && StyledIconFontColorMixin};
|
|
6771
|
-
`;
|
|
6772
|
-
|
|
6773
|
-
const ElementIcon = react.memo(({ type, elementConfig }) => {
|
|
6774
|
-
const { attributes } = useWidgetContext(type);
|
|
6775
|
-
const { value, attributeName, options } = elementConfig || {};
|
|
6776
|
-
const { fontSize, fontColor } = options || {};
|
|
6777
|
-
const iconValue = react.useMemo(() => (attributeName ? attributes.find(item => item.name === attributeName)?.value : value), [attributeName, attributes, value]);
|
|
6778
|
-
return jsxRuntime.jsx(StyledIcon, { kind: iconValue, fontSize: fontSize, fontColor: fontColor });
|
|
6779
|
-
});
|
|
6780
|
-
|
|
6781
|
-
const TooltipIcon = styled(uilibGl.Icon) `
|
|
6782
|
-
&&& {
|
|
6783
|
-
:after {
|
|
6784
|
-
font-size: 0.75rem;
|
|
6785
|
-
color: ${({ theme: { palette } }) => palette.iconDisabled};
|
|
6786
|
-
transition: color ${uilibGl.transition.hover};
|
|
6787
|
-
}
|
|
6788
|
-
|
|
6789
|
-
:hover:after {
|
|
6790
|
-
color: ${({ theme: { palette } }) => palette.icon};
|
|
6791
|
-
}
|
|
6792
|
-
}
|
|
6793
|
-
`;
|
|
6794
|
-
|
|
6795
|
-
const ElementTooltip = react.memo(({ type, elementConfig }) => {
|
|
6796
|
-
const { attributes } = useWidgetContext(type);
|
|
6797
|
-
const { attributeName, options } = elementConfig || {};
|
|
6798
|
-
const { icon } = options || {};
|
|
6799
|
-
const attribute = getAttributeByName(attributeName, attributes);
|
|
6800
|
-
const text = (attribute?.value || elementConfig?.value);
|
|
6801
|
-
return text ? (jsxRuntime.jsx(uilibGl.Tooltip, { placement: "top", arrow: true, content: text, children: ref => jsxRuntime.jsx(TooltipIcon, { kind: icon || "question", ref: ref }) })) : null;
|
|
6802
|
-
});
|
|
6803
|
-
|
|
6804
|
-
const ExternalLink = styled(uilibGl.IconButton).attrs(() => ({
|
|
6805
|
-
kind: "external_link",
|
|
6806
|
-
})) `
|
|
6807
|
-
${uilibGl.Icon} {
|
|
6808
|
-
color: ${({ theme: { palette } }) => palette.primary};
|
|
6809
|
-
}
|
|
6810
|
-
|
|
6811
|
-
&:hover ${uilibGl.Icon} {
|
|
6812
|
-
color: ${({ theme: { palette } }) => palette.primaryDeep};
|
|
6813
|
-
}
|
|
6814
|
-
`;
|
|
6815
|
-
const LocalLinkBlank = styled(uilibGl.Blank) `
|
|
6816
|
-
min-width: 13.5rem;
|
|
6817
|
-
padding: 0.5rem 0.75rem 0;
|
|
6818
|
-
|
|
6819
|
-
a {
|
|
6820
|
-
text-decoration: none;
|
|
6821
|
-
font-size: 0.75rem;
|
|
6822
|
-
color: ${({ theme: { palette } }) => palette.primary};
|
|
6823
|
-
}
|
|
6824
|
-
|
|
6825
|
-
${uilibGl.IconButtonButton} {
|
|
6826
|
-
font-size: 0.75rem;
|
|
7008
|
+
&:hover {
|
|
7009
|
+
${SmallPreviewControl}, ${SmallPreviewCounter} {
|
|
7010
|
+
opacity: 1;
|
|
7011
|
+
}
|
|
6827
7012
|
}
|
|
6828
|
-
`;
|
|
6829
|
-
const LocalLinkButton = styled(uilibGl.IconButton).attrs(() => ({
|
|
6830
|
-
kind: "link",
|
|
6831
|
-
})) `
|
|
6832
|
-
width: 1rem;
|
|
6833
|
-
height: 1rem;
|
|
6834
|
-
background-color: ${({ theme: { palette } }) => palette.primary};
|
|
6835
|
-
border-radius: 50%;
|
|
6836
7013
|
|
|
6837
|
-
|
|
6838
|
-
|
|
6839
|
-
|
|
6840
|
-
|
|
7014
|
+
img {
|
|
7015
|
+
z-index: 0;
|
|
7016
|
+
cursor: pointer;
|
|
7017
|
+
position: absolute;
|
|
7018
|
+
top: 0;
|
|
7019
|
+
left: 0;
|
|
7020
|
+
width: 100%;
|
|
7021
|
+
height: 100%;
|
|
7022
|
+
min-height: inherit;
|
|
7023
|
+
object-position: center;
|
|
7024
|
+
object-fit: cover;
|
|
6841
7025
|
|
|
6842
|
-
|
|
6843
|
-
|
|
6844
|
-
font-size: 0.6rem;
|
|
6845
|
-
color: white;
|
|
7026
|
+
&:nth-child(${({ currentIndex }) => currentIndex}) {
|
|
7027
|
+
z-index: 1;
|
|
6846
7028
|
}
|
|
6847
|
-
}
|
|
6848
|
-
`;
|
|
6849
|
-
const LocalLinkCopy = styled(uilibGl.Flex) `
|
|
6850
|
-
justify-content: center;
|
|
6851
|
-
`;
|
|
6852
|
-
|
|
6853
|
-
const LocalLink = react.memo(({ link }) => {
|
|
6854
|
-
const { t } = useGlobalContext();
|
|
6855
|
-
const [isOpen, toggleOpen] = useToggle();
|
|
6856
|
-
const onCopy = react.useCallback(() => {
|
|
6857
|
-
navigator.clipboard.writeText(link);
|
|
6858
|
-
toggleOpen();
|
|
6859
|
-
}, [link, toggleOpen]);
|
|
6860
|
-
return (jsxRuntime.jsx(uilibGl.Popover, { open: isOpen, zIndex: 10, onRequestClose: toggleOpen, anchorOrigin: "bottom-right", targetOrigin: "top-right", anchor: jsxRuntime.jsx(LocalLinkButton, { onClick: toggleOpen }), children: jsxRuntime.jsxs(LocalLinkBlank, { children: [jsxRuntime.jsx("a", { href: link, target: "_blank", rel: "noreferrer", children: link }), jsxRuntime.jsx(LocalLinkCopy, { children: jsxRuntime.jsx(uilibGl.IconButton, { kind: "copy", onClick: onCopy, children: t("copy", { ns: "dashboard" }) }) })] }) }));
|
|
6861
|
-
});
|
|
6862
|
-
|
|
6863
|
-
const ElementLink = react.memo(({ type, elementConfig }) => {
|
|
6864
|
-
const { attributes } = useWidgetContext(type);
|
|
6865
|
-
const attribute = getAttributeByName(elementConfig?.attributeName, attributes);
|
|
6866
|
-
const link = attribute?.value;
|
|
6867
|
-
if (!link || typeof link !== "string")
|
|
6868
|
-
return null;
|
|
6869
|
-
return link.startsWith("http") ? jsxRuntime.jsx(ExternalLink, { onClick: () => window.open(link) }) : jsxRuntime.jsx(LocalLink, { link: link });
|
|
6870
|
-
});
|
|
6871
|
-
|
|
6872
|
-
const ImageContainerButton = styled(uilibGl.FlatButton) `
|
|
6873
|
-
min-height: 1.5rem;
|
|
6874
|
-
border-radius: ${({ theme: { borderRadius } }) => borderRadius.large};
|
|
6875
|
-
background-color: ${({ theme: { palette } }) => palette.primary};
|
|
6876
|
-
text-transform: none;
|
|
6877
7029
|
|
|
6878
|
-
|
|
6879
|
-
background-color: ${({ theme: { palette } }) => palette.primaryDeep};
|
|
7030
|
+
${({ prevIndex, currentIndex }) => prevIndex !== currentIndex && imgSlideShowMixin}
|
|
6880
7031
|
}
|
|
6881
7032
|
`;
|
|
6882
|
-
|
|
6883
|
-
const ElementButton = react.memo(({ type, elementConfig }) => {
|
|
6884
|
-
const { attributes } = useWidgetContext(type);
|
|
6885
|
-
const attribute = getAttributeByName(elementConfig?.attributeName, attributes);
|
|
6886
|
-
const link = attribute?.value;
|
|
6887
|
-
if (!link || typeof link !== "string")
|
|
6888
|
-
return null;
|
|
6889
|
-
return (jsxRuntime.jsx(ImageContainerButton, { onClick: () => window.open(attribute?.value), children: elementConfig.value || "" }));
|
|
6890
|
-
});
|
|
7033
|
+
const SmallPreviewImages = styled.div ``;
|
|
6891
7034
|
|
|
6892
7035
|
const NoLiveSnapshot = () => {
|
|
6893
7036
|
return (jsxRuntime.jsxs(NoLiveSnapshotContainer, { children: [jsxRuntime.jsx(uilibGl.Icon, { kind: "alert" }), jsxRuntime.jsx(uilibGl.Description, { children: "\u0421\u043D\u0438\u043C\u043E\u043A \u043D\u0435 \u0434\u043E\u0441\u0442\u0443\u043F\u0435\u043D" })] }));
|
|
6894
7037
|
};
|
|
6895
7038
|
|
|
7039
|
+
const SmallPreview = ({ images, totalCount, currentIndex, isLoading, setCurrentIndex, onClick, onNextPage }) => {
|
|
7040
|
+
const { t } = useGlobalContext();
|
|
7041
|
+
const [prevIndex, setPrevIndex] = React.useState(currentIndex + 1);
|
|
7042
|
+
const isPrevDisabled = currentIndex === 0;
|
|
7043
|
+
const total = totalCount || images?.length || 0;
|
|
7044
|
+
const isNextDisabled = currentIndex === total - 1;
|
|
7045
|
+
const prev = React.useCallback(() => {
|
|
7046
|
+
if (isPrevDisabled)
|
|
7047
|
+
return;
|
|
7048
|
+
setPrevIndex(currentIndex);
|
|
7049
|
+
setCurrentIndex(currentIndex - 1);
|
|
7050
|
+
}, [currentIndex, isPrevDisabled, setCurrentIndex]);
|
|
7051
|
+
const next = React.useCallback(() => {
|
|
7052
|
+
if (isNextDisabled)
|
|
7053
|
+
return;
|
|
7054
|
+
setPrevIndex(currentIndex);
|
|
7055
|
+
setCurrentIndex(currentIndex + 1);
|
|
7056
|
+
if (currentIndex === images.length) {
|
|
7057
|
+
onNextPage();
|
|
7058
|
+
}
|
|
7059
|
+
}, [currentIndex, images, isNextDisabled, onNextPage, setCurrentIndex]);
|
|
7060
|
+
return (jsxRuntime.jsxs(SmallPreviewContainer$1, { currentIndex: currentIndex + 1, prevIndex: prevIndex + 1, children: [isLoading && jsxRuntime.jsx(uilibGl.LinearProgress, {}), images.length > 1 && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(SmallPreviewLeft, { "$isDisabled": isPrevDisabled, onClick: prev }), jsxRuntime.jsx(SmallPreviewRight, { "$isDisabled": isNextDisabled, onClick: next }), jsxRuntime.jsx(SmallPreviewCounter, { children: jsxRuntime.jsxs("div", { children: [currentIndex + 1, " ", t("of", { ns: "dashboard" }), " ", total] }) })] })), jsxRuntime.jsx(SmallPreviewImages, { onClick: onClick, children: images.map(image => (jsxRuntime.jsx("img", { src: image.src, alt: "" }, image.src))) })] }));
|
|
7061
|
+
};
|
|
7062
|
+
|
|
6896
7063
|
const DEFAULT_ARCHIVED_PERIOD = "#24h";
|
|
6897
7064
|
const SNAPSHOTS_PER_PAGE = 10;
|
|
6898
7065
|
const getDuration = (archivePeriod) => {
|
|
@@ -6913,20 +7080,20 @@ const getDuration = (archivePeriod) => {
|
|
|
6913
7080
|
};
|
|
6914
7081
|
const useCameraAttribute = (cameraId) => {
|
|
6915
7082
|
const { api } = useGlobalContext();
|
|
6916
|
-
const [currentIndex, setCurrentIndex] =
|
|
6917
|
-
const [currentPage, setCurrentPage] =
|
|
6918
|
-
const [timeline, setTimeline] =
|
|
6919
|
-
const [isLoadingSnapshot, setLoadingSnapshot] =
|
|
6920
|
-
const [isLoadingTimeline, setLoadingTimeline] =
|
|
7083
|
+
const [currentIndex, setCurrentIndex] = React.useState(0);
|
|
7084
|
+
const [currentPage, setCurrentPage] = React.useState(0);
|
|
7085
|
+
const [timeline, setTimeline] = React.useState([]);
|
|
7086
|
+
const [isLoadingSnapshot, setLoadingSnapshot] = React.useState(false);
|
|
7087
|
+
const [isLoadingTimeline, setLoadingTimeline] = React.useState(false);
|
|
6921
7088
|
const [isOpenGallery, toggleGallery] = useToggle();
|
|
6922
|
-
const [galleryImages, setGalleryImages] =
|
|
6923
|
-
const imagesRef =
|
|
7089
|
+
const [galleryImages, setGalleryImages] = React.useState([]);
|
|
7090
|
+
const imagesRef = React.useRef([]);
|
|
6924
7091
|
// Todo get archivePeriod from project configuration
|
|
6925
7092
|
const archivePeriod = /* appConfig?.settings?.cameraAttribute?.archivePeriod ||*/ DEFAULT_ARCHIVED_PERIOD;
|
|
6926
|
-
const onNextPage =
|
|
7093
|
+
const onNextPage = React.useCallback(() => {
|
|
6927
7094
|
setCurrentPage(currentPage + 1);
|
|
6928
7095
|
}, [currentPage]);
|
|
6929
|
-
|
|
7096
|
+
React.useEffect(() => {
|
|
6930
7097
|
(async () => {
|
|
6931
7098
|
if (!cameraId)
|
|
6932
7099
|
return;
|
|
@@ -6957,7 +7124,7 @@ const useCameraAttribute = (cameraId) => {
|
|
|
6957
7124
|
setTimeline(timelineResponse.timeline);
|
|
6958
7125
|
})();
|
|
6959
7126
|
}, [cameraId]);
|
|
6960
|
-
|
|
7127
|
+
React.useEffect(() => {
|
|
6961
7128
|
if (!timeline.length)
|
|
6962
7129
|
return;
|
|
6963
7130
|
const timelinePage = timeline.slice(currentPage * SNAPSHOTS_PER_PAGE, (currentPage + 1) * SNAPSHOTS_PER_PAGE);
|
|
@@ -7023,44 +7190,421 @@ const ElementCamera = ({ type, renderElement, elementConfig, field }) => {
|
|
|
7023
7190
|
onClose: toggleGallery }))] }))] }));
|
|
7024
7191
|
};
|
|
7025
7192
|
|
|
7026
|
-
const ElementChart =
|
|
7027
|
-
const { config } = useWidgetConfig(type);
|
|
7028
|
-
return (jsxRuntime.jsx(Chart, { type: type, config: config, elementConfig: elementConfig, element: elementConfig, renderElement: renderElement }));
|
|
7029
|
-
});
|
|
7030
|
-
|
|
7031
|
-
const
|
|
7032
|
-
const { attributes } = useWidgetContext(type);
|
|
7193
|
+
const ElementChart = React.memo(({ type, elementConfig, renderElement }) => {
|
|
7194
|
+
const { config } = useWidgetConfig(type);
|
|
7195
|
+
return (jsxRuntime.jsx(Chart, { type: type, config: config, elementConfig: elementConfig, element: elementConfig, renderElement: renderElement }));
|
|
7196
|
+
});
|
|
7197
|
+
|
|
7198
|
+
const ElementChips = React.memo(({ type, elementConfig }) => {
|
|
7199
|
+
const { attributes } = useWidgetContext(type);
|
|
7200
|
+
const { attributeName, options, style } = elementConfig || {};
|
|
7201
|
+
const { separator, bgColor, fontColor, fontSize } = options || {};
|
|
7202
|
+
const attribute = getAttributeByName(attributeName, attributes);
|
|
7203
|
+
const tags = attribute?.value?.split(separator || ",");
|
|
7204
|
+
return (jsxRuntime.jsx(DashboardChipsContainer, { style: style, children: tags?.map(tag => (jsxRuntime.jsx(DashboardChip$1, { text: tag, "$bgColor": bgColor, "$fontColor": fontColor, "$fontSize": fontSize, "$isDefault": true }, tag))) }));
|
|
7205
|
+
});
|
|
7206
|
+
|
|
7207
|
+
const StyledIconFontSizeMixin = styled.css `
|
|
7208
|
+
height: ${({ fontSize }) => `${fontSize}px`};
|
|
7209
|
+
|
|
7210
|
+
&&:after {
|
|
7211
|
+
font-size: ${({ fontSize }) => `${fontSize}px`};
|
|
7212
|
+
}
|
|
7213
|
+
`;
|
|
7214
|
+
const StyledIconFontColorMixin = styled.css `
|
|
7215
|
+
&&:after {
|
|
7216
|
+
color: ${({ fontColor }) => fontColor};
|
|
7217
|
+
}
|
|
7218
|
+
`;
|
|
7219
|
+
const StyledIcon = styled(uilibGl.Icon) `
|
|
7220
|
+
${({ fontSize }) => !!fontSize && StyledIconFontSizeMixin};
|
|
7221
|
+
${({ fontColor }) => !!fontColor && StyledIconFontColorMixin};
|
|
7222
|
+
`;
|
|
7223
|
+
|
|
7224
|
+
const ElementIcon = React.memo(({ type, elementConfig }) => {
|
|
7225
|
+
const { attributes } = useWidgetContext(type);
|
|
7226
|
+
const { value, attributeName, options } = elementConfig || {};
|
|
7227
|
+
const { fontSize, fontColor } = options || {};
|
|
7228
|
+
const iconValue = React.useMemo(() => (attributeName ? attributes?.find(item => item.name === attributeName)?.value : value), [attributeName, attributes, value]);
|
|
7229
|
+
return jsxRuntime.jsx(StyledIcon, { kind: iconValue, fontSize: fontSize, fontColor: fontColor });
|
|
7230
|
+
});
|
|
7231
|
+
|
|
7232
|
+
const ElementImage = React.memo(({ type, elementConfig }) => {
|
|
7233
|
+
const { attributes } = useWidgetContext(type);
|
|
7234
|
+
const { value, attributeName, options } = elementConfig || {};
|
|
7235
|
+
const { width } = options || {};
|
|
7236
|
+
const firstImage = React.useMemo(() => {
|
|
7237
|
+
if (value) {
|
|
7238
|
+
return value.toString();
|
|
7239
|
+
}
|
|
7240
|
+
if (!attributeName || Array.isArray(attributeName)) {
|
|
7241
|
+
return null;
|
|
7242
|
+
}
|
|
7243
|
+
const attribute = attributes?.find(item => item.name === attributeName);
|
|
7244
|
+
return attribute?.value?.split(";")?.[0];
|
|
7245
|
+
}, [attributeName, attributes, value]);
|
|
7246
|
+
return firstImage ? jsxRuntime.jsx("img", { src: firstImage, alt: firstImage, width: width }) : null;
|
|
7247
|
+
});
|
|
7248
|
+
|
|
7249
|
+
const ElementLegend = React.memo(({ type, element, elementConfig, expandedContainers }) => {
|
|
7250
|
+
const { attributes } = useWidgetContext(type);
|
|
7251
|
+
const { options } = elementConfig || {};
|
|
7252
|
+
const { twoColumns, chartId, relatedDataSources } = options || {};
|
|
7253
|
+
const chartElement = React.useMemo(() => findAnd.returnFound(element?.children, { id: chartId }), [chartId, element?.children]);
|
|
7254
|
+
const { data, loading } = useChartData({
|
|
7255
|
+
element: chartElement,
|
|
7256
|
+
type,
|
|
7257
|
+
});
|
|
7258
|
+
const legendData = React.useMemo(() => {
|
|
7259
|
+
if (!data[0]?.items?.length)
|
|
7260
|
+
return [];
|
|
7261
|
+
const relatedAttributes = relatedDataSources || [];
|
|
7262
|
+
const isRelated = !!relatedAttributes?.length;
|
|
7263
|
+
return isRelated
|
|
7264
|
+
? data[0].items
|
|
7265
|
+
: data[0].items.map(item => {
|
|
7266
|
+
const attribute = attributes?.find(({ name }) => name === item.name);
|
|
7267
|
+
return { ...item, name: attribute?.alias || item.name };
|
|
7268
|
+
});
|
|
7269
|
+
}, [attributes, data, relatedDataSources]);
|
|
7270
|
+
return !chartElement?.options?.expanded || expandedContainers?.[chartElement.id] ? (jsxRuntime.jsx(ChartLegend, { data: legendData, loading: loading, chartElement: chartElement, twoColumns: twoColumns, type: type })) : null;
|
|
7271
|
+
});
|
|
7272
|
+
|
|
7273
|
+
const ExternalLink = styled(uilibGl.IconButton).attrs(() => ({
|
|
7274
|
+
kind: "external_link",
|
|
7275
|
+
})) `
|
|
7276
|
+
${uilibGl.Icon} {
|
|
7277
|
+
color: ${({ theme: { palette } }) => palette.primary};
|
|
7278
|
+
}
|
|
7279
|
+
|
|
7280
|
+
&:hover ${uilibGl.Icon} {
|
|
7281
|
+
color: ${({ theme: { palette } }) => palette.primaryDeep};
|
|
7282
|
+
}
|
|
7283
|
+
`;
|
|
7284
|
+
const LocalLinkBlank = styled(uilibGl.Blank) `
|
|
7285
|
+
min-width: 13.5rem;
|
|
7286
|
+
padding: 0.5rem 0.75rem 0;
|
|
7287
|
+
|
|
7288
|
+
a {
|
|
7289
|
+
text-decoration: none;
|
|
7290
|
+
font-size: 0.75rem;
|
|
7291
|
+
color: ${({ theme: { palette } }) => palette.primary};
|
|
7292
|
+
}
|
|
7293
|
+
|
|
7294
|
+
${uilibGl.IconButtonButton} {
|
|
7295
|
+
font-size: 0.75rem;
|
|
7296
|
+
}
|
|
7297
|
+
`;
|
|
7298
|
+
const LocalLinkButton = styled(uilibGl.IconButton).attrs(() => ({
|
|
7299
|
+
kind: "link",
|
|
7300
|
+
})) `
|
|
7301
|
+
width: 1rem;
|
|
7302
|
+
height: 1rem;
|
|
7303
|
+
background-color: ${({ theme: { palette } }) => palette.primary};
|
|
7304
|
+
border-radius: 50%;
|
|
7305
|
+
|
|
7306
|
+
span[kind] {
|
|
7307
|
+
display: flex;
|
|
7308
|
+
justify-content: center;
|
|
7309
|
+
align-items: center;
|
|
7310
|
+
|
|
7311
|
+
:after {
|
|
7312
|
+
position: relative;
|
|
7313
|
+
font-size: 0.6rem;
|
|
7314
|
+
color: white;
|
|
7315
|
+
}
|
|
7316
|
+
}
|
|
7317
|
+
`;
|
|
7318
|
+
const LocalLinkCopy = styled(uilibGl.Flex) `
|
|
7319
|
+
justify-content: center;
|
|
7320
|
+
`;
|
|
7321
|
+
|
|
7322
|
+
const LocalLink = React.memo(({ link }) => {
|
|
7323
|
+
const { t } = useGlobalContext();
|
|
7324
|
+
const [isOpen, toggleOpen] = useToggle();
|
|
7325
|
+
const onCopy = React.useCallback(() => {
|
|
7326
|
+
navigator.clipboard.writeText(link);
|
|
7327
|
+
toggleOpen();
|
|
7328
|
+
}, [link, toggleOpen]);
|
|
7329
|
+
return (jsxRuntime.jsx(uilibGl.Popover, { open: isOpen, zIndex: 10, onRequestClose: toggleOpen, anchorOrigin: "bottom-right", targetOrigin: "top-right", anchor: jsxRuntime.jsx(LocalLinkButton, { onClick: toggleOpen }), children: jsxRuntime.jsxs(LocalLinkBlank, { children: [jsxRuntime.jsx("a", { href: link, target: "_blank", rel: "noreferrer", children: link }), jsxRuntime.jsx(LocalLinkCopy, { children: jsxRuntime.jsx(uilibGl.IconButton, { kind: "copy", onClick: onCopy, children: t("copy", { ns: "dashboard" }) }) })] }) }));
|
|
7330
|
+
});
|
|
7331
|
+
|
|
7332
|
+
const ElementLink = React.memo(({ type, elementConfig }) => {
|
|
7333
|
+
const { attributes } = useWidgetContext(type);
|
|
7334
|
+
const attribute = getAttributeByName(elementConfig?.attributeName, attributes);
|
|
7335
|
+
const link = attribute?.value;
|
|
7336
|
+
if (!link || typeof link !== "string")
|
|
7337
|
+
return null;
|
|
7338
|
+
return link.startsWith("http") ? jsxRuntime.jsx(ExternalLink, { onClick: () => window.open(link) }) : jsxRuntime.jsx(LocalLink, { link: link });
|
|
7339
|
+
});
|
|
7340
|
+
|
|
7341
|
+
const SmallPreviewContainer = styled.div `
|
|
7342
|
+
width: 100%;
|
|
7343
|
+
height: 100%;
|
|
7344
|
+
`;
|
|
7345
|
+
|
|
7346
|
+
const ElementSlideshow = ({ elementConfig, type, renderElement }) => {
|
|
7347
|
+
const { expandedContainers, dataSources, attributes } = useWidgetContext(type);
|
|
7348
|
+
const [currentIndex, setCurrentIndex] = React.useState(0);
|
|
7349
|
+
const [isOpenGallery, toggleGallery] = useToggle();
|
|
7350
|
+
const { id, options, attributeName } = elementConfig || {};
|
|
7351
|
+
const { expandable, expanded, relatedDataSource } = options || {};
|
|
7352
|
+
const isVisible = isVisibleContainer(id, expandable, expanded, expandedContainers);
|
|
7353
|
+
const images = React.useMemo(() => {
|
|
7354
|
+
const dataSource = relatedDataSource ? dataSources?.find(({ name }) => name === relatedDataSource) : null;
|
|
7355
|
+
const array = dataSource
|
|
7356
|
+
? dataSource.features.map(feature => feature.attributes[attributeName])
|
|
7357
|
+
: getSlideshowImages({
|
|
7358
|
+
element: elementConfig,
|
|
7359
|
+
attribute: attributes?.find(({ name }) => name === attributeName),
|
|
7360
|
+
});
|
|
7361
|
+
return (array?.map(image => ({
|
|
7362
|
+
src: image,
|
|
7363
|
+
fileName: image,
|
|
7364
|
+
})) || []);
|
|
7365
|
+
}, [attributeName, attributes, dataSources, elementConfig, relatedDataSource]);
|
|
7366
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsxs(SmallPreviewContainer, { children: [jsxRuntime.jsx(SmallPreview, { images: images, currentIndex: currentIndex, setCurrentIndex: setCurrentIndex, onClick: toggleGallery }), isOpenGallery && (jsxRuntime.jsx(uilibGl.Preview, { images: images,
|
|
7367
|
+
// currentIndex={currentIndex}
|
|
7368
|
+
// totalCount={images.length}
|
|
7369
|
+
isOpen: isOpenGallery, onClose: toggleGallery }))] }))] }));
|
|
7370
|
+
};
|
|
7371
|
+
|
|
7372
|
+
const ElementSvg = React.memo(({ type, elementConfig }) => {
|
|
7373
|
+
const { layerInfo, attributes } = useWidgetContext(type);
|
|
7033
7374
|
const { options } = elementConfig || {};
|
|
7034
|
-
const {
|
|
7035
|
-
|
|
7036
|
-
const { data, loading } = useChartData({
|
|
7037
|
-
element: chartElement,
|
|
7038
|
-
type,
|
|
7039
|
-
});
|
|
7040
|
-
const legendData = react.useMemo(() => {
|
|
7041
|
-
if (!data[0]?.items?.length)
|
|
7042
|
-
return [];
|
|
7043
|
-
const relatedAttributes = relatedDataSources || [];
|
|
7044
|
-
const isRelated = !!relatedAttributes?.length;
|
|
7045
|
-
return isRelated
|
|
7046
|
-
? data[0].items
|
|
7047
|
-
: data[0].items.map(item => {
|
|
7048
|
-
const attribute = attributes?.find(({ name }) => name === item.name);
|
|
7049
|
-
return { ...item, name: attribute?.alias || item.name };
|
|
7050
|
-
});
|
|
7051
|
-
}, [attributes, data, relatedDataSources]);
|
|
7052
|
-
return !chartElement?.options?.expanded || expandedContainers?.[chartElement.id] ? (jsxRuntime.jsx(ChartLegend, { data: legendData, loading: loading, chartElement: chartElement, twoColumns: twoColumns, type: type })) : null;
|
|
7375
|
+
const { width, height, fontColor } = options || {};
|
|
7376
|
+
return (jsxRuntime.jsx(SvgImage, { url: getSvgUrl({ elementConfig, layerInfo, attributes }), width: width, height: height, fontColor: fontColor }));
|
|
7053
7377
|
});
|
|
7054
7378
|
|
|
7055
|
-
const
|
|
7379
|
+
const TooltipIcon = styled(uilibGl.Icon) `
|
|
7380
|
+
&&& {
|
|
7381
|
+
:after {
|
|
7382
|
+
font-size: 0.75rem;
|
|
7383
|
+
color: ${({ theme: { palette } }) => palette.iconDisabled};
|
|
7384
|
+
transition: color ${uilibGl.transition.hover};
|
|
7385
|
+
}
|
|
7386
|
+
|
|
7387
|
+
:hover:after {
|
|
7388
|
+
color: ${({ theme: { palette } }) => palette.icon};
|
|
7389
|
+
}
|
|
7390
|
+
}
|
|
7391
|
+
`;
|
|
7392
|
+
|
|
7393
|
+
const ElementTooltip = React.memo(({ type, elementConfig }) => {
|
|
7056
7394
|
const { attributes } = useWidgetContext(type);
|
|
7057
|
-
const { attributeName, options
|
|
7058
|
-
const {
|
|
7395
|
+
const { attributeName, options } = elementConfig || {};
|
|
7396
|
+
const { icon } = options || {};
|
|
7059
7397
|
const attribute = getAttributeByName(attributeName, attributes);
|
|
7060
|
-
const
|
|
7061
|
-
return (jsxRuntime.jsx(
|
|
7398
|
+
const text = (attribute?.value || elementConfig?.value);
|
|
7399
|
+
return text ? (jsxRuntime.jsx(uilibGl.Tooltip, { placement: "top", arrow: true, content: text, children: ref => jsxRuntime.jsx(TooltipIcon, { kind: icon || "question", ref: ref }) })) : null;
|
|
7062
7400
|
});
|
|
7063
7401
|
|
|
7402
|
+
const SlideshowHeaderWrapper = styled.div `
|
|
7403
|
+
padding: ${({ withPadding }) => (withPadding ? "0.5rem 0.5rem 0" : 0)};
|
|
7404
|
+
|
|
7405
|
+
${Header} {
|
|
7406
|
+
align-items: flex-start;
|
|
7407
|
+
width: calc(100% + 2rem);
|
|
7408
|
+
height: ${({ big }) => (big ? "15.5rem" : "auto")};
|
|
7409
|
+
padding: 1.5rem;
|
|
7410
|
+
margin: -1rem -1rem 0 -1rem;
|
|
7411
|
+
border-radius: ${({ theme: { borderRadius } }) => borderRadius.medium};
|
|
7412
|
+
|
|
7413
|
+
${SmallPreviewCounter} {
|
|
7414
|
+
bottom: ${({ withPadding }) => (withPadding ? 0.625 : 1.125)}rem;
|
|
7415
|
+
}
|
|
7416
|
+
|
|
7417
|
+
:before,
|
|
7418
|
+
:after {
|
|
7419
|
+
content: "";
|
|
7420
|
+
z-index: 2;
|
|
7421
|
+
position: absolute;
|
|
7422
|
+
top: 0;
|
|
7423
|
+
left: 0;
|
|
7424
|
+
width: 100%;
|
|
7425
|
+
}
|
|
7426
|
+
|
|
7427
|
+
:before {
|
|
7428
|
+
height: 100%;
|
|
7429
|
+
background: rgba(32, 46, 53, 0.25);
|
|
7430
|
+
}
|
|
7431
|
+
|
|
7432
|
+
:after {
|
|
7433
|
+
height: 4.5rem;
|
|
7434
|
+
background: linear-gradient(180deg, #000000 0%, rgba(0, 0, 0, 0) 100%);
|
|
7435
|
+
}
|
|
7436
|
+
|
|
7437
|
+
:hover {
|
|
7438
|
+
${SmallPreviewControl}, ${SmallPreviewCounter} {
|
|
7439
|
+
opacity: 1;
|
|
7440
|
+
}
|
|
7441
|
+
}
|
|
7442
|
+
}
|
|
7443
|
+
`;
|
|
7444
|
+
const ImageContainerBg = styled.div `
|
|
7445
|
+
position: absolute;
|
|
7446
|
+
top: 0;
|
|
7447
|
+
bottom: 0;
|
|
7448
|
+
left: 0;
|
|
7449
|
+
right: 0;
|
|
7450
|
+
|
|
7451
|
+
img {
|
|
7452
|
+
width: 100%;
|
|
7453
|
+
height: 100%;
|
|
7454
|
+
object-position: center;
|
|
7455
|
+
object-fit: cover;
|
|
7456
|
+
}
|
|
7457
|
+
`;
|
|
7458
|
+
const HeaderSlideshow = styled.div `
|
|
7459
|
+
position: absolute;
|
|
7460
|
+
top: 0;
|
|
7461
|
+
bottom: ${({ height }) => (height ? `${height}px` : 0)};
|
|
7462
|
+
left: 0;
|
|
7463
|
+
right: 0;
|
|
7464
|
+
|
|
7465
|
+
img {
|
|
7466
|
+
width: 100%;
|
|
7467
|
+
height: 100%;
|
|
7468
|
+
min-height: inherit;
|
|
7469
|
+
object-position: center;
|
|
7470
|
+
object-fit: cover;
|
|
7471
|
+
}
|
|
7472
|
+
`;
|
|
7473
|
+
|
|
7474
|
+
const FeatureCardSlideshowHeader = ({ isRow }) => {
|
|
7475
|
+
const { layerInfo } = useWidgetContext(exports.WidgetType.FeatureCard);
|
|
7476
|
+
const { config } = useWidgetConfig(exports.WidgetType.FeatureCard);
|
|
7477
|
+
const { header, options } = config || {};
|
|
7478
|
+
const renderElement = useHeaderRender(header);
|
|
7479
|
+
return (jsxRuntime.jsx(SlideshowHeaderWrapper, { big: true, withPadding: options?.withPadding, children: jsxRuntime.jsx(uilibGl.ThemeProvider, { theme: uilibGl.darkTheme, children: jsxRuntime.jsxs(Header, { "$isRow": isRow, children: [jsxRuntime.jsxs(HeaderFrontView, { children: [jsxRuntime.jsxs(HeaderContainer, { children: [jsxRuntime.jsx(LayerIcon, { layerInfo: layerInfo }), jsxRuntime.jsx(FeatureCardTitle, { title: renderElement({
|
|
7480
|
+
id: "title",
|
|
7481
|
+
wrap: false,
|
|
7482
|
+
}), description: renderElement({
|
|
7483
|
+
id: "description",
|
|
7484
|
+
wrap: false,
|
|
7485
|
+
}) })] }), jsxRuntime.jsx(FeatureCardButtons, {})] }), jsxRuntime.jsx(ImageContainerBg, { children: renderElement({
|
|
7486
|
+
id: "bgImage",
|
|
7487
|
+
wrap: false,
|
|
7488
|
+
}) }), jsxRuntime.jsx(HeaderSlideshow, { height: options?.height, children: renderElement({
|
|
7489
|
+
id: "slideshow",
|
|
7490
|
+
wrap: false,
|
|
7491
|
+
}) })] }) }) }));
|
|
7492
|
+
};
|
|
7493
|
+
|
|
7494
|
+
const getDashboardHeader = (templateName) => {
|
|
7495
|
+
switch (templateName) {
|
|
7496
|
+
case exports.HeaderTemplate.Default:
|
|
7497
|
+
default:
|
|
7498
|
+
return DashboardDefaultHeader;
|
|
7499
|
+
}
|
|
7500
|
+
};
|
|
7501
|
+
|
|
7502
|
+
const getDataFromAttributes = (t, config, attributes) => {
|
|
7503
|
+
const colors = config?.options?.colors || FEATURE_CARD_DEFAULT_COLORS;
|
|
7504
|
+
const data = config?.children?.map(({ attributeName }, index) => {
|
|
7505
|
+
const attribute = attributes?.find(({ name }) => name === attributeName);
|
|
7506
|
+
return {
|
|
7507
|
+
name: attribute?.name || "",
|
|
7508
|
+
value: attribute ? Number(attribute.value) : 0,
|
|
7509
|
+
color: colors[index] || FEATURE_CARD_OTHER_COLOR
|
|
7510
|
+
};
|
|
7511
|
+
});
|
|
7512
|
+
if (config?.options?.orderByValue) {
|
|
7513
|
+
data.sort((a, b) => b.value - a.value);
|
|
7514
|
+
}
|
|
7515
|
+
const isOtherSliced = config?.options?.otherItems && config.options.otherItems < data.length;
|
|
7516
|
+
if (!isOtherSliced)
|
|
7517
|
+
return data;
|
|
7518
|
+
const otherValue = data
|
|
7519
|
+
.slice(0, config?.options?.otherItems)
|
|
7520
|
+
.reduce((prev, { value }) => prev + value, 0);
|
|
7521
|
+
return [
|
|
7522
|
+
...data?.slice(0, config.options?.otherItems),
|
|
7523
|
+
{
|
|
7524
|
+
name: t("other", { ns: "dashboard" }),
|
|
7525
|
+
color: FEATURE_CARD_OTHER_COLOR,
|
|
7526
|
+
value: Number(otherValue)
|
|
7527
|
+
}
|
|
7528
|
+
];
|
|
7529
|
+
};
|
|
7530
|
+
|
|
7531
|
+
const getDataFromRelatedFeatures = ({ t, config, filters, relatedConfig, dataSource, layerInfo }) => {
|
|
7532
|
+
if (!dataSource || !dataSource?.features?.length) {
|
|
7533
|
+
return [];
|
|
7534
|
+
}
|
|
7535
|
+
const { colors } = config.options;
|
|
7536
|
+
const layerDefinition = getLayerDefinition(layerInfo);
|
|
7537
|
+
let data = JSON.parse(JSON.stringify(dataSource?.features));
|
|
7538
|
+
const sortAttribute = config?.options?.orderByValue
|
|
7539
|
+
? relatedConfig.attributeName
|
|
7540
|
+
: config?.options?.orderByTitle
|
|
7541
|
+
? relatedConfig.attributeTitle
|
|
7542
|
+
: null;
|
|
7543
|
+
if (sortAttribute) {
|
|
7544
|
+
data.sort((a, b) => b.attributes[sortAttribute] - a.attributes[sortAttribute]);
|
|
7545
|
+
}
|
|
7546
|
+
const isOtherSliced = config?.options?.otherItems && config.options.otherItems < data.length;
|
|
7547
|
+
const otherValue = isOtherSliced
|
|
7548
|
+
? data
|
|
7549
|
+
.slice(config.options.otherItems)
|
|
7550
|
+
.reduce((prev, { attributes }) => prev + attributes[relatedConfig.attributeName], 0)
|
|
7551
|
+
: null;
|
|
7552
|
+
if (isOtherSliced) {
|
|
7553
|
+
data = data.slice(0, config?.options?.otherItems);
|
|
7554
|
+
}
|
|
7555
|
+
const gradientArray = relatedConfig.chartAxis && colors?.length < data.length
|
|
7556
|
+
? new Gradient()
|
|
7557
|
+
.setColorGradient(colors[0], colors[colors.length - 1])
|
|
7558
|
+
.setMidpoint(data.length)
|
|
7559
|
+
.getColors()
|
|
7560
|
+
: colors;
|
|
7561
|
+
const filter = getConfigFilter(relatedConfig?.filterName, filters);
|
|
7562
|
+
const result = data.reduce((acc, feature, index) => {
|
|
7563
|
+
if (relatedConfig?.filterName && !filter) {
|
|
7564
|
+
return acc;
|
|
7565
|
+
}
|
|
7566
|
+
const attributeName = feature.attributes[relatedConfig.attributeName];
|
|
7567
|
+
const attributeTitle = feature.attributes[relatedConfig.attributeTitle];
|
|
7568
|
+
const attributeColor = feature.attributes[relatedConfig.attributeColor];
|
|
7569
|
+
return [
|
|
7570
|
+
...acc,
|
|
7571
|
+
{
|
|
7572
|
+
name: formatAttributeValue({
|
|
7573
|
+
t,
|
|
7574
|
+
type: layerDefinition.attributes[relatedConfig.attributeTitle]?.type,
|
|
7575
|
+
value: attributeTitle,
|
|
7576
|
+
stringFormat: layerDefinition.attributes[relatedConfig.attributeTitle]?.stringFormat
|
|
7577
|
+
}),
|
|
7578
|
+
value: attributeName === null ? null : Number(attributeName),
|
|
7579
|
+
color: attributeColor || gradientArray?.[index] || FEATURE_CARD_OTHER_COLOR,
|
|
7580
|
+
min: filter?.attributeMin ? feature.attributes[filter.attributeMin] : null,
|
|
7581
|
+
max: filter?.attributeMin ? feature.attributes[filter.attributeMax] : null
|
|
7582
|
+
}
|
|
7583
|
+
];
|
|
7584
|
+
}, []);
|
|
7585
|
+
if (isOtherSliced) {
|
|
7586
|
+
result.push({
|
|
7587
|
+
name: t("other", { ns: "dashboard" }),
|
|
7588
|
+
color: FEATURE_CARD_OTHER_COLOR,
|
|
7589
|
+
value: Number(otherValue)
|
|
7590
|
+
});
|
|
7591
|
+
}
|
|
7592
|
+
return result;
|
|
7593
|
+
};
|
|
7594
|
+
|
|
7595
|
+
const getDefaultConfig = ({ title, defaultTitle, items, baseMapName, position, resolution, srid, }) => {
|
|
7596
|
+
const dashboardConfiguration = JSON.parse(JSON.stringify(DEFAULT_DASHBOARD_CONFIG));
|
|
7597
|
+
const defaultPages = JSON.parse(JSON.stringify(DEFAULT_PAGES_CONFIG));
|
|
7598
|
+
const defaultPage = createConfigPage({ title, baseMapName, position, resolution, defaultTitle });
|
|
7599
|
+
if (items?.length) {
|
|
7600
|
+
const contentItems = items.map(item => createConfigLayer(item.name));
|
|
7601
|
+
defaultPage.layers.push(...contentItems);
|
|
7602
|
+
}
|
|
7603
|
+
defaultPages.children.push(defaultPage);
|
|
7604
|
+
dashboardConfiguration.children.push(defaultPages);
|
|
7605
|
+
return dashboardConfiguration;
|
|
7606
|
+
};
|
|
7607
|
+
|
|
7064
7608
|
const elementComponents = {
|
|
7065
7609
|
image: ElementImage,
|
|
7066
7610
|
slideshow: ElementSlideshow,
|
|
@@ -7152,6 +7696,20 @@ function getFeatureAttributes(feature = {}, layer, dataSource) {
|
|
|
7152
7696
|
});
|
|
7153
7697
|
}
|
|
7154
7698
|
|
|
7699
|
+
const getFeatureCardHeader = (templateName) => {
|
|
7700
|
+
switch (templateName) {
|
|
7701
|
+
case exports.HeaderTemplate.Slideshow:
|
|
7702
|
+
return FeatureCardSlideshowHeader;
|
|
7703
|
+
case exports.HeaderTemplate.Gradient:
|
|
7704
|
+
return FeatureCardGradientHeader;
|
|
7705
|
+
case exports.HeaderTemplate.Icon:
|
|
7706
|
+
return FeatureCardIconHeader;
|
|
7707
|
+
case exports.HeaderTemplate.Default:
|
|
7708
|
+
default:
|
|
7709
|
+
return FeatureCardDefaultHeader;
|
|
7710
|
+
}
|
|
7711
|
+
};
|
|
7712
|
+
|
|
7155
7713
|
const RangeNumberFilter = ({ type, filter }) => {
|
|
7156
7714
|
const { t } = useGlobalContext();
|
|
7157
7715
|
const { filters, changeFilters } = useWidgetContext(type);
|
|
@@ -7160,8 +7718,8 @@ const RangeNumberFilter = ({ type, filter }) => {
|
|
|
7160
7718
|
const { filters: configFilters } = currentPage;
|
|
7161
7719
|
const { filterName, width, step, label, minValue = RANGE_MIN_VALUE, maxValue = RANGE_MAX_VALUE } = filter.options;
|
|
7162
7720
|
const filterValue = [filters[filterName]?.min || minValue, filters[filterName]?.max || maxValue];
|
|
7163
|
-
const [value, setValue] =
|
|
7164
|
-
|
|
7721
|
+
const [value, setValue] = React.useState(filterValue);
|
|
7722
|
+
React.useEffect(() => {
|
|
7165
7723
|
updateDebounce(() => {
|
|
7166
7724
|
changeFilters({
|
|
7167
7725
|
[filterName]: {
|
|
@@ -7180,8 +7738,8 @@ const RangeNumberFilter = ({ type, filter }) => {
|
|
|
7180
7738
|
|
|
7181
7739
|
const TextFilter = ({ type, filter, config }) => {
|
|
7182
7740
|
const { filters, changeFilters, dataSources } = useWidgetContext(type);
|
|
7183
|
-
const suggestRef =
|
|
7184
|
-
const [totalCount, setTotalCount] =
|
|
7741
|
+
const suggestRef = React.useRef(null);
|
|
7742
|
+
const [totalCount, setTotalCount] = React.useState(0);
|
|
7185
7743
|
const { attributes, layerInfo } = useRelatedDataSourceAttributes({
|
|
7186
7744
|
type,
|
|
7187
7745
|
elementConfig: filter,
|
|
@@ -7191,10 +7749,10 @@ const TextFilter = ({ type, filter, config }) => {
|
|
|
7191
7749
|
const { filterName, searchFilterName, placeholder, width, height, multiSelect, variants } = filter.options;
|
|
7192
7750
|
const { eqlParameters } = (layerInfo?.configuration || {});
|
|
7193
7751
|
const layerParams = useLayerParams(layerInfo);
|
|
7194
|
-
const [value, setValue] =
|
|
7195
|
-
const configFilter =
|
|
7196
|
-
const searchFilter =
|
|
7197
|
-
const searchDataSource =
|
|
7752
|
+
const [value, setValue] = React.useState("");
|
|
7753
|
+
const configFilter = React.useMemo(() => getConfigFilter(filterName, configFilters), [configFilters, filterName]);
|
|
7754
|
+
const searchFilter = React.useMemo(() => getConfigFilter(searchFilterName, configFilters), [configFilters, searchFilterName]);
|
|
7755
|
+
const searchDataSource = React.useMemo(() => !!searchFilter?.relatedDataSource &&
|
|
7198
7756
|
configDataSources.find(({ name }) => name === searchFilter.relatedDataSource), [configDataSources, searchFilter?.relatedDataSource]);
|
|
7199
7757
|
const updateDataSource = useUpdateDataSource({
|
|
7200
7758
|
dataSource: searchDataSource,
|
|
@@ -7204,15 +7762,15 @@ const TextFilter = ({ type, filter, config }) => {
|
|
|
7204
7762
|
layerParams,
|
|
7205
7763
|
eqlParameters,
|
|
7206
7764
|
});
|
|
7207
|
-
const [options, setOptions] =
|
|
7208
|
-
const setFilterValue =
|
|
7765
|
+
const [options, setOptions] = React.useState([]);
|
|
7766
|
+
const setFilterValue = React.useCallback(newValue => {
|
|
7209
7767
|
changeFilters({
|
|
7210
7768
|
[filterName]: {
|
|
7211
7769
|
value: newValue,
|
|
7212
7770
|
},
|
|
7213
7771
|
}, configFilter?.resetFilters);
|
|
7214
7772
|
}, [changeFilters, configFilter?.resetFilters, filterName]);
|
|
7215
|
-
const onSelect =
|
|
7773
|
+
const onSelect = React.useCallback((newSelected) => {
|
|
7216
7774
|
const lastSelected = newSelected[newSelected.length - 1];
|
|
7217
7775
|
setFilterValue(multiSelect
|
|
7218
7776
|
? newSelected.map(item => item.value)
|
|
@@ -7221,7 +7779,7 @@ const TextFilter = ({ type, filter, config }) => {
|
|
|
7221
7779
|
: []);
|
|
7222
7780
|
setValue(multiSelect ? "" : lastSelected?.text || "");
|
|
7223
7781
|
}, [multiSelect, setFilterValue]);
|
|
7224
|
-
const onBlur =
|
|
7782
|
+
const onBlur = React.useCallback(() => {
|
|
7225
7783
|
if (variants) {
|
|
7226
7784
|
setFilterValue([value]);
|
|
7227
7785
|
}
|
|
@@ -7229,7 +7787,7 @@ const TextFilter = ({ type, filter, config }) => {
|
|
|
7229
7787
|
setOptions([]);
|
|
7230
7788
|
}
|
|
7231
7789
|
}, [variants, setFilterValue, value]);
|
|
7232
|
-
const onKeyUp =
|
|
7790
|
+
const onKeyUp = React.useCallback(e => {
|
|
7233
7791
|
if (e.key === "Enter") {
|
|
7234
7792
|
setFilterValue([value]);
|
|
7235
7793
|
}
|
|
@@ -7248,7 +7806,7 @@ const TextFilter = ({ type, filter, config }) => {
|
|
|
7248
7806
|
}));
|
|
7249
7807
|
},
|
|
7250
7808
|
});
|
|
7251
|
-
const search =
|
|
7809
|
+
const search = React.useCallback((searchValue, isLoadNext = false) => {
|
|
7252
7810
|
if (variants || !searchFilter?.attributeAlias || !searchFilter?.attributeValue)
|
|
7253
7811
|
return;
|
|
7254
7812
|
const newFilter = {
|
|
@@ -7270,11 +7828,11 @@ const TextFilter = ({ type, filter, config }) => {
|
|
|
7270
7828
|
updateDataSource,
|
|
7271
7829
|
options.length,
|
|
7272
7830
|
]);
|
|
7273
|
-
const infiniteScrollProps =
|
|
7831
|
+
const infiniteScrollProps = React.useMemo(() => ({
|
|
7274
7832
|
loadNext: () => loadNext(() => search(value, true)),
|
|
7275
7833
|
hasMore: totalCount > options.length,
|
|
7276
7834
|
}), [totalCount, options.length, loadNext, search, value]);
|
|
7277
|
-
const selected =
|
|
7835
|
+
const selected = React.useMemo(() => {
|
|
7278
7836
|
if (!filters[filterName]?.value)
|
|
7279
7837
|
return [];
|
|
7280
7838
|
return Array.isArray(filters[filterName].value)
|
|
@@ -7306,7 +7864,7 @@ const DropdownFilter = ({ type, filter, elementConfig }) => {
|
|
|
7306
7864
|
const { filterName, placeholder, width, noEmptyOption } = filter.options;
|
|
7307
7865
|
const { sliceItems } = useShownOtherItems(options);
|
|
7308
7866
|
const configFilter = getConfigFilter(filterName, configFilters);
|
|
7309
|
-
const filterOptions =
|
|
7867
|
+
const filterOptions = React.useMemo(() => {
|
|
7310
7868
|
const dataSource = getDataSource(configFilter.relatedDataSource, dataSources);
|
|
7311
7869
|
const listOptions = getListOptions(sliceItems(dataSource?.features), filterName, configFilters);
|
|
7312
7870
|
if (noEmptyOption === undefined || noEmptyOption === false) {
|
|
@@ -7314,12 +7872,12 @@ const DropdownFilter = ({ type, filter, elementConfig }) => {
|
|
|
7314
7872
|
}
|
|
7315
7873
|
return listOptions;
|
|
7316
7874
|
}, [configFilter.relatedDataSource, configFilters, dataSources, filterName, noEmptyOption, placeholder, sliceItems]);
|
|
7317
|
-
const value =
|
|
7875
|
+
const value = React.useMemo(() => filters?.[filterName] !== undefined
|
|
7318
7876
|
? Array.isArray(filters[filterName].value)
|
|
7319
7877
|
? null
|
|
7320
7878
|
: filters[filterName].value
|
|
7321
7879
|
: getConfigFilter(filterName, configFilters).defaultValue, [configFilters, filterName, filters]);
|
|
7322
|
-
const onChange =
|
|
7880
|
+
const onChange = React.useCallback((items) => {
|
|
7323
7881
|
changeFilters({ [filterName]: items[0] });
|
|
7324
7882
|
}, [changeFilters, filterName]);
|
|
7325
7883
|
if (!configFilter)
|
|
@@ -7362,7 +7920,7 @@ const ChartLoading = ({ column }) => (jsxRuntime.jsx(uilibGl.Flex, { position: "
|
|
|
7362
7920
|
|
|
7363
7921
|
const ContainerLoading = () => (jsxRuntime.jsx(uilibGl.Flex, { alignContent: "center", justifyContent: "center", width: "100%", children: jsxRuntime.jsx(uilibGl.CircularProgress, { diameter: 1.5, mono: true }) }));
|
|
7364
7922
|
|
|
7365
|
-
const ChartWrapper =
|
|
7923
|
+
const ChartWrapper = React.memo(({ width, height, column, loading, children }) => {
|
|
7366
7924
|
return (jsxRuntime.jsxs(ChartWrapperContainer, { column: column, style: { width, height }, children: [loading && jsxRuntime.jsx(ChartLoading, { column: column }), jsxRuntime.jsx(uilibGl.Flex, { opacity: loading ? FILTERED_VALUE_OPACITY / 100 : 1, children: children })] }));
|
|
7367
7925
|
});
|
|
7368
7926
|
|
|
@@ -7411,16 +7969,16 @@ const useBarChartFilter = ({ type, filter, elementConfig }) => {
|
|
|
7411
7969
|
const { t } = useGlobalContext();
|
|
7412
7970
|
const { isLoading, dataSources, filters, changeFilters } = useWidgetContext(type);
|
|
7413
7971
|
const { currentPage } = useWidgetPage(type);
|
|
7414
|
-
const [selectedPixels, setSelectedPixels] =
|
|
7972
|
+
const [selectedPixels, setSelectedPixels] = React.useState(null);
|
|
7415
7973
|
const { filterName } = filter.options;
|
|
7416
7974
|
const { options } = elementConfig;
|
|
7417
7975
|
const { barHeight, barWidth = DEFAULT_BAR_WIDTH, padding = DEFAULT_BAR_PADDING, height = DEFAULT_BAR_CHART_HEIGHT, radius = DEFAULT_BARCHART_RADIUS, width: configWidth, markers: configMarkers, colors: configColors, colorAttribute, defaultColor, primaryColor, drawMinMax } = options || {};
|
|
7418
7976
|
const barFullWidth = barWidth + padding;
|
|
7419
7977
|
const { filters: configFilters } = currentPage;
|
|
7420
|
-
const configFilter =
|
|
7978
|
+
const configFilter = React.useMemo(() => getConfigFilter(filterName, configFilters), [configFilters, filterName]);
|
|
7421
7979
|
const { relatedDataSource, attributeValue, defaultValue } = configFilter || {};
|
|
7422
|
-
const dataSource =
|
|
7423
|
-
const filterItems =
|
|
7980
|
+
const dataSource = React.useMemo(() => getDataSource(relatedDataSource, dataSources), [dataSources, relatedDataSource]);
|
|
7981
|
+
const filterItems = React.useMemo(() => getDataFromRelatedFeatures({
|
|
7424
7982
|
t,
|
|
7425
7983
|
dataSource,
|
|
7426
7984
|
config: elementConfig,
|
|
@@ -7442,32 +8000,32 @@ const useBarChartFilter = ({ type, filter, elementConfig }) => {
|
|
|
7442
8000
|
elementConfig,
|
|
7443
8001
|
t
|
|
7444
8002
|
]);
|
|
7445
|
-
const amount =
|
|
7446
|
-
const width =
|
|
7447
|
-
const data =
|
|
8003
|
+
const amount = React.useMemo(() => filterItems?.length || 0, [filterItems?.length]);
|
|
8004
|
+
const width = React.useMemo(() => configWidth || amount * barFullWidth, [amount, barFullWidth, configWidth]);
|
|
8005
|
+
const data = React.useMemo(() => getDataFromFilterItems(filterItems), [filterItems]);
|
|
7448
8006
|
const loading = isLoading && !amount;
|
|
7449
8007
|
const { formatFilterColor, onFilter } = useFeatureFilters(type, filterName, filterItems);
|
|
7450
|
-
const colors =
|
|
7451
|
-
const selectedRange =
|
|
7452
|
-
const customXAxis =
|
|
8008
|
+
const colors = React.useMemo(() => getColorsFromFilterItems(filterItems, defaultColor, formatFilterColor), [defaultColor, filterItems, formatFilterColor]);
|
|
8009
|
+
const selectedRange = React.useMemo(() => getIndexRange(selectedPixels, amount, barFullWidth), [amount, barFullWidth, selectedPixels]);
|
|
8010
|
+
const customXAxis = React.useCallback(xAxis => {
|
|
7453
8011
|
xAxis.select(".tick:first-of-type").attr("transform", "translate(0, 0)");
|
|
7454
8012
|
xAxis.select(".tick:last-of-type").attr("transform", `translate(${width}, 0)`);
|
|
7455
8013
|
}, [width]);
|
|
7456
|
-
const customXAxisBottom =
|
|
8014
|
+
const customXAxisBottom = React.useCallback(xAxisBottom => {
|
|
7457
8015
|
xAxisBottom.tickFormat((index) => (drawMinMax === undefined || drawMinMax) && (index === 0 || index === data.length - 1)
|
|
7458
8016
|
? data[index].groupName
|
|
7459
8017
|
: "");
|
|
7460
8018
|
}, [data, drawMinMax]);
|
|
7461
|
-
const customYAxis =
|
|
8019
|
+
const customYAxis = React.useCallback(yAxis => {
|
|
7462
8020
|
yAxis.remove();
|
|
7463
8021
|
}, []);
|
|
7464
|
-
const customBars =
|
|
8022
|
+
const customBars = React.useCallback(({ bars }) => {
|
|
7465
8023
|
bars.attr("rx", radius).attr("ry", radius);
|
|
7466
8024
|
}, [radius]);
|
|
7467
|
-
const tooltipY =
|
|
7468
|
-
const markers =
|
|
7469
|
-
const hasDefinedColors =
|
|
7470
|
-
const marshalledMap =
|
|
8025
|
+
const tooltipY = React.useMemo(() => (barHeight ? height - barHeight - DEFAULT_BAR_CHART_MARGINS.bottom : undefined), [barHeight, height]);
|
|
8026
|
+
const markers = React.useMemo(() => getChartMarkers(filterItems, configMarkers), [configMarkers, filterItems]);
|
|
8027
|
+
const hasDefinedColors = React.useMemo(() => configColors?.length || colorAttribute, [configColors, colorAttribute]);
|
|
8028
|
+
const marshalledMap = React.useCallback(items => {
|
|
7471
8029
|
if (hasDefinedColors)
|
|
7472
8030
|
return undefined;
|
|
7473
8031
|
return items.map(([item], index) => {
|
|
@@ -7481,22 +8039,22 @@ const useBarChartFilter = ({ type, filter, elementConfig }) => {
|
|
|
7481
8039
|
];
|
|
7482
8040
|
});
|
|
7483
8041
|
}, [defaultColor, hasDefinedColors, primaryColor, selectedRange, theme.palette.elementDeep, theme.palette.primary]);
|
|
7484
|
-
const minValue =
|
|
7485
|
-
const onBarClick =
|
|
8042
|
+
const minValue = React.useMemo(() => getMinValueFromFilterItems(filterItems), [filterItems]);
|
|
8043
|
+
const onBarClick = React.useCallback((group) => {
|
|
7486
8044
|
if (loading)
|
|
7487
8045
|
return;
|
|
7488
8046
|
setSelectedPixels([group.groupIndex * barFullWidth, group.groupIndex * barFullWidth]);
|
|
7489
8047
|
const feature = filterItems.find(({ value }) => value === group.value);
|
|
7490
8048
|
onFilter(feature.name);
|
|
7491
8049
|
}, [barFullWidth, filterItems, loading, onFilter]);
|
|
7492
|
-
const getValueRange =
|
|
8050
|
+
const getValueRange = React.useCallback((pixelRange) => {
|
|
7493
8051
|
const currentRange = pixelRange || selectedPixels;
|
|
7494
8052
|
const indexRange = getIndexRange(currentRange, filterItems?.length, barFullWidth);
|
|
7495
8053
|
if (!indexRange || lodash.isNil(filterItems[indexRange[0]]) || lodash.isNil(filterItems[indexRange[1]]))
|
|
7496
8054
|
return null;
|
|
7497
8055
|
return [filterItems[indexRange[0]].name, filterItems[indexRange[1]].name];
|
|
7498
8056
|
}, [barFullWidth, filterItems, selectedPixels]);
|
|
7499
|
-
const onSelect =
|
|
8057
|
+
const onSelect = React.useCallback((pixelRange) => {
|
|
7500
8058
|
const valueRange = getValueRange(pixelRange);
|
|
7501
8059
|
if (!valueRange)
|
|
7502
8060
|
return;
|
|
@@ -7509,25 +8067,25 @@ const useBarChartFilter = ({ type, filter, elementConfig }) => {
|
|
|
7509
8067
|
}
|
|
7510
8068
|
}, configFilter?.resetFilters);
|
|
7511
8069
|
}, [changeFilters, configFilter?.resetFilters, filterName, getValueRange]);
|
|
7512
|
-
const prevDisabled =
|
|
7513
|
-
const nextDisabled =
|
|
7514
|
-
const onPrev =
|
|
8070
|
+
const prevDisabled = React.useMemo(() => loading || !selectedPixels || selectedPixels?.[0] - barFullWidth < 0, [barFullWidth, loading, selectedPixels]);
|
|
8071
|
+
const nextDisabled = React.useMemo(() => loading || !selectedPixels || selectedPixels?.[1] + barFullWidth >= width, [barFullWidth, loading, selectedPixels, width]);
|
|
8072
|
+
const onPrev = React.useCallback(() => {
|
|
7515
8073
|
if (prevDisabled)
|
|
7516
8074
|
return;
|
|
7517
8075
|
onSelect([selectedPixels[0] - barFullWidth, selectedPixels[1] - barFullWidth]);
|
|
7518
8076
|
}, [barFullWidth, prevDisabled, onSelect, selectedPixels]);
|
|
7519
|
-
const onNext =
|
|
8077
|
+
const onNext = React.useCallback(() => {
|
|
7520
8078
|
if (nextDisabled)
|
|
7521
8079
|
return;
|
|
7522
8080
|
onSelect([selectedPixels[0] + barFullWidth, selectedPixels[1] + barFullWidth]);
|
|
7523
8081
|
}, [barFullWidth, nextDisabled, onSelect, selectedPixels]);
|
|
7524
|
-
|
|
8082
|
+
React.useEffect(() => {
|
|
7525
8083
|
if (selectedRange || !defaultValue || !filterItems?.length)
|
|
7526
8084
|
return;
|
|
7527
8085
|
const pixelRange = getPixelRange((Array.isArray(defaultValue) ? defaultValue : [defaultValue, defaultValue]), filterItems, barFullWidth);
|
|
7528
8086
|
onSelect(pixelRange);
|
|
7529
8087
|
}, [amount]);
|
|
7530
|
-
|
|
8088
|
+
React.useEffect(() => {
|
|
7531
8089
|
if (lodash.isEmpty(filters[filterName]?.value)) {
|
|
7532
8090
|
if (!lodash.isEmpty(selectedPixels)) {
|
|
7533
8091
|
setSelectedPixels(null);
|
|
@@ -7574,14 +8132,14 @@ const BarChartFilter = ({ type, config, elementConfig, filter }) => {
|
|
|
7574
8132
|
elementConfig,
|
|
7575
8133
|
filter
|
|
7576
8134
|
});
|
|
7577
|
-
const renderSelectedRange =
|
|
8135
|
+
const renderSelectedRange = React.useMemo(() => {
|
|
7578
8136
|
if (!selectedRange)
|
|
7579
8137
|
return null;
|
|
7580
8138
|
return (jsxRuntime.jsx(BarChartFilterSelected, { children: selectedRange[0] === selectedRange[1]
|
|
7581
8139
|
? data[selectedRange[0]].groupName
|
|
7582
8140
|
: `${data[selectedRange[0]].groupName} - ${data[selectedRange[1]].groupName}` }));
|
|
7583
8141
|
}, [data, selectedRange]);
|
|
7584
|
-
const renderTooltip =
|
|
8142
|
+
const renderTooltip = React.useCallback((groups) => {
|
|
7585
8143
|
const group = groups[0];
|
|
7586
8144
|
return (jsxRuntime.jsx(uilibGl.ThemeProvider, { children: jsxRuntime.jsx(TooltipContainer, { children: group.groupName === group.value.toString() ? group.value : [group.groupName, group.value].join(": ") }) }));
|
|
7587
8145
|
}, []);
|
|
@@ -7594,25 +8152,25 @@ const RangeDateFilter = ({ type, filter }) => {
|
|
|
7594
8152
|
const { t } = useGlobalContext();
|
|
7595
8153
|
const { changeFilters, dataSources } = useWidgetContext(type);
|
|
7596
8154
|
const { currentPage } = useWidgetPage(type);
|
|
7597
|
-
const [value, setValue] =
|
|
7598
|
-
const isInit =
|
|
8155
|
+
const [value, setValue] = React.useState([undefined, undefined]);
|
|
8156
|
+
const isInit = React.useRef(false);
|
|
7599
8157
|
const updateDebounce = useDebouncedCallback(FILTER_UPDATE_DEBOUNCE);
|
|
7600
8158
|
const { filters: configFilters } = currentPage;
|
|
7601
8159
|
const { filterName, label, minValue, maxValue, withTime } = filter.options;
|
|
7602
|
-
const configFilter =
|
|
7603
|
-
const dataSource =
|
|
7604
|
-
const { minFromData, maxFromData } =
|
|
8160
|
+
const configFilter = React.useMemo(() => getConfigFilter(filterName, configFilters), [configFilters, filterName]);
|
|
8161
|
+
const dataSource = React.useMemo(() => getDataSource(configFilter?.relatedDataSource, dataSources), [configFilter?.relatedDataSource, dataSources]);
|
|
8162
|
+
const { minFromData, maxFromData } = React.useMemo(() => dataSource?.features?.reduce((prev, { attributes }) => {
|
|
7605
8163
|
const date = getDate(attributes[configFilter?.attributeValue]);
|
|
7606
8164
|
return {
|
|
7607
8165
|
minFromData: !prev.minFromData ? date : date < prev.minFromData ? date : prev.minFromData,
|
|
7608
8166
|
maxFromData: !prev.maxFromData ? date : date > prev.maxFromData ? date : prev.maxFromData
|
|
7609
8167
|
};
|
|
7610
8168
|
}, DEFAULT_FROM_DATA) || DEFAULT_FROM_DATA, [configFilter?.attributeValue, dataSource?.features]);
|
|
7611
|
-
const minDate =
|
|
7612
|
-
const maxDate =
|
|
7613
|
-
const isEmpty =
|
|
7614
|
-
const isDefault =
|
|
7615
|
-
const reset =
|
|
8169
|
+
const minDate = React.useMemo(() => minValue || minFromData.toISOString(), [minFromData, minValue]);
|
|
8170
|
+
const maxDate = React.useMemo(() => maxValue || maxFromData.toISOString(), [maxFromData, maxValue]);
|
|
8171
|
+
const isEmpty = React.useMemo(() => lodash.isNil(value?.[0]) && lodash.isNil(value?.[1]), [value]);
|
|
8172
|
+
const isDefault = React.useMemo(() => value?.[0] === minDate && value?.[1] === maxDate, [maxDate, minDate, value]);
|
|
8173
|
+
const reset = React.useCallback(() => {
|
|
7616
8174
|
setValue([minDate, maxDate]);
|
|
7617
8175
|
changeFilters({
|
|
7618
8176
|
[filterName]: {
|
|
@@ -7622,15 +8180,15 @@ const RangeDateFilter = ({ type, filter }) => {
|
|
|
7622
8180
|
}
|
|
7623
8181
|
}, configFilter?.resetFilters);
|
|
7624
8182
|
}, [changeFilters, configFilter?.resetFilters, filterName, maxDate, minDate]);
|
|
7625
|
-
const onChange =
|
|
8183
|
+
const onChange = React.useCallback((newValue) => {
|
|
7626
8184
|
setValue([newValue[0].toISOString(), newValue[1].toISOString()]);
|
|
7627
8185
|
}, []);
|
|
7628
|
-
|
|
8186
|
+
React.useEffect(() => {
|
|
7629
8187
|
if (!lodash.isNil(minDate) && !lodash.isNil(maxDate)) {
|
|
7630
8188
|
reset();
|
|
7631
8189
|
}
|
|
7632
8190
|
}, []); // eslint-disable-line
|
|
7633
|
-
|
|
8191
|
+
React.useEffect(() => {
|
|
7634
8192
|
if (!isInit.current) {
|
|
7635
8193
|
isInit.current = true;
|
|
7636
8194
|
return;
|
|
@@ -7708,7 +8266,7 @@ const getFilterValue = ({ selectedFilters, configFilters, filterName, newValue,
|
|
|
7708
8266
|
const getFormattedAttributes = (t, data, attributes, config) => {
|
|
7709
8267
|
const showOtherItems = config?.options?.otherItems < data?.length;
|
|
7710
8268
|
const otherIndex = config?.options?.otherItems + 1;
|
|
7711
|
-
const otherAttribute = showOtherItems && config?.children?.[otherIndex]
|
|
8269
|
+
const otherAttribute = showOtherItems && config?.children?.[otherIndex] && attributes?.length
|
|
7712
8270
|
? attributes.find(({ name }) => name === config?.children?.[otherIndex]?.attributeName)
|
|
7713
8271
|
: null;
|
|
7714
8272
|
return otherAttribute
|
|
@@ -7819,7 +8377,7 @@ const getSvgUrl = ({ elementConfig, layerInfo, attributes, }) => {
|
|
|
7819
8377
|
}
|
|
7820
8378
|
else {
|
|
7821
8379
|
url = elementConfig.attributeName
|
|
7822
|
-
? attributes
|
|
8380
|
+
? attributes?.find(item => item.name === elementConfig.attributeName)?.value?.toString()
|
|
7823
8381
|
: elementConfig.value?.toString();
|
|
7824
8382
|
}
|
|
7825
8383
|
if (!url || typeof url !== "string")
|
|
@@ -7829,7 +8387,7 @@ const getSvgUrl = ({ elementConfig, layerInfo, attributes, }) => {
|
|
|
7829
8387
|
|
|
7830
8388
|
const getTotalFromAttributes = (children, attributes) => {
|
|
7831
8389
|
const total = children?.reduce((result, { attributeName }) => {
|
|
7832
|
-
const value = attributes
|
|
8390
|
+
const value = attributes?.find(({ name }) => name === attributeName)?.value || 0;
|
|
7833
8391
|
return result + value;
|
|
7834
8392
|
}, 0);
|
|
7835
8393
|
return typeof total === "number" ? total.toFixed(0) : "";
|
|
@@ -7840,7 +8398,7 @@ const getTotalFromRelatedFeatures = (data) => {
|
|
|
7840
8398
|
};
|
|
7841
8399
|
|
|
7842
8400
|
const pieChartTooltipFromAttributes = (t, data, attributes) => {
|
|
7843
|
-
const attribute = attributes
|
|
8401
|
+
const attribute = attributes?.find(({ name }) => name === data[0].name);
|
|
7844
8402
|
const renderValue = attribute
|
|
7845
8403
|
? formatAttributeValue({ t, type: attribute.type, value: data[0].value, stringFormat: attribute.stringFormat })
|
|
7846
8404
|
: data[0].value;
|
|
@@ -7894,7 +8452,7 @@ const sliceShownOtherItems = (data, options = {}, showMore) => {
|
|
|
7894
8452
|
};
|
|
7895
8453
|
|
|
7896
8454
|
const tooltipNameFromAttributes = (name, attributes) => {
|
|
7897
|
-
const attribute = attributes
|
|
8455
|
+
const attribute = attributes?.find(item => item.name === name);
|
|
7898
8456
|
return attribute?.alias || name;
|
|
7899
8457
|
};
|
|
7900
8458
|
|
|
@@ -7908,9 +8466,9 @@ const tooltipValueFromRelatedFeatures = (t, value, relatedAttributes, layerInfo)
|
|
|
7908
8466
|
};
|
|
7909
8467
|
|
|
7910
8468
|
const useWidgetConfig = (type = exports.WidgetType.Dashboard) => {
|
|
7911
|
-
const { config: configProp } =
|
|
8469
|
+
const { config: configProp } = React.useContext(ConfigContext);
|
|
7912
8470
|
const { projectInfo, layerInfo } = useWidgetContext(type);
|
|
7913
|
-
const config =
|
|
8471
|
+
const config = React.useMemo(() => {
|
|
7914
8472
|
if (configProp) {
|
|
7915
8473
|
return configProp;
|
|
7916
8474
|
}
|
|
@@ -7919,7 +8477,7 @@ const useWidgetConfig = (type = exports.WidgetType.Dashboard) => {
|
|
|
7919
8477
|
}
|
|
7920
8478
|
return (layerInfo?.configuration?.cardConfiguration || {});
|
|
7921
8479
|
}, [configProp, layerInfo?.configuration?.cardConfiguration, projectInfo?.content?.dashboardConfiguration, type]);
|
|
7922
|
-
const pages =
|
|
8480
|
+
const pages = React.useMemo(() => (getPagesFromConfig(config) || []), [config]);
|
|
7923
8481
|
return {
|
|
7924
8482
|
config,
|
|
7925
8483
|
pages,
|
|
@@ -7930,10 +8488,11 @@ const useWidgetPage = (type = exports.WidgetType.Dashboard) => {
|
|
|
7930
8488
|
const { t } = useGlobalContext();
|
|
7931
8489
|
const { pageIndex, changePage, projectInfo, updateProject } = useWidgetContext(type);
|
|
7932
8490
|
const { config } = useWidgetConfig(type);
|
|
7933
|
-
const currentPage =
|
|
8491
|
+
const currentPage = React.useMemo(() => {
|
|
7934
8492
|
const page = getPagesFromConfig(config)?.[pageIndex - 1];
|
|
7935
8493
|
return {
|
|
7936
8494
|
...(page || {}),
|
|
8495
|
+
header: page?.header || config.header,
|
|
7937
8496
|
dataSources: [
|
|
7938
8497
|
...(page?.dataSources?.filter(({ name }) => !config.dataSources?.some(item => item.name === name)) || []),
|
|
7939
8498
|
...(config.dataSources || [])
|
|
@@ -7948,7 +8507,7 @@ const useWidgetPage = (type = exports.WidgetType.Dashboard) => {
|
|
|
7948
8507
|
})) || []
|
|
7949
8508
|
};
|
|
7950
8509
|
}, [config, pageIndex]);
|
|
7951
|
-
const updateConfigPage =
|
|
8510
|
+
const updateConfigPage = React.useCallback((newConfig) => {
|
|
7952
8511
|
const newProjectInfo = JSON.parse(JSON.stringify(projectInfo));
|
|
7953
8512
|
const pages = getPagesFromProjectInfo(newProjectInfo);
|
|
7954
8513
|
if (!pages?.[pageIndex - 1])
|
|
@@ -7956,7 +8515,7 @@ const useWidgetPage = (type = exports.WidgetType.Dashboard) => {
|
|
|
7956
8515
|
pages[pageIndex - 1] = { ...pages[pageIndex - 1], ...newConfig };
|
|
7957
8516
|
updateProject(newProjectInfo);
|
|
7958
8517
|
}, [projectInfo, pageIndex, updateProject]);
|
|
7959
|
-
const addConfigPage =
|
|
8518
|
+
const addConfigPage = React.useCallback(() => {
|
|
7960
8519
|
const newProjectInfo = JSON.parse(JSON.stringify(projectInfo));
|
|
7961
8520
|
const pages = getPagesFromProjectInfo(newProjectInfo);
|
|
7962
8521
|
if (!pages)
|
|
@@ -7965,7 +8524,7 @@ const useWidgetPage = (type = exports.WidgetType.Dashboard) => {
|
|
|
7965
8524
|
updateProject(newProjectInfo);
|
|
7966
8525
|
changePage(pages.length);
|
|
7967
8526
|
}, [changePage, projectInfo, t, updateProject]);
|
|
7968
|
-
const deleteConfigPage =
|
|
8527
|
+
const deleteConfigPage = React.useCallback((index) => {
|
|
7969
8528
|
const newProjectInfo = JSON.parse(JSON.stringify(projectInfo));
|
|
7970
8529
|
const pages = getPagesFromProjectInfo(newProjectInfo);
|
|
7971
8530
|
if (!pages?.[index] || pages.length === 1)
|
|
@@ -7983,10 +8542,10 @@ const useChartData = ({ element, type }) => {
|
|
|
7983
8542
|
const { t } = useGlobalContext();
|
|
7984
8543
|
const { dataSources, layerInfos, attributes } = useWidgetContext(type);
|
|
7985
8544
|
const { currentPage } = useWidgetPage(type);
|
|
7986
|
-
const relatedAttributes =
|
|
7987
|
-
const loading =
|
|
8545
|
+
const relatedAttributes = React.useMemo(() => element?.options?.relatedDataSources || [], [element?.options?.relatedDataSources]);
|
|
8546
|
+
const loading = React.useMemo(() => !!relatedAttributes?.length &&
|
|
7988
8547
|
!dataSources?.some(({ name }) => relatedAttributes.some(({ chartAxis, dataSourceName }) => chartAxis === "y" && dataSourceName === name)), [dataSources, relatedAttributes]);
|
|
7989
|
-
const fetchedData =
|
|
8548
|
+
const fetchedData = React.useMemo(() => {
|
|
7990
8549
|
const configDataSources = currentPage?.dataSources || [];
|
|
7991
8550
|
const isRelated = !!relatedAttributes?.length;
|
|
7992
8551
|
const filteredAttributes = relatedAttributes.filter(({ chartAxis }) => chartAxis === "y");
|
|
@@ -8039,8 +8598,8 @@ const useChartData = ({ element, type }) => {
|
|
|
8039
8598
|
layerInfos,
|
|
8040
8599
|
dataSources
|
|
8041
8600
|
]);
|
|
8042
|
-
const [data, setData] =
|
|
8043
|
-
|
|
8601
|
+
const [data, setData] = React.useState(fetchedData);
|
|
8602
|
+
React.useEffect(() => {
|
|
8044
8603
|
if (!loading && fetchedData?.length) {
|
|
8045
8604
|
setData(fetchedData);
|
|
8046
8605
|
}
|
|
@@ -8048,17 +8607,34 @@ const useChartData = ({ element, type }) => {
|
|
|
8048
8607
|
return { data, loading };
|
|
8049
8608
|
};
|
|
8050
8609
|
|
|
8051
|
-
const
|
|
8610
|
+
const useHeaderRender = (elementConfig, type = exports.WidgetType.Dashboard) => {
|
|
8611
|
+
const { layerInfo, attributes, expandedContainers, selectedTabId, setSelectedTabId } = useWidgetContext(type);
|
|
8612
|
+
const { config } = useWidgetConfig(type);
|
|
8613
|
+
const { pageIndex } = useWidgetPage(type);
|
|
8614
|
+
return React.useMemo(() => getRenderElement({
|
|
8615
|
+
config,
|
|
8616
|
+
elementConfig,
|
|
8617
|
+
attributes,
|
|
8618
|
+
layerInfo,
|
|
8619
|
+
expandedContainers,
|
|
8620
|
+
selectedTabId,
|
|
8621
|
+
setSelectedTabId,
|
|
8622
|
+
pageIndex,
|
|
8623
|
+
}), [config, elementConfig, attributes, layerInfo, expandedContainers, selectedTabId, setSelectedTabId, pageIndex]);
|
|
8624
|
+
};
|
|
8625
|
+
|
|
8626
|
+
const useDashboardHeader = () => {
|
|
8052
8627
|
const { themeName } = useGlobalContext();
|
|
8053
8628
|
const { projectInfo } = useWidgetContext();
|
|
8054
8629
|
const { currentPage } = useWidgetPage();
|
|
8055
8630
|
const { alias, name } = projectInfo || {};
|
|
8056
8631
|
const { id: pageId, header } = currentPage || {};
|
|
8057
|
-
const
|
|
8058
|
-
const
|
|
8059
|
-
const
|
|
8060
|
-
const
|
|
8061
|
-
const
|
|
8632
|
+
const renderElement = useHeaderRender(header);
|
|
8633
|
+
const image = React.useMemo(() => (header?.children?.some(({ id }) => id === "image") ? renderElement({ id: "image", wrap: false }) : null), [header?.children, renderElement]);
|
|
8634
|
+
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]);
|
|
8635
|
+
const title = React.useMemo(() => header?.children?.some(({ id }) => id === "title") ? renderElement({ id: "title" }) : currentPage?.options?.title, [header?.children, renderElement, currentPage?.options?.title]);
|
|
8636
|
+
const tooltip = React.useMemo(() => (jsxRuntime.jsxs(uilibGl.Flex, { textAlign: "left", children: [jsxRuntime.jsx("div", { children: alias || name }), jsxRuntime.jsx(uilibGl.Flex, { opacity: 0.54, children: title })] })), [alias, name, title]);
|
|
8637
|
+
const description = React.useMemo(() => (header?.children?.some(({ id }) => id === "description") ? renderElement({ id: "description" }) : ""), [header?.children, renderElement]);
|
|
8062
8638
|
return {
|
|
8063
8639
|
pageId,
|
|
8064
8640
|
image,
|
|
@@ -8067,6 +8643,7 @@ const useDashboardHeader = (renderElement) => {
|
|
|
8067
8643
|
tooltip,
|
|
8068
8644
|
description,
|
|
8069
8645
|
themeName,
|
|
8646
|
+
renderElement,
|
|
8070
8647
|
};
|
|
8071
8648
|
};
|
|
8072
8649
|
|
|
@@ -8076,8 +8653,8 @@ const useDataSources = ({ type: widgetType, config, attributes, filters, layerPa
|
|
|
8076
8653
|
const { ewktGeometry, api } = useGlobalContext();
|
|
8077
8654
|
const { dataSources } = useWidgetContext(widgetType);
|
|
8078
8655
|
const { filters: configFilters, dataSources: configDataSources } = config || {};
|
|
8079
|
-
const prevFilters =
|
|
8080
|
-
const getDataSourcePromises =
|
|
8656
|
+
const prevFilters = React.useRef({});
|
|
8657
|
+
const getDataSourcePromises = React.useCallback(async ({ ds, query, parameters, layerName, limit, condition, url, resourceId, type }, newFilters, offset = 0) => {
|
|
8081
8658
|
const selectedFilters = {
|
|
8082
8659
|
...(filters || {}),
|
|
8083
8660
|
...(newFilters || {}),
|
|
@@ -8139,7 +8716,7 @@ const useDataSources = ({ type: widgetType, config, attributes, filters, layerPa
|
|
|
8139
8716
|
: [condition, query].filter(Boolean),
|
|
8140
8717
|
});
|
|
8141
8718
|
}, [filters, dataSources, configFilters, ewktGeometry, attributes, layerParams, eqlParameters]);
|
|
8142
|
-
const getUpdatingDataSources =
|
|
8719
|
+
const getUpdatingDataSources = React.useCallback(() => {
|
|
8143
8720
|
const diffFilterNames = filters
|
|
8144
8721
|
? Object.keys(filters).filter(key => Array.isArray(filters[key].value)
|
|
8145
8722
|
? filters[key].value.length !== prevFilters.current[key]?.value?.length ||
|
|
@@ -8156,7 +8733,7 @@ const useDataSources = ({ type: widgetType, config, attributes, filters, layerPa
|
|
|
8156
8733
|
prevFilters.current = JSON.parse(JSON.stringify(filters));
|
|
8157
8734
|
return filteredDataSources;
|
|
8158
8735
|
}, [configDataSources, filters]);
|
|
8159
|
-
const getUpdatedDataSources =
|
|
8736
|
+
const getUpdatedDataSources = React.useCallback((responses, currentDataSources, otherDataSources) => {
|
|
8160
8737
|
const newDataSources = JSON.parse(JSON.stringify([...currentDataSources, ...otherDataSources]));
|
|
8161
8738
|
responses.forEach((response, index) => {
|
|
8162
8739
|
const isQueryDataSource = !lodash.isNil(currentDataSources[index].query) ||
|
|
@@ -8179,7 +8756,7 @@ const useDataSources = ({ type: widgetType, config, attributes, filters, layerPa
|
|
|
8179
8756
|
});
|
|
8180
8757
|
return newDataSources;
|
|
8181
8758
|
}, []);
|
|
8182
|
-
const zoomToLayersExtent =
|
|
8759
|
+
const zoomToLayersExtent = React.useCallback(async (layers) => {
|
|
8183
8760
|
const newExtent = await api.layers.getBulkExtents({ srId: 4326 }, layers?.map(({ layerName, conditions, parameters }) => ({
|
|
8184
8761
|
layerName,
|
|
8185
8762
|
conditions,
|
|
@@ -8210,17 +8787,17 @@ const useDataSources = ({ type: widgetType, config, attributes, filters, layerPa
|
|
|
8210
8787
|
|
|
8211
8788
|
const useDiffPage = (type) => {
|
|
8212
8789
|
const { pageIndex } = useWidgetContext(type);
|
|
8213
|
-
const prevPageIndex =
|
|
8790
|
+
const prevPageIndex = React.useRef(pageIndex);
|
|
8214
8791
|
const isDiffPage = prevPageIndex.current !== pageIndex;
|
|
8215
|
-
|
|
8792
|
+
React.useEffect(() => {
|
|
8216
8793
|
prevPageIndex.current = pageIndex;
|
|
8217
8794
|
}, [pageIndex]);
|
|
8218
|
-
return
|
|
8795
|
+
return React.useMemo(() => isDiffPage, [isDiffPage]);
|
|
8219
8796
|
};
|
|
8220
8797
|
|
|
8221
8798
|
const useExpandableContainers = () => {
|
|
8222
|
-
const [expandedContainers, setExpandedContainers] =
|
|
8223
|
-
const expandContainer =
|
|
8799
|
+
const [expandedContainers, setExpandedContainers] = React.useState({});
|
|
8800
|
+
const expandContainer = React.useCallback((id, expanded) => {
|
|
8224
8801
|
setExpandedContainers(state => ({
|
|
8225
8802
|
...state,
|
|
8226
8803
|
[id]: state?.[id] === undefined && expanded !== undefined ? !expanded : !state?.[id],
|
|
@@ -8244,11 +8821,11 @@ const useFeatureFilters = (type, filterName, items) => {
|
|
|
8244
8821
|
const theme = styled.useTheme();
|
|
8245
8822
|
const { filters, changeFilters } = useWidgetContext(type);
|
|
8246
8823
|
const { currentPage } = useWidgetPage(type);
|
|
8247
|
-
const configFilter =
|
|
8824
|
+
const configFilter = React.useMemo(() => getConfigFilter(filterName, currentPage.filters), [currentPage.filters, filterName]);
|
|
8248
8825
|
const hasAnyFilter = Array.isArray(filters?.[filterName]?.value)
|
|
8249
8826
|
? !!filters[filterName].value.length
|
|
8250
8827
|
: !!filters?.[filterName]?.value;
|
|
8251
|
-
const isFiltered =
|
|
8828
|
+
const isFiltered = React.useCallback((name) => {
|
|
8252
8829
|
const filterValue = filters[filterName]?.value || configFilter?.defaultValue;
|
|
8253
8830
|
if (!Array.isArray(filterValue)) {
|
|
8254
8831
|
return filterValue === name;
|
|
@@ -8258,7 +8835,7 @@ const useFeatureFilters = (type, filterName, items) => {
|
|
|
8258
8835
|
? filterValue.includes(name)
|
|
8259
8836
|
: filterValue?.[0] <= name && filterValue?.[1] >= name));
|
|
8260
8837
|
}, [configFilter?.defaultValue, configFilter?.valueType, filterName, filters]);
|
|
8261
|
-
const formatFilterColor =
|
|
8838
|
+
const formatFilterColor = React.useCallback((name, color, defaultColor = FEATURE_CARD_OTHER_COLOR) => {
|
|
8262
8839
|
return isFiltered(name)
|
|
8263
8840
|
? color || theme.palette.primary
|
|
8264
8841
|
: hasAnyFilter
|
|
@@ -8267,7 +8844,7 @@ const useFeatureFilters = (type, filterName, items) => {
|
|
|
8267
8844
|
: defaultColor
|
|
8268
8845
|
: color || theme.palette.primary;
|
|
8269
8846
|
}, [hasAnyFilter, isFiltered, theme.palette.primary]);
|
|
8270
|
-
const onFilter =
|
|
8847
|
+
const onFilter = React.useCallback((newValue) => {
|
|
8271
8848
|
const value = getFilterValue({
|
|
8272
8849
|
selectedFilters: filters,
|
|
8273
8850
|
configFilters: currentPage.filters,
|
|
@@ -8313,12 +8890,12 @@ const useFeatureFilters = (type, filterName, items) => {
|
|
|
8313
8890
|
|
|
8314
8891
|
const useGetConfigLayer = () => {
|
|
8315
8892
|
const { currentPage } = useWidgetPage();
|
|
8316
|
-
return
|
|
8893
|
+
return React.useCallback((layerName) => currentPage?.layers?.find(({ name }) => name === layerName), [currentPage?.layers]);
|
|
8317
8894
|
};
|
|
8318
8895
|
|
|
8319
8896
|
const useProjectDashboardInit = () => {
|
|
8320
8897
|
const { projectInfo, updateProject } = useWidgetContext();
|
|
8321
|
-
return
|
|
8898
|
+
return React.useCallback(() => {
|
|
8322
8899
|
if (!lodash.isEmpty(projectInfo?.content?.dashboardConfiguration) || !projectInfo?.content?.items?.length) {
|
|
8323
8900
|
return;
|
|
8324
8901
|
}
|
|
@@ -8335,10 +8912,10 @@ const useRelatedDataSourceAttributes = ({ type = exports.WidgetType.Dashboard, e
|
|
|
8335
8912
|
const { currentPage } = useWidgetPage(type);
|
|
8336
8913
|
const { options } = elementConfig || {};
|
|
8337
8914
|
const { relatedDataSource } = options || {};
|
|
8338
|
-
const dataSource =
|
|
8339
|
-
const layerInfo =
|
|
8915
|
+
const dataSource = React.useMemo(() => getDataSource(relatedDataSource, dataSources), [dataSources, relatedDataSource]);
|
|
8916
|
+
const layerInfo = React.useMemo(() => getLayerInfoFromDataSources(layerInfos, currentPage?.dataSources, relatedDataSource) ||
|
|
8340
8917
|
{ layerDefinition: { attributes: dataSource?.attributeDefinition || {} } }, [currentPage?.dataSources, dataSource?.attributeDefinition, layerInfos, relatedDataSource]);
|
|
8341
|
-
const attributes =
|
|
8918
|
+
const attributes = React.useMemo(() => getFeatureAttributes(feature, layerInfo, dataSource), [dataSource, feature, layerInfo]);
|
|
8342
8919
|
return { layerInfo, attributes, dataSource };
|
|
8343
8920
|
};
|
|
8344
8921
|
|
|
@@ -8347,7 +8924,7 @@ const useRenderElement = (type = exports.WidgetType.Dashboard, elementConfig) =>
|
|
|
8347
8924
|
const { selectedTabId, setSelectedTabId, expandedContainers, layerInfo, attributes } = useWidgetContext(type);
|
|
8348
8925
|
const { config } = useWidgetConfig(type);
|
|
8349
8926
|
const { pageIndex } = useWidgetPage(type);
|
|
8350
|
-
return
|
|
8927
|
+
return React.useMemo(() => getRenderElement({
|
|
8351
8928
|
t,
|
|
8352
8929
|
type,
|
|
8353
8930
|
config,
|
|
@@ -8392,7 +8969,7 @@ const useUpdateDataSource = ({ dataSource, config, filters, attributes, layerPar
|
|
|
8392
8969
|
layerParams,
|
|
8393
8970
|
eqlParameters,
|
|
8394
8971
|
});
|
|
8395
|
-
return
|
|
8972
|
+
return React.useCallback(async (newFilters, offset = 0) => {
|
|
8396
8973
|
return getDataSourcePromises(dataSource, newFilters, offset).then((response) => {
|
|
8397
8974
|
const responseDataSources = getUpdatedDataSources([response], [dataSource], dataSources);
|
|
8398
8975
|
return {
|
|
@@ -8411,17 +8988,17 @@ const StackBar = ({ data, filterName, type, alias, options, renderElement, rende
|
|
|
8411
8988
|
const { items, layerInfo, attributeName } = data?.[0] || {};
|
|
8412
8989
|
const attribute = layerInfo?.layerDefinition.attributes[attributeName];
|
|
8413
8990
|
const units = attribute?.stringFormat?.unitsLabel;
|
|
8414
|
-
const total =
|
|
8415
|
-
const getWidth =
|
|
8416
|
-
const renderGroupTooltip =
|
|
8417
|
-
const renderItem =
|
|
8418
|
-
const renderItems =
|
|
8991
|
+
const total = React.useMemo(() => items?.reduce((result, { value }) => result + Number(value), 0) || 0, [items]);
|
|
8992
|
+
const getWidth = React.useCallback(value => ((Number(value) / total) * 100).toFixed(2), [total]);
|
|
8993
|
+
const renderGroupTooltip = React.useMemo(() => (jsxRuntime.jsx(uilibGl.ThemeProvider, { children: jsxRuntime.jsx(ChartTooltipTable, { cellPadding: 0, cellSpacing: 0, children: items?.map(({ name, value, color }, index) => (jsxRuntime.jsxs("tr", { children: [jsxRuntime.jsx("td", { children: jsxRuntime.jsxs(ChartTooltip, { children: [jsxRuntime.jsx(ChartTooltipColor, { "$color": color }), jsxRuntime.jsx(ChartTooltipName, { children: name })] }) }), jsxRuntime.jsx("td", { children: value })] }, index))) }) })), [items]);
|
|
8994
|
+
const renderItem = React.useCallback(({ name, value, color }, ref) => (jsxRuntime.jsx(StackBarSection, { ref: ref, "$width": getWidth(value), "$height": height, "$color": color, cornerRadius: cornerRadius, hasAnyFilter: hasAnyFilter, isFiltered: isFiltered(name), onClick: filterName ? () => onFilter(name) : undefined })), [cornerRadius, filterName, getWidth, hasAnyFilter, height, isFiltered, onFilter]);
|
|
8995
|
+
const renderItems = React.useMemo(() => (jsxRuntime.jsx(jsxRuntime.Fragment, { children: items?.map((item, index) => (jsxRuntime.jsx(React.Fragment, { children: groupTooltip ? (renderItem(item)) : (jsxRuntime.jsx(uilibGl.ThemeProvider, { children: jsxRuntime.jsx(uilibGl.Tooltip, { placement: "top", arrow: true, content: renderTooltip([item]), children: ref => renderItem(item, ref) }) })) }, index))) })), [groupTooltip, items, renderItem, renderTooltip]);
|
|
8419
8996
|
if (!total || !attribute)
|
|
8420
8997
|
return null;
|
|
8421
8998
|
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [(alias || showTotal) && (jsxRuntime.jsxs(StackBarHeader, { children: [jsxRuntime.jsx(StackBarAlias, { children: renderElement({ id: "alias" }) }), showTotal && (jsxRuntime.jsxs(StackBarTotal, { children: [jsxRuntime.jsx(StackBarValue, { children: formatAttributeValue({ t, type: attribute.type, value: total, stringFormat: attribute.stringFormat, noUnits: true }) }), !!units && jsxRuntime.jsx(StackBarUnits, { children: units })] }))] })), groupTooltip ? (jsxRuntime.jsx(uilibGl.Tooltip, { placement: "top", arrow: true, content: renderGroupTooltip, children: ref => jsxRuntime.jsx(StackBarContainer, { ref: ref, children: renderItems }) })) : (jsxRuntime.jsx(StackBarContainer, { children: renderItems }))] }));
|
|
8422
8999
|
};
|
|
8423
9000
|
|
|
8424
|
-
const Chart =
|
|
9001
|
+
const Chart = React.memo(({ config, element, elementConfig, type, renderElement }) => {
|
|
8425
9002
|
const theme = styled.useTheme();
|
|
8426
9003
|
const { palette } = theme;
|
|
8427
9004
|
const { t } = useGlobalContext();
|
|
@@ -8440,8 +9017,8 @@ const Chart = react.memo(({ config, element, elementConfig, type, renderElement
|
|
|
8440
9017
|
const barWidth = options?.barWidth || DEFAULT_BAR_WIDTH;
|
|
8441
9018
|
const cornerRadius = options?.cornerRadius || 0;
|
|
8442
9019
|
const primaryColor = theme.palette.primary;
|
|
8443
|
-
const relatedAttributes =
|
|
8444
|
-
const axes =
|
|
9020
|
+
const relatedAttributes = React.useMemo(() => relatedDataSources || [], [relatedDataSources]);
|
|
9021
|
+
const axes = React.useMemo(() => relatedAttributes.filter(({ chartAxis }) => chartAxis === "y"), [relatedAttributes]);
|
|
8445
9022
|
const filterName = getChartFilterName(relatedDataSources);
|
|
8446
9023
|
const isRelated = !!relatedAttributes?.length;
|
|
8447
9024
|
const { data, loading } = useChartData({ element, type });
|
|
@@ -8467,23 +9044,23 @@ const Chart = react.memo(({ config, element, elementConfig, type, renderElement
|
|
|
8467
9044
|
defaultColor: primaryColor
|
|
8468
9045
|
});
|
|
8469
9046
|
const { formatFilterColor, onFilter } = useFeatureFilters(type, filterName, data?.[0]?.items);
|
|
8470
|
-
const formattedAttributes =
|
|
8471
|
-
const totalSum =
|
|
9047
|
+
const formattedAttributes = React.useMemo(() => getFormattedAttributes(t, (data[0]?.items || []), attributes, element), [attributes, data, element, t]);
|
|
9048
|
+
const totalSum = React.useMemo(() => isRelated
|
|
8472
9049
|
? getTotalFromRelatedFeatures((data[0]?.items || []))
|
|
8473
9050
|
: getTotalFromAttributes(children, formattedAttributes), [data, children, formattedAttributes, isRelated]);
|
|
8474
|
-
const totalWord =
|
|
8475
|
-
? attributes
|
|
9051
|
+
const totalWord = React.useMemo(() => options?.totalAttribute
|
|
9052
|
+
? attributes?.find(({ name }) => name === options.totalAttribute)?.value
|
|
8476
9053
|
: options?.totalWord, [attributes, options.totalAttribute, options?.totalWord]);
|
|
8477
|
-
const renderPieChartTooltip =
|
|
9054
|
+
const renderPieChartTooltip = React.useCallback(item => isRelated
|
|
8478
9055
|
? pieChartTooltipFromRelatedFeatures(t, item, relatedAttributes, data[0]?.layerInfo)
|
|
8479
9056
|
: pieChartTooltipFromAttributes(t, item, formattedAttributes), [data, formattedAttributes, isRelated, relatedAttributes]);
|
|
8480
|
-
const labels =
|
|
9057
|
+
const labels = React.useMemo(() => {
|
|
8481
9058
|
if (!isLineChart)
|
|
8482
9059
|
return [];
|
|
8483
9060
|
const result = data?.map(item => item?.items?.map(({ name }) => name?.toString()))?.flat();
|
|
8484
9061
|
return result?.filter((name, index) => result.indexOf(name) === index);
|
|
8485
9062
|
}, [data, isLineChart]);
|
|
8486
|
-
const renderLineChartTooltip =
|
|
9063
|
+
const renderLineChartTooltip = React.useCallback((items, { indexX }) => {
|
|
8487
9064
|
return (jsxRuntime.jsx(uilibGl.ThemeProvider, { children: jsxRuntime.jsxs(ChartTooltip, { children: [jsxRuntime.jsx("div", { children: labels[indexX] }), items
|
|
8488
9065
|
.filter(({ value }) => !isEmptyValue(value))
|
|
8489
9066
|
?.map(({ layerName, attributeName, value, stroke }, index) => {
|
|
@@ -8492,12 +9069,12 @@ const Chart = react.memo(({ config, element, elementConfig, type, renderElement
|
|
|
8492
9069
|
return (jsxRuntime.jsxs(ChartTooltipRow, { children: [jsxRuntime.jsx(ChartLegendColor$1, { "$color": stroke }), jsxRuntime.jsx(ChartLegendValue, { children: attribute ? formatAttributeValue({ t, type: attribute.type, value, stringFormat: attribute.stringFormat }) : value })] }, index));
|
|
8493
9070
|
})] }) }));
|
|
8494
9071
|
}, [labels, layerInfos]);
|
|
8495
|
-
const markers =
|
|
8496
|
-
const formatTooltipName =
|
|
8497
|
-
const formatTooltipValue =
|
|
9072
|
+
const markers = React.useMemo(() => getChartMarkers(data[0]?.items, configMarkers), [data, configMarkers]);
|
|
9073
|
+
const formatTooltipName = React.useCallback((name) => (isRelated ? name : tooltipNameFromAttributes(name, formattedAttributes)), [formattedAttributes, isRelated]);
|
|
9074
|
+
const formatTooltipValue = React.useCallback((value, name) => isRelated
|
|
8498
9075
|
? tooltipValueFromRelatedFeatures(t, value, relatedAttributes, data[0]?.layerInfo)
|
|
8499
9076
|
: tooltipValueFromAttributes(t, value, name, formattedAttributes), [data, formattedAttributes, isRelated, relatedAttributes]);
|
|
8500
|
-
const renderChart =
|
|
9077
|
+
const renderChart = React.useMemo(() => {
|
|
8501
9078
|
if (!element)
|
|
8502
9079
|
return null;
|
|
8503
9080
|
if (isLineChart) {
|
|
@@ -8588,7 +9165,7 @@ const Chart = react.memo(({ config, element, elementConfig, type, renderElement
|
|
|
8588
9165
|
const ChartLegend = ({ data, chartElement, type, twoColumns, loading }) => {
|
|
8589
9166
|
const { t } = useGlobalContext();
|
|
8590
9167
|
const { sliceItems, showMore, onShowMore } = useShownOtherItems(chartElement?.options);
|
|
8591
|
-
const axes =
|
|
9168
|
+
const axes = React.useMemo(() => chartElement?.options?.relatedDataSources?.filter(({ chartAxis }) => chartAxis === "y"), [chartElement?.options?.relatedDataSources]);
|
|
8592
9169
|
const { isFiltered, hasAnyFilter, onFilter } = useFeatureFilters(type, axes?.[0]?.filterName);
|
|
8593
9170
|
const { fontColor, shownItems, hideEmpty } = chartElement?.options || {};
|
|
8594
9171
|
const showMoreBtn = !!shownItems && data.length > shownItems;
|
|
@@ -8597,7 +9174,7 @@ const ChartLegend = ({ data, chartElement, type, twoColumns, loading }) => {
|
|
|
8597
9174
|
return (jsxRuntime.jsxs(uilibGl.Flex, { opacity: loading ? FILTERED_VALUE_OPACITY / 100 : 1, children: [jsxRuntime.jsx(ChartLegendContainer, { twoColumns: twoColumns, children: sliceItems(data)?.map(({ name, color }, index) => (jsxRuntime.jsxs(ChartLegendItem, { hasAnyFilter: hasAnyFilter, isFiltered: isFiltered(name), onClick: axes?.[0]?.filterName ? () => onFilter(name) : undefined, children: [jsxRuntime.jsx(ChartLegendColor, { color: color }), jsxRuntime.jsx(ChartLegendName, { "$fontColor": fontColor, children: name })] }, index))) }), showMoreBtn && (jsxRuntime.jsx(uilibGl.LegendToggler, { onClick: onShowMore, toggled: showMore, children: t("other", { ns: "dashboard" }) }))] }));
|
|
8598
9175
|
};
|
|
8599
9176
|
|
|
8600
|
-
const ContainerChildren =
|
|
9177
|
+
const ContainerChildren = React.memo(({ items, isColumn, isMain, renderElement }) => {
|
|
8601
9178
|
return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: items
|
|
8602
9179
|
?.filter(item => !["title", "icon", "titleIcon"].includes(item.id))
|
|
8603
9180
|
?.map((item, index) => {
|
|
@@ -8606,19 +9183,19 @@ const ContainerChildren = react.memo(({ items, isColumn, isMain, renderElement }
|
|
|
8606
9183
|
index,
|
|
8607
9184
|
wrap: isColumn || isMain,
|
|
8608
9185
|
});
|
|
8609
|
-
return isMain ? (jsxRuntime.jsx(ContainerWrapper, { "data-id": item.id, "data-templatename": item.templateName, children: jsxRuntime.jsx(DashboardWrapper, { children: render }) }, index)) : (jsxRuntime.jsx(
|
|
9186
|
+
return isMain ? (jsxRuntime.jsx(ContainerWrapper, { "data-id": item.id, "data-templatename": item.templateName, children: jsxRuntime.jsx(DashboardWrapper, { children: render }) }, index)) : (jsxRuntime.jsx(React.Fragment, { children: render }, index));
|
|
8610
9187
|
}) }));
|
|
8611
9188
|
});
|
|
8612
9189
|
|
|
8613
|
-
const DashboardLoading =
|
|
9190
|
+
const DashboardLoading = React.memo(() => {
|
|
8614
9191
|
return (jsxRuntime.jsx(ContainerWrapper, { children: jsxRuntime.jsx(DashboardWrapper, { children: jsxRuntime.jsx(DashboardPlaceholderWrap, { children: jsxRuntime.jsxs(DashboardPlaceholder, { isLoading: true, children: [jsxRuntime.jsx(uilibGl.Icon, { kind: "dashboard_loading" }), jsxRuntime.jsx(uilibGl.Flex, { width: "8rem", children: jsxRuntime.jsx(uilibGl.LinearProgress, {}) })] }) }) }) }));
|
|
8615
9192
|
});
|
|
8616
9193
|
|
|
8617
|
-
const Dashboard =
|
|
9194
|
+
const Dashboard = React.memo(({ type = exports.WidgetType.Dashboard, config }) => {
|
|
8618
9195
|
const { dataSources, isLoading } = useWidgetContext(type);
|
|
8619
9196
|
const { currentPage } = useWidgetPage();
|
|
8620
9197
|
const isDiffPage = useDiffPage(type);
|
|
8621
|
-
const dataSourceLoading =
|
|
9198
|
+
const dataSourceLoading = React.useMemo(() => currentPage?.dataSources?.length && !dataSources?.length && isLoading, [currentPage?.dataSources?.length, dataSources?.length, isLoading]);
|
|
8622
9199
|
if (dataSourceLoading || isDiffPage) {
|
|
8623
9200
|
return (jsxRuntime.jsx(DashboardLoading, {}));
|
|
8624
9201
|
}
|
|
@@ -8635,12 +9212,18 @@ const DashboardCheckbox = ({ title, checked, onChange, }) => {
|
|
|
8635
9212
|
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(AttributeLabel, { isEdit: !!onChange, forCheckbox: !!onChange, children: title }), onChange ? jsxRuntime.jsx(CardCheckbox, { checked: checked, label: label, onChange: onChange }) : label] }));
|
|
8636
9213
|
};
|
|
8637
9214
|
|
|
9215
|
+
const DashboardHeader = React.memo(() => {
|
|
9216
|
+
const { currentPage } = useWidgetPage();
|
|
9217
|
+
const HeaderTemplate = React.useMemo(() => getDashboardHeader(currentPage?.header?.templateName), [currentPage?.header?.templateName]);
|
|
9218
|
+
return jsxRuntime.jsx(HeaderTemplate, {});
|
|
9219
|
+
});
|
|
9220
|
+
|
|
8638
9221
|
const DataSourceError = ({ name }) => {
|
|
8639
9222
|
const { t } = useGlobalContext();
|
|
8640
9223
|
return (jsxRuntime.jsxs(DataSourceErrorContainer, { children: [jsxRuntime.jsx(uilibGl.Icon, { kind: "alert" }), jsxRuntime.jsxs("div", { children: [t("block", { ns: "dashboard" }), " \"", name, "\" ", t("isNotLoaded", { ns: "dashboard" })] })] }));
|
|
8641
9224
|
};
|
|
8642
9225
|
|
|
8643
|
-
const ExpandableTitle =
|
|
9226
|
+
const ExpandableTitle = React.memo(({ elementConfig, type, renderElement }) => {
|
|
8644
9227
|
const { expandedContainers } = useWidgetContext(type);
|
|
8645
9228
|
const { id, options, templateName, children } = elementConfig || {};
|
|
8646
9229
|
const { expandable, fontColor, expanded, layerNames } = options || {};
|
|
@@ -8651,6 +9234,50 @@ const ExpandableTitle = react.memo(({ elementConfig, type, renderElement }) => {
|
|
|
8651
9234
|
return (jsxRuntime.jsx(TitleContainer, { containerId: id, elementConfig: titleElement, templateName: templateName, layerNames: layerNames, fontColor: fontColor, expandable: expandable, expanded: expanded, type: type, isVisible: isVisible, renderElement: renderElement }));
|
|
8652
9235
|
});
|
|
8653
9236
|
|
|
9237
|
+
const FeatureCardButtons = () => {
|
|
9238
|
+
const { closeFeatureCard } = useWidgetContext(exports.WidgetType.FeatureCard);
|
|
9239
|
+
return (jsxRuntime.jsx(uilibGl.FlexSpan, { children: jsxRuntime.jsx(uilibGl.IconButton, { kind: "close", style: {
|
|
9240
|
+
padding: 0,
|
|
9241
|
+
width: "1rem",
|
|
9242
|
+
}, onClick: closeFeatureCard }) }));
|
|
9243
|
+
};
|
|
9244
|
+
|
|
9245
|
+
const FeatureCardHeader = () => {
|
|
9246
|
+
const { currentPage } = useWidgetPage(exports.WidgetType.FeatureCard);
|
|
9247
|
+
const HeaderTemplate = getFeatureCardHeader(currentPage?.header?.templateName);
|
|
9248
|
+
return jsxRuntime.jsx(HeaderTemplate, {});
|
|
9249
|
+
};
|
|
9250
|
+
|
|
9251
|
+
const FeatureCardTitle = ({ title, description }) => {
|
|
9252
|
+
const { t } = useGlobalContext();
|
|
9253
|
+
const { attributes, layerInfo, feature } = useWidgetContext(exports.WidgetType.FeatureCard);
|
|
9254
|
+
const zoomToFeatures = useZoomToFeatures();
|
|
9255
|
+
const { alias, name, layerDefinition, titleAttribute } = layerInfo || {};
|
|
9256
|
+
const resultDescription = description || alias || name || "";
|
|
9257
|
+
const resultTitle = React.useMemo(() => {
|
|
9258
|
+
const layerDefinitionAttribute = layerDefinition && attributes?.length
|
|
9259
|
+
? attributes.find(item => item.name === layerDefinition.titleAttribute)
|
|
9260
|
+
: null;
|
|
9261
|
+
const layerDefinitionTitle = layerDefinition?.titleAttribute && layerDefinitionAttribute?.value
|
|
9262
|
+
? layerDefinitionAttribute.value
|
|
9263
|
+
: null;
|
|
9264
|
+
const sourceTitleAttribute = titleAttribute && attributes?.length ? attributes.find(item => item.name === titleAttribute) : null;
|
|
9265
|
+
const sourceTitle = titleAttribute && sourceTitleAttribute?.value ? sourceTitleAttribute.value : null;
|
|
9266
|
+
return (title ||
|
|
9267
|
+
(!!sourceTitle &&
|
|
9268
|
+
formatAttributeValue({ t, type: sourceTitleAttribute.type, value: sourceTitle, stringFormat: sourceTitleAttribute.stringFormat })) ||
|
|
9269
|
+
(!!layerDefinitionTitle &&
|
|
9270
|
+
formatAttributeValue({
|
|
9271
|
+
t,
|
|
9272
|
+
type: layerDefinitionAttribute.type,
|
|
9273
|
+
value: layerDefinitionTitle,
|
|
9274
|
+
stringFormat: layerDefinitionAttribute.stringFormat,
|
|
9275
|
+
})) ||
|
|
9276
|
+
feature?.id);
|
|
9277
|
+
}, [attributes, feature?.id, layerDefinition, title, titleAttribute]);
|
|
9278
|
+
return (jsxRuntime.jsxs(HeaderTitleContainer, { children: [jsxRuntime.jsx(FeatureTitleContainer, { clickable: true, children: jsxRuntime.jsx(uilibGl.Tooltip, { arrow: true, placement: "top", content: t("zoomToFeature", { ns: "dashboard" }), delay: [600, 0], children: ref => (jsxRuntime.jsx(uilibGl.FlexSpan, { ref: ref, onClick: () => zoomToFeatures([feature]), children: resultTitle })) }) }), jsxRuntime.jsx(LayerDescription, { title: resultDescription, children: resultDescription })] }));
|
|
9279
|
+
};
|
|
9280
|
+
|
|
8654
9281
|
const HiddenFilters = styled(uilibGl.Flex) `
|
|
8655
9282
|
flex-wrap: wrap;
|
|
8656
9283
|
margin-top: -1.25rem;
|
|
@@ -8673,15 +9300,15 @@ function isIsoDate(value) {
|
|
|
8673
9300
|
const d = new Date(value);
|
|
8674
9301
|
return !isNaN(d.getTime());
|
|
8675
9302
|
}
|
|
8676
|
-
const HiddenTitleItems =
|
|
9303
|
+
const HiddenTitleItems = React.memo(({ elementConfig, config, type, filter }) => {
|
|
8677
9304
|
const { filters, dataSources, changeFilters, expandedContainers } = useWidgetContext(type);
|
|
8678
9305
|
const { filters: configFilters } = config || {};
|
|
8679
9306
|
const { id, options, children } = elementConfig || {};
|
|
8680
9307
|
const { fontColor, expandable, expanded } = options || {};
|
|
8681
9308
|
const isVisible = isVisibleContainer(id, expandable, expanded, expandedContainers);
|
|
8682
|
-
const filterItems =
|
|
8683
|
-
const configFilter =
|
|
8684
|
-
const clearFilter =
|
|
9309
|
+
const filterItems = React.useMemo(() => children?.filter(child => child.options?.filterName), [children]);
|
|
9310
|
+
const configFilter = React.useMemo(() => getConfigFilter(filter, configFilters), [configFilters, filter]);
|
|
9311
|
+
const clearFilter = React.useCallback((name, value) => {
|
|
8685
9312
|
changeFilters({
|
|
8686
9313
|
[name]: {
|
|
8687
9314
|
value: value &&
|
|
@@ -8693,26 +9320,26 @@ const HiddenTitleItems = react.memo(({ elementConfig, config, type, filter }) =>
|
|
|
8693
9320
|
},
|
|
8694
9321
|
}, configFilter?.resetFilters);
|
|
8695
9322
|
}, [changeFilters, configFilter?.resetFilters, configFilter?.valueType, filters]);
|
|
8696
|
-
const selectedItems =
|
|
8697
|
-
const isLoading =
|
|
9323
|
+
const selectedItems = React.useMemo(() => getFilterSelectedItems(filterItems, filters, configFilters), [configFilters, filters, filterItems]);
|
|
9324
|
+
const isLoading = React.useMemo(() => elementConfig?.children?.some(child => {
|
|
8698
9325
|
const currentFilter = configFilters?.find(({ name }) => name === child.options?.filterName);
|
|
8699
9326
|
return (!!currentFilter &&
|
|
8700
9327
|
!!child.options?.filterName &&
|
|
8701
9328
|
!dataSources?.some(({ name }) => name === currentFilter.relatedDataSource));
|
|
8702
9329
|
}), [configFilters, dataSources, elementConfig?.children]);
|
|
8703
|
-
const chipProps =
|
|
9330
|
+
const chipProps = React.useMemo(() => ({
|
|
8704
9331
|
$fontSize: "0.75rem",
|
|
8705
9332
|
$fontColor: fontColor,
|
|
8706
9333
|
$bgColor: fontColor ? transparentizeColor(fontColor, 6) : null,
|
|
8707
9334
|
$radius: "0.25rem",
|
|
8708
9335
|
}), [fontColor]);
|
|
8709
|
-
const formatValue =
|
|
9336
|
+
const formatValue = React.useCallback((value) => {
|
|
8710
9337
|
return typeof value === "object" ? uilibGl.dateFormat(value) : isIsoDate(value) ? uilibGl.dateFormat(new Date(value)) : value;
|
|
8711
9338
|
}, []);
|
|
8712
|
-
const formatJoin =
|
|
9339
|
+
const formatJoin = React.useCallback((valueType) => {
|
|
8713
9340
|
return valueType === "range" ? " - " : ", ";
|
|
8714
9341
|
}, []);
|
|
8715
|
-
const renderItem =
|
|
9342
|
+
const renderItem = React.useCallback((filterName, value, index) => {
|
|
8716
9343
|
return (jsxRuntime.jsxs(DashboardChip$1, { ...chipProps, children: [value, " ", jsxRuntime.jsx(uilibGl.IconButton, { kind: "close", onClick: () => clearFilter(filterName, value) })] }, index));
|
|
8717
9344
|
}, [chipProps, clearFilter]);
|
|
8718
9345
|
if (isLoading || isVisible || !selectedItems.length)
|
|
@@ -8749,7 +9376,7 @@ const PageNavigator = styled(uilibGl.Flex) `
|
|
|
8749
9376
|
}
|
|
8750
9377
|
`;
|
|
8751
9378
|
|
|
8752
|
-
const Pagination =
|
|
9379
|
+
const Pagination = React.memo(({ type = exports.WidgetType.Dashboard }) => {
|
|
8753
9380
|
const { nextPage, prevPage } = useWidgetContext(type);
|
|
8754
9381
|
const { pages } = useWidgetConfig(type);
|
|
8755
9382
|
return (jsxRuntime.jsxs(PageNavigator, { children: [jsxRuntime.jsx(uilibGl.IconButton, { kind: "prev", onClick: () => prevPage(pages.length) }), jsxRuntime.jsx(uilibGl.IconButton, { kind: "next", onClick: () => nextPage(pages.length) })] }));
|
|
@@ -8784,10 +9411,10 @@ const StyledSvg = styled.div `
|
|
|
8784
9411
|
${({ $fontColor }) => !!$fontColor && StyledSvgColorMixin};
|
|
8785
9412
|
`;
|
|
8786
9413
|
|
|
8787
|
-
const SvgImage =
|
|
8788
|
-
const [svg, setSvg] =
|
|
8789
|
-
const [loading, setLoading] =
|
|
8790
|
-
|
|
9414
|
+
const SvgImage = React.memo(({ url, width, height, fontColor }) => {
|
|
9415
|
+
const [svg, setSvg] = React.useState(null);
|
|
9416
|
+
const [loading, setLoading] = React.useState(false);
|
|
9417
|
+
React.useEffect(() => {
|
|
8791
9418
|
if (!url || loading) {
|
|
8792
9419
|
return;
|
|
8793
9420
|
}
|
|
@@ -8799,7 +9426,7 @@ const SvgImage = react.memo(({ url, width, height, fontColor }) => {
|
|
|
8799
9426
|
setLoading(false);
|
|
8800
9427
|
});
|
|
8801
9428
|
}, [url]);
|
|
8802
|
-
|
|
9429
|
+
React.useEffect(() => () => {
|
|
8803
9430
|
setSvg(null);
|
|
8804
9431
|
}, []);
|
|
8805
9432
|
if (!svg?.endsWith("</svg>"))
|
|
@@ -8807,11 +9434,11 @@ const SvgImage = react.memo(({ url, width, height, fontColor }) => {
|
|
|
8807
9434
|
return (jsxRuntime.jsx(StyledSvg, { "$width": width, "$height": height, "$fontColor": fontColor, dangerouslySetInnerHTML: { __html: svg } }));
|
|
8808
9435
|
});
|
|
8809
9436
|
|
|
8810
|
-
const TextTrim =
|
|
9437
|
+
const TextTrim = React.memo(({ maxLength, expandable, lineBreak, children }) => {
|
|
8811
9438
|
const { t } = useGlobalContext();
|
|
8812
9439
|
const [expanded, toggleExpanded] = useToggle();
|
|
8813
9440
|
const text = children?.toString();
|
|
8814
|
-
const formatValue =
|
|
9441
|
+
const formatValue = React.useCallback((value) => {
|
|
8815
9442
|
if (!lineBreak)
|
|
8816
9443
|
return value;
|
|
8817
9444
|
return jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: lodash.unescape(value).split(lineBreak).join("<br />") } });
|
|
@@ -8884,7 +9511,7 @@ const getClientStyleItemPrefixSuffix = (geometryType, type) => {
|
|
|
8884
9511
|
const VectorLayer = ({ layer, tileUrl, visible, beforeId, getLayerTempStyle, }) => {
|
|
8885
9512
|
const clientStyle = layer?.configuration?.clientStyle;
|
|
8886
9513
|
const { idAttribute, geometryType } = layer.layerDefinition || {};
|
|
8887
|
-
const renderLayerByGeometryType =
|
|
9514
|
+
const renderLayerByGeometryType = React.useCallback(() => {
|
|
8888
9515
|
const visibility = visible ? "visible" : "none";
|
|
8889
9516
|
switch (geometryType) {
|
|
8890
9517
|
case api.GeometryType.Point:
|
|
@@ -8951,7 +9578,7 @@ const VectorLayer = ({ layer, tileUrl, visible, beforeId, getLayerTempStyle, })
|
|
|
8951
9578
|
visible,
|
|
8952
9579
|
getLayerTempStyle,
|
|
8953
9580
|
]);
|
|
8954
|
-
const renderClientStyle =
|
|
9581
|
+
const renderClientStyle = React.useCallback(() => {
|
|
8955
9582
|
return clientStyle.items.map(mockItem => {
|
|
8956
9583
|
const prefixSuffix = getClientStyleItemPrefixSuffix(geometryType, mockItem.type);
|
|
8957
9584
|
const isExtrusionItem = mockItem.type === "fill-extrusion";
|
|
@@ -8999,7 +9626,7 @@ const VectorLayer = ({ layer, tileUrl, visible, beforeId, getLayerTempStyle, })
|
|
|
8999
9626
|
};
|
|
9000
9627
|
|
|
9001
9628
|
const Layer = ({ layer, layerType, visible, beforeId, tileUrl, getLayerTempStyle, onMount = () => null, }) => {
|
|
9002
|
-
|
|
9629
|
+
React.useEffect(onMount, []); // eslint-disable-line
|
|
9003
9630
|
if (!layer) {
|
|
9004
9631
|
return null;
|
|
9005
9632
|
}
|
|
@@ -9042,23 +9669,6 @@ const Map$1 = ({ zIndex, lowerSiblings, upperSiblings, onError, children, ...res
|
|
|
9042
9669
|
}, children: children }), upperSiblings] }));
|
|
9043
9670
|
};
|
|
9044
9671
|
|
|
9045
|
-
exports.ThemeName = void 0;
|
|
9046
|
-
(function (ThemeName) {
|
|
9047
|
-
ThemeName["Light"] = "light";
|
|
9048
|
-
ThemeName["Dark"] = "dark";
|
|
9049
|
-
})(exports.ThemeName || (exports.ThemeName = {}));
|
|
9050
|
-
|
|
9051
|
-
exports.TmsType = void 0;
|
|
9052
|
-
(function (TmsType) {
|
|
9053
|
-
TmsType["WMS"] = "WMS";
|
|
9054
|
-
TmsType["TMS"] = "TMS";
|
|
9055
|
-
TmsType["ArcGIS"] = "ArcGIS";
|
|
9056
|
-
})(exports.TmsType || (exports.TmsType = {}));
|
|
9057
|
-
exports.EditGeometryType = void 0;
|
|
9058
|
-
(function (EditGeometryType) {
|
|
9059
|
-
EditGeometryType["Raster"] = "raster";
|
|
9060
|
-
})(exports.EditGeometryType || (exports.EditGeometryType = {}));
|
|
9061
|
-
|
|
9062
9672
|
exports.AddFeatureButton = AddFeatureButton;
|
|
9063
9673
|
exports.AddFeatureContainer = AddFeatureContainer;
|
|
9064
9674
|
exports.AttributeGalleryContainer = AttributeGalleryContainer;
|
|
@@ -9099,6 +9709,8 @@ exports.DashboardCheckbox = DashboardCheckbox;
|
|
|
9099
9709
|
exports.DashboardChip = DashboardChip;
|
|
9100
9710
|
exports.DashboardContent = DashboardContent;
|
|
9101
9711
|
exports.DashboardContext = DashboardContext;
|
|
9712
|
+
exports.DashboardDefaultHeader = DashboardDefaultHeader;
|
|
9713
|
+
exports.DashboardHeader = DashboardHeader;
|
|
9102
9714
|
exports.DashboardPlaceholder = DashboardPlaceholder;
|
|
9103
9715
|
exports.DashboardPlaceholderWrap = DashboardPlaceholderWrap;
|
|
9104
9716
|
exports.DashboardProvider = DashboardProvider;
|
|
@@ -9109,6 +9721,7 @@ exports.DataSourceErrorContainer = DataSourceErrorContainer;
|
|
|
9109
9721
|
exports.DataSourceInnerContainer = DataSourceInnerContainer;
|
|
9110
9722
|
exports.DataSourceProgressContainer = DataSourceProgressContainer;
|
|
9111
9723
|
exports.DefaultAttributesContainer = DefaultAttributesContainer;
|
|
9724
|
+
exports.DefaultHeaderContainer = DefaultHeaderContainer;
|
|
9112
9725
|
exports.DividerContainer = DividerContainer;
|
|
9113
9726
|
exports.ElementButton = ElementButton;
|
|
9114
9727
|
exports.ElementCamera = ElementCamera;
|
|
@@ -9127,24 +9740,40 @@ exports.FEATURE_CARD_DEFAULT_COLORS = FEATURE_CARD_DEFAULT_COLORS;
|
|
|
9127
9740
|
exports.FEATURE_CARD_OTHER_COLOR = FEATURE_CARD_OTHER_COLOR;
|
|
9128
9741
|
exports.FILTERED_VALUE_OPACITY = FILTERED_VALUE_OPACITY;
|
|
9129
9742
|
exports.FILTER_PREFIX = FILTER_PREFIX;
|
|
9743
|
+
exports.FeatureCardButtons = FeatureCardButtons;
|
|
9130
9744
|
exports.FeatureCardContext = FeatureCardContext;
|
|
9745
|
+
exports.FeatureCardDefaultHeader = FeatureCardDefaultHeader;
|
|
9746
|
+
exports.FeatureCardGradientHeader = FeatureCardGradientHeader;
|
|
9747
|
+
exports.FeatureCardHeader = FeatureCardHeader;
|
|
9748
|
+
exports.FeatureCardIconHeader = FeatureCardIconHeader;
|
|
9131
9749
|
exports.FeatureCardProvider = FeatureCardProvider;
|
|
9750
|
+
exports.FeatureCardSlideshowHeader = FeatureCardSlideshowHeader;
|
|
9751
|
+
exports.FeatureCardTitle = FeatureCardTitle;
|
|
9752
|
+
exports.FeatureControls = FeatureControls;
|
|
9753
|
+
exports.FeatureTitleContainer = FeatureTitleContainer;
|
|
9132
9754
|
exports.FiltersContainer = FiltersContainer;
|
|
9133
9755
|
exports.GEOMETRY_ATTRIBUTE = GEOMETRY_ATTRIBUTE;
|
|
9134
9756
|
exports.GlobalContext = GlobalContext;
|
|
9135
9757
|
exports.GlobalProvider = GlobalProvider;
|
|
9758
|
+
exports.Header = Header;
|
|
9759
|
+
exports.HeaderContainer = HeaderContainer;
|
|
9760
|
+
exports.HeaderFrontView = HeaderFrontView;
|
|
9761
|
+
exports.HeaderTitleContainer = HeaderTitleContainer;
|
|
9136
9762
|
exports.HiddenTitleItems = HiddenTitleItems;
|
|
9137
9763
|
exports.IconContainer = IconContainer;
|
|
9138
9764
|
exports.ImageContainer = ImageContainer;
|
|
9139
9765
|
exports.LEFT_PANEL_HEADER_HEIGHT = LEFT_PANEL_HEADER_HEIGHT;
|
|
9140
9766
|
exports.Layer = Layer;
|
|
9767
|
+
exports.LayerDescription = LayerDescription;
|
|
9141
9768
|
exports.LayerGroup = LayerGroup;
|
|
9142
9769
|
exports.LayerGroupList = LayerGroupList;
|
|
9770
|
+
exports.LayerIcon = LayerIcon;
|
|
9143
9771
|
exports.LayerListContainer = LayerListContainer;
|
|
9144
9772
|
exports.LayerTree = LayerTree;
|
|
9145
9773
|
exports.LayersContainer = LayersContainer;
|
|
9146
9774
|
exports.LayersListWrapper = LayersListWrapper;
|
|
9147
9775
|
exports.LinearProgressContainer = LinearProgressContainer;
|
|
9776
|
+
exports.LogoContainer = LogoContainer;
|
|
9148
9777
|
exports.MAX_CHART_WIDTH = MAX_CHART_WIDTH;
|
|
9149
9778
|
exports.Map = Map$1;
|
|
9150
9779
|
exports.MapContext = MapContext;
|
|
@@ -9154,6 +9783,7 @@ exports.NUMERIC_ATTRIBUTE_TYPES = NUMERIC_ATTRIBUTE_TYPES;
|
|
|
9154
9783
|
exports.NoLiveSnapshotContainer = NoLiveSnapshotContainer;
|
|
9155
9784
|
exports.OneColumnContainer = OneColumnContainer;
|
|
9156
9785
|
exports.PageNavigator = PageNavigator;
|
|
9786
|
+
exports.PageTitle = PageTitle;
|
|
9157
9787
|
exports.PagesContainer = PagesContainer;
|
|
9158
9788
|
exports.Pagination = Pagination;
|
|
9159
9789
|
exports.PresentationHeader = PresentationHeader;
|
|
@@ -9167,7 +9797,7 @@ exports.RoundedBackgroundContainer = RoundedBackgroundContainer;
|
|
|
9167
9797
|
exports.ServerNotificationsContext = ServerNotificationsContext;
|
|
9168
9798
|
exports.ServerNotificationsProvider = ServerNotificationsProvider;
|
|
9169
9799
|
exports.SlideshowContainer = SlideshowContainer;
|
|
9170
|
-
exports.SmallPreviewContainer = SmallPreviewContainer;
|
|
9800
|
+
exports.SmallPreviewContainer = SmallPreviewContainer$1;
|
|
9171
9801
|
exports.SmallPreviewControl = SmallPreviewControl;
|
|
9172
9802
|
exports.SmallPreviewCounter = SmallPreviewCounter;
|
|
9173
9803
|
exports.SmallPreviewImages = SmallPreviewImages;
|
|
@@ -9179,6 +9809,8 @@ exports.TIME_ZONE_FORMAT = TIME_ZONE_FORMAT;
|
|
|
9179
9809
|
exports.TabsContainer = TabsContainer;
|
|
9180
9810
|
exports.TextTrim = TextTrim;
|
|
9181
9811
|
exports.TitleContainer = TitleContainer;
|
|
9812
|
+
exports.TopContainer = TopContainer;
|
|
9813
|
+
exports.TopContainerButtons = TopContainerButtons;
|
|
9182
9814
|
exports.TwoColumnContainer = TwoColumnContainer;
|
|
9183
9815
|
exports.TwoColumnsInnerContainer = TwoColumnsInnerContainer;
|
|
9184
9816
|
exports.addDataSource = addDataSource;
|
|
@@ -9216,6 +9848,7 @@ exports.getChartFilterName = getChartFilterName;
|
|
|
9216
9848
|
exports.getChartMarkers = getChartMarkers;
|
|
9217
9849
|
exports.getConfigFilter = getConfigFilter;
|
|
9218
9850
|
exports.getContainerComponent = getContainerComponent;
|
|
9851
|
+
exports.getDashboardHeader = getDashboardHeader;
|
|
9219
9852
|
exports.getDataFromAttributes = getDataFromAttributes;
|
|
9220
9853
|
exports.getDataFromRelatedFeatures = getDataFromRelatedFeatures;
|
|
9221
9854
|
exports.getDataSource = getDataSource;
|
|
@@ -9224,6 +9857,7 @@ exports.getDate = getDate;
|
|
|
9224
9857
|
exports.getDefaultConfig = getDefaultConfig;
|
|
9225
9858
|
exports.getElementValue = getElementValue;
|
|
9226
9859
|
exports.getFeatureAttributes = getFeatureAttributes;
|
|
9860
|
+
exports.getFeatureCardHeader = getFeatureCardHeader;
|
|
9227
9861
|
exports.getFilterComponent = getFilterComponent;
|
|
9228
9862
|
exports.getFilterSelectedItems = getFilterSelectedItems;
|
|
9229
9863
|
exports.getFilterValue = getFilterValue;
|
|
@@ -9275,6 +9909,7 @@ exports.useExpandableContainers = useExpandableContainers;
|
|
|
9275
9909
|
exports.useFeatureFilters = useFeatureFilters;
|
|
9276
9910
|
exports.useGetConfigLayer = useGetConfigLayer;
|
|
9277
9911
|
exports.useGlobalContext = useGlobalContext;
|
|
9912
|
+
exports.useHeaderRender = useHeaderRender;
|
|
9278
9913
|
exports.useLayerParams = useLayerParams;
|
|
9279
9914
|
exports.useMapContext = useMapContext;
|
|
9280
9915
|
exports.useMapDraw = useMapDraw;
|