@geo2france/api-dashboard 1.8.0 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/components/Attributions/Attributions.js +7 -7
  2. package/dist/components/Charts/Pie.js +3 -6
  3. package/dist/components/Charts/Statistics.d.ts +64 -0
  4. package/dist/components/Charts/Statistics.js +61 -0
  5. package/dist/components/Charts/YearSerie.js +3 -6
  6. package/dist/components/Control/Select.js +4 -3
  7. package/dist/components/DashboardElement/DashboardElement.js +2 -3
  8. package/dist/components/DashboardPage/Block.d.ts +1 -0
  9. package/dist/components/DashboardPage/Block.js +12 -5
  10. package/dist/components/DashboardPage/Page.d.ts +1 -0
  11. package/dist/components/Dataset/Dataset.js +1 -1
  12. package/dist/components/Dataset/hooks.d.ts +3 -0
  13. package/dist/components/Debug/Debug.js +2 -2
  14. package/dist/components/FlipCard/FlipCard.js +2 -2
  15. package/dist/components/Layout/Sider.js +2 -2
  16. package/dist/components/LoadingContainer/LoadingContainer.js +2 -2
  17. package/dist/components/Map/Map.d.ts +59 -0
  18. package/dist/components/Map/Map.js +147 -0
  19. package/dist/components/MapLegend/MapLegend.d.ts +6 -0
  20. package/dist/components/MapLegend/MapLegend.js +29 -0
  21. package/dist/components/NextPrevSelect/NextPrevSelect.js +1 -1
  22. package/dist/dsl/index.d.ts +4 -1
  23. package/dist/dsl/index.js +4 -1
  24. package/dist/utils/parsers.d.ts +2 -0
  25. package/dist/utils/parsers.js +14 -0
  26. package/dist/utils/useMapControl.d.ts +3 -0
  27. package/dist/utils/useMapControl.js +3 -0
  28. package/package.json +15 -6
  29. package/dist/data_providers/wfs/utils/mapOperator.d.ts +0 -1
  30. package/dist/data_providers/wfs/utils/mapOperator.js +0 -36
@@ -1,21 +1,21 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Tooltip, Typography } from 'antd';
3
- import { FaCreativeCommons, FaCreativeCommonsBy, FaCreativeCommonsNc, FaCreativeCommonsPd, FaCreativeCommonsSa, FaCreativeCommonsZero } from 'react-icons/fa';
3
+ import { Icon } from '@iconify/react';
4
4
  const { Text, Link } = Typography;
5
5
  const LogoLicence = ({ license, style }) => {
6
6
  switch (license) {
7
7
  case "CC":
8
- return _jsx(FaCreativeCommons, { style: style });
8
+ return _jsx(Icon, { icon: "cib:creative-commons", style: style });
9
9
  case "BY":
10
- return _jsx(FaCreativeCommonsBy, { style: style });
10
+ return _jsx(Icon, { icon: "cib:creative-commons-by", style: style });
11
11
  case "NC":
12
- return _jsx(FaCreativeCommonsNc, { style: style });
12
+ return _jsx(Icon, { icon: "cib:creative-commons-nc", style: style });
13
13
  case "PD":
14
- return _jsx(FaCreativeCommonsPd, { style: style });
14
+ return _jsx(Icon, { icon: "cib:creative-commons-pd", style: style });
15
15
  case "SA":
16
- return _jsx(FaCreativeCommonsSa, { style: style });
16
+ return _jsx(Icon, { icon: "cib:creative-commons-sa", style: style });
17
17
  case "ZERO":
18
- return _jsx(FaCreativeCommonsZero, { style: style });
18
+ return _jsx(Icon, { icon: "cib:creative-commons-zero", style: style });
19
19
  }
20
20
  };
21
21
  const Attribution = ({ data, style, licenses }) => {
@@ -1,20 +1,17 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { useContext, useEffect } from "react";
3
2
  import { useDataset } from "../Dataset/hooks";
4
- import { ChartBlockContext } from "../DashboardPage/Block";
5
3
  import { usePalette } from "../Palette/Palette";
6
4
  import { from, op } from "arquero";
7
5
  import { ChartEcharts } from "./ChartEcharts";
8
6
  import { merge_others } from "../..";
7
+ import { useBlockConfig } from "../DashboardPage/Block";
9
8
  export const ChartPie = ({ dataset: dataset_id, nameKey, dataKey, unit, title, donut = false, other = 5 }) => {
10
9
  const dataset = useDataset(dataset_id);
11
- const blockConfig = useContext(ChartBlockContext);
12
10
  const data = dataset?.data;
13
- const block_config = {
11
+ useBlockConfig({
14
12
  title: title,
15
13
  dataExport: data
16
- };
17
- useEffect(() => blockConfig?.setConfig(block_config), [data]);
14
+ });
18
15
  const chart_data1 = data && data.length > 0
19
16
  ? from(data)
20
17
  .groupby(nameKey)
@@ -0,0 +1,64 @@
1
+ import { ReactElement } from "react";
2
+ type comparwithType = "first" | "previous";
3
+ interface StatisticsProps {
4
+ /** Identifiant du jeu de données */
5
+ dataset: string;
6
+ /** Nom de la colonne qui contient les valeurs */
7
+ dataKey: string;
8
+ /** Texte à afficher après l'évolution */
9
+ evolutionSuffix?: string;
10
+ /** Afficher l'évolution en % (sinon dans la même unité que la valeur) */
11
+ relativeEvolution?: boolean;
12
+ /** Titre */
13
+ title?: string;
14
+ /** Couleur */
15
+ color?: string;
16
+ /** Unité de la valeur */
17
+ unit?: string;
18
+ /** Inverser les couleurs (rouge/vert) de l'évolution */
19
+ invertColor?: boolean;
20
+ /** Icône (composant ou nom de l'icône sur Iconify.js ) */
21
+ icon?: ReactElement | string;
22
+ /** Texte à afficher dans le tooltip d'aide */
23
+ help?: string;
24
+ /** Comparer la valeur avec la précédente ou la première du jeu de données */
25
+ compareWith?: comparwithType;
26
+ }
27
+ /**
28
+ * Composant `Statistics` affichant une valeur d'un dataset avec son évolution.
29
+ *
30
+ * Affiche :
31
+ * - La dernière valeur du dataset
32
+ * - Unité et picto
33
+ * - Évolution par rapport à la première ou l'avant-dernière valeur
34
+ * - Couleur selon évolution positive/négative
35
+ * - Tooltip d'aide si fourni
36
+ *
37
+ * @param {StatisticsProps} props - Propriétés du composant
38
+ * @returns {ReactElement} Carte statistique
39
+ */
40
+ export declare const Statistics: React.FC<StatisticsProps>;
41
+ type StatisticsCollectionProps = {
42
+ /**
43
+ * Un ou plusieurs composants `<Statistics>`.
44
+ */
45
+ children: ReactElement<typeof Statistics> | ReactElement<typeof Statistics>[];
46
+ /**
47
+ * Nombre de colonnes (défaut : 3)
48
+ */
49
+ columns?: number;
50
+ /**
51
+ * Titre du bloc.
52
+ */
53
+ title?: string;
54
+ };
55
+ /**
56
+ * `StatisticsCollection` permet de regrouper plusieurs cartes statistiques
57
+ * dans un bloc
58
+ *
59
+ * @param {StatisticsProps} props - Propriétés du composant
60
+ * @returns {ReactElement} Collection de cartes statistiques
61
+ * ```
62
+ */
63
+ export declare const StatisticsCollection: React.FC<StatisticsCollectionProps>;
64
+ export {};
@@ -0,0 +1,61 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { QuestionCircleOutlined } from "@ant-design/icons";
3
+ import { Avatar, Card, Col, Flex, Row, Tooltip, Typography } from "antd";
4
+ import { Children } from "react";
5
+ import { useDataset } from "../Dataset/hooks";
6
+ import { Icon } from "@iconify/react";
7
+ import { useBlockConfig } from "../DashboardPage/Block";
8
+ const { Text, Paragraph } = Typography;
9
+ // DEV : modele cf https://bootstrapbrain.com/component/bootstrap-statistics-card-example/
10
+ /**
11
+ * Composant `Statistics` affichant une valeur d'un dataset avec son évolution.
12
+ *
13
+ * Affiche :
14
+ * - La dernière valeur du dataset
15
+ * - Unité et picto
16
+ * - Évolution par rapport à la première ou l'avant-dernière valeur
17
+ * - Couleur selon évolution positive/négative
18
+ * - Tooltip d'aide si fourni
19
+ *
20
+ * @param {StatisticsProps} props - Propriétés du composant
21
+ * @returns {ReactElement} Carte statistique
22
+ */
23
+ export const Statistics = ({ dataset: dataset_id, dataKey, unit, evolutionSuffix, title, icon: icon_input, color, invertColor = false, help, compareWith, relativeEvolution = false }) => {
24
+ const icon = typeof icon_input === "string" ? _jsx(Icon, { icon: icon_input }) : icon_input;
25
+ const dataset = useDataset(dataset_id);
26
+ const value = dataset?.data?.slice(-1)[0][dataKey]; // Dernière valeur du dataset
27
+ const compare_value = compareWith === 'previous' ? dataset?.data?.slice(-2)[0][dataKey] : dataset?.data?.slice(0, 1)[0][dataKey]; //Première ou avant dernière
28
+ const evolution = relativeEvolution ? 100 * ((value - compare_value) / compare_value) : value - compare_value;
29
+ const evolution_unit = relativeEvolution ? '%' : unit;
30
+ const evolution_is_good = invertColor ? evolution < 0 : evolution > 0;
31
+ const tooltip = help && _jsx(Tooltip, { title: help, children: _jsx(QuestionCircleOutlined, {}) });
32
+ return (_jsx(Card, { title: title, style: {
33
+ borderLeft: `4px solid ${color}`,
34
+ height: "100%"
35
+ }, styles: {
36
+ body: {
37
+ padding: 16,
38
+ paddingTop: 8,
39
+ paddingBottom: 8
40
+ },
41
+ header: {
42
+ padding: "5px",
43
+ paddingLeft: "15px",
44
+ fontSize: 14,
45
+ minHeight: 35,
46
+ },
47
+ }, extra: tooltip, children: _jsxs(Flex, { vertical: true, children: [_jsxs(Flex, { justify: "space-between", align: "center", children: [_jsxs(Text, { style: { fontSize: "150%", paddingTop: 8, paddingBottom: 8, paddingLeft: 0 }, children: [value?.toLocaleString(), " ", unit] }), icon && _jsx(Avatar, { size: 32 + 8, icon: icon, style: { backgroundColor: color } })] }), evolution && _jsxs(Paragraph, { style: { marginBottom: "0.5rem" }, children: [_jsxs(Text, { strong: true, type: evolution_is_good ? "success" : "danger", style: { fontSize: "120%" }, children: [evolution < 0.1 ? '' : '+', evolution.toLocaleString(undefined, { maximumFractionDigits: 1 }), "\u00A0", evolution_unit] }), " ", _jsx(Text, { italic: true, type: "secondary", children: evolutionSuffix })] })] }) }));
48
+ };
49
+ /**
50
+ * `StatisticsCollection` permet de regrouper plusieurs cartes statistiques
51
+ * dans un bloc
52
+ *
53
+ * @param {StatisticsProps} props - Propriétés du composant
54
+ * @returns {ReactElement} Collection de cartes statistiques
55
+ * ```
56
+ */
57
+ export const StatisticsCollection = ({ children, columns = 3, title }) => {
58
+ const arrayChildren = Children.toArray(children);
59
+ useBlockConfig({ title: title });
60
+ return (_jsx(Row, { gutter: [8, 8], children: arrayChildren.map((c, index) => (_jsx(Col, { xl: 24 / columns, xs: 24, children: c }, index))) }));
61
+ };
@@ -6,20 +6,17 @@ import { from, op } from "arquero";
6
6
  import { useDataset } from "../Dataset/hooks";
7
7
  import { usePalette } from "../Palette/Palette";
8
8
  import { ChartEcharts } from "./ChartEcharts";
9
- import { useContext, useEffect } from "react";
10
- import { ChartBlockContext } from "../DashboardPage/Block";
9
+ import { useBlockConfig } from "../DashboardPage/Block";
11
10
  export const ChartYearSerie = ({ dataset: dataset_id, categoryKey, valueKey, yearKey, yearMark, stack: stack_input, title, type: chart_type = 'bar' }) => {
12
11
  const stack = stack_input || chart_type == 'line' ? false : true; // Pas de stack par défaut pour le type line
13
12
  const dataset = useDataset(dataset_id);
14
13
  const data = dataset?.data;
15
14
  let chart_data = [];
16
15
  let distinct_cat = [];
17
- const blockConfig = useContext(ChartBlockContext); //TODO : créer un hook pour simplifier la config du block
18
- const block_config = {
16
+ useBlockConfig({
19
17
  title: title,
20
18
  dataExport: data
21
- };
22
- useEffect(() => blockConfig?.setConfig(block_config), [title, data]);
19
+ });
23
20
  if (data && data.length > 0) {
24
21
  const grouped_data = categoryKey ? from(data).groupby(yearKey, categoryKey) //Somme par année et categorykey
25
22
  .rollup({ [valueKey]: op.sum(valueKey) })
@@ -19,7 +19,8 @@ export const Select = ({ name, dataset: datasetSource, options: input_options =
19
19
  if (data_options === undefined) {
20
20
  return _jsx(_Fragment, {});
21
21
  }
22
- return (_jsx(NextPrevSelect, { name: name, options: data_options, defaultValue: initial_value == null || initial_value == false
23
- ? undefined
24
- : initial_value, arrows: arrows, optionFilterProp: "label", ...rest }));
22
+ const value = initial_value == null || initial_value == false
23
+ ? undefined
24
+ : initial_value;
25
+ return (_jsx(NextPrevSelect, { name: name, options: data_options, defaultValue: value, value: value, arrows: arrows, optionFilterProp: "label", ...rest }));
25
26
  };
@@ -1,6 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { DownloadOutlined, FileImageOutlined, FullscreenOutlined, MoreOutlined, } from "@ant-design/icons";
3
- import { HiQuestionMarkCircle } from "react-icons/hi2";
2
+ import { DownloadOutlined, FileImageOutlined, FullscreenOutlined, MoreOutlined, QuestionCircleOutlined, } from "@ant-design/icons";
4
3
  import { Card, theme, Modal, Dropdown, Flex, Button, Popover, Typography } from "antd";
5
4
  import React, { createContext, useEffect, useState } from "react";
6
5
  import Attribution from "../Attributions/Attributions";
@@ -103,6 +102,6 @@ const DashboardElement = ({ children, title, header = true, attributions, isFetc
103
102
  }, variant: virtual ? 'borderless' : 'outlined', title: header && !virtual &&
104
103
  _jsxs(Flex, { justify: "space-between", align: "center", children: [_jsx("span", { style: { overflow: "hidden", paddingRight: 15 }, children: title }), _jsx("div", { style: { marginRight: 5, fontSize: 16 }, children: toolbox && dropdown_toolbox })] }), children: _jsxs(Flex, { vertical: true, justify: "space-between", style: { height: "100%" }, children: [_jsx(chartContext.Provider, { value: { chartRef, setchartRef, setData, setNodata }, children: _jsx(LoadingContainer, { isFetching: isFetching, noData: nodata, children: children }) }), _jsxs(Flex, { justify: "flex-end", align: "flex-end", style: { marginRight: 5 }, children: [attributions && (_jsx("div", { style: { marginTop: "auto" }, children: _jsx(Attribution, { licenses: licenses, data: attributions }) })), description && (_jsx(Popover, { content: _jsx("div", { style: { maxWidth: 800 }, children: typeof description === "string" ?
105
104
  _jsxs(Text, { italic: true, type: "secondary", children: [" ", description, " "] })
106
- : _jsx(_Fragment, { children: description }) }), children: _jsx(Button, { type: "link", icon: _jsx(HiQuestionMarkCircle, {}), style: { fontSize: "150%" } }) }))] })] }) }), toolbox && fullscreen && (_jsxs(Modal, { forceRender: true, title: title, open: modalIsOpen, onCancel: () => setModalIsOpen(false), onOk: () => setModalIsOpen(false), footer: null, wrapClassName: "modal-fullscreen", children: [fullscreenChildren, attributions && _jsx(Attribution, { data: attributions })] }))] }));
105
+ : _jsx(_Fragment, { children: description }) }), children: _jsx(Button, { type: "link", icon: _jsx(QuestionCircleOutlined, {}), style: { fontSize: "150%" } }) }))] })] }) }), toolbox && fullscreen && (_jsxs(Modal, { forceRender: true, title: title, open: modalIsOpen, onCancel: () => setModalIsOpen(false), onOk: () => setModalIsOpen(false), footer: null, wrapClassName: "modal-fullscreen", children: [fullscreenChildren, attributions && _jsx(Attribution, { data: attributions })] }))] }));
107
106
  };
108
107
  export default DashboardElement;
@@ -12,4 +12,5 @@ interface IChartBlockProps {
12
12
  children: React.ReactElement;
13
13
  }
14
14
  export declare const DSL_ChartBlock: React.FC<IChartBlockProps>;
15
+ export declare const useBlockConfig: ({ title, dataExport }: ChartBlockConfig) => void;
15
16
  export {};
@@ -1,9 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Card, Dropdown, theme } from "antd";
3
- import { createContext, useId, useState } from "react";
4
- import { FaFileCsv } from "react-icons/fa";
5
- import { AiOutlineMore } from "react-icons/ai";
3
+ import { createContext, useContext, useEffect, useId, useState } from "react";
4
+ import { Icon } from "@iconify/react";
6
5
  import { ProducersFooter } from "../Dataset/Producer";
6
+ import { MoreOutlined } from '@ant-design/icons';
7
7
  const { useToken } = theme;
8
8
  export const ChartBlockContext = createContext(undefined);
9
9
  export const DSL_ChartBlock = ({ children }) => {
@@ -13,12 +13,12 @@ export const DSL_ChartBlock = ({ children }) => {
13
13
  const menu_items = [
14
14
  {
15
15
  key: "export_data_csv",
16
- label: (_jsxs("a", { onClick: () => handleExportData(), children: [_jsx(FaFileCsv, {}), " CSV"] })),
16
+ label: (_jsxs("a", { onClick: () => handleExportData(), children: [_jsx(Icon, { icon: "hugeicons:csv-01" }), " CSV"] })),
17
17
  disabled: config.dataExport === undefined
18
18
  },
19
19
  ];
20
20
  const has_action = menu_items.some(item => !item.disabled);
21
- const dropdown_toolbox = (_jsx(Dropdown, { menu: { items: menu_items }, children: _jsx("a", { style: { color: token.colorTextBase }, children: _jsx(AiOutlineMore, {}) }) }));
21
+ const dropdown_toolbox = (_jsx(Dropdown, { menu: { items: menu_items }, children: _jsx("a", { style: { color: token.colorTextBase }, children: _jsx(MoreOutlined, {}) }) }));
22
22
  const handleExportData = () => {
23
23
  console.log('datadl');
24
24
  console.log(config.dataExport);
@@ -38,3 +38,10 @@ export const DSL_ChartBlock = ({ children }) => {
38
38
  };
39
39
  return (_jsx(ChartBlockContext.Provider, { value: { config: config, setConfig: (e) => setConfig(e) }, children: _jsxs(Card, { style: { height: '100%' }, extra: has_action && dropdown_toolbox, title: config.title, children: [children, _jsx(ProducersFooter, { component: children })] }) }));
40
40
  };
41
+ export const useBlockConfig = ({ title, dataExport }) => {
42
+ const blockContext = useContext(ChartBlockContext);
43
+ useEffect(() => blockContext?.setConfig({
44
+ title: title,
45
+ dataExport: dataExport
46
+ }), [title, dataExport]);
47
+ };
@@ -24,6 +24,7 @@ type dataset = {
24
24
  isFetching: boolean;
25
25
  isError: boolean;
26
26
  producers?: any[];
27
+ geojson?: any;
27
28
  };
28
29
  type ControlContextType = {
29
30
  values: Record<string, any>;
@@ -86,7 +86,7 @@ export const DSL_Dataset = ({ children, id, provider: provider_input, type: prov
86
86
  useEffect(() => {
87
87
  const finalData = data?.data && transformers.reduce((datat, fn) => fn(datat), data.data);
88
88
  if (datasetRegistryContext) {
89
- datasetRegistryContext({ id: id, resource: resource, data: finalData, isFetching: isFetching, isError: isError, producers: producers });
89
+ datasetRegistryContext({ id: id, resource: resource, data: finalData, isFetching: isFetching, isError: isError, producers: producers, geojson: data?.geojson });
90
90
  //Ajouter une info pour distinguer les erreurs du fourniseurs et celles des transformers ?
91
91
  }
92
92
  }, [resource, data, isFetching, someFetching, children]);
@@ -5,6 +5,7 @@ export declare const useDataset: (dataset_id?: string) => {
5
5
  isFetching: boolean;
6
6
  isError: boolean;
7
7
  producers?: any[];
8
+ geojson?: any;
8
9
  } | undefined;
9
10
  export declare const useDatasets: (dataset_ids?: string[]) => {
10
11
  id: string;
@@ -13,6 +14,7 @@ export declare const useDatasets: (dataset_ids?: string[]) => {
13
14
  isFetching: boolean;
14
15
  isError: boolean;
15
16
  producers?: any[];
17
+ geojson?: any;
16
18
  }[] | undefined;
17
19
  export declare const useAllDatasets: () => {
18
20
  id: string;
@@ -21,4 +23,5 @@ export declare const useAllDatasets: () => {
21
23
  isFetching: boolean;
22
24
  isError: boolean;
23
25
  producers?: any[];
26
+ geojson?: any;
24
27
  }[] | undefined;
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
2
2
  import { Badge, Collapse, Divider, FloatButton, Modal, theme, Typography } from "antd";
3
3
  import { DataPreview, PalettePreview } from "../../dsl";
4
4
  import { useAllDatasets } from "../Dataset/hooks";
5
- import { AiOutlineBug } from "react-icons/ai";
5
+ import { BugOutlined } from "@ant-design/icons";
6
6
  import { useState } from "react";
7
7
  import { DatasetBadgeStatus } from "../Dataset/DataPreview";
8
8
  import { ControlPreview } from "../Control/Control";
@@ -20,5 +20,5 @@ export const Debug = () => {
20
20
  label: _jsxs("span", { children: [_jsx(DatasetBadgeStatus, { isError: dataset?.isError, isFetching: dataset?.isFetching }), " ", dataset.id, " ", " ", _jsxs(Text, { type: "secondary", children: [" ", dataset?.resource, " "] }), " ", _jsx(Badge, { color: token.colorInfo, overflowCount: 9999, count: dataset?.data?.length })] }),
21
21
  children: _jsx(DataPreview, { dataset: dataset.id, pageSize: 3 })
22
22
  }));
23
- return (_jsxs(_Fragment, { children: [_jsx(FloatButton, { icon: _jsx(AiOutlineBug, {}), type: "primary", onClick: () => setIsModalOpen(true), style: { top: 5 }, className: "debugFloatButton" }), ";", _jsxs(Modal, { title: "Information concepteur", width: "90%", centered: true, styles: { content: { 'width': "100%", padding: 36 } }, closable: { 'aria-label': 'Custom Close Button' }, open: isModalOpen, onCancel: () => setIsModalOpen(false), footer: null, children: [_jsx(Title, { level: 5, children: "Jeux de donn\u00E9es " }), _jsx(Collapse, { accordion: true, items: items }), _jsx(Divider, {}), _jsx(Title, { level: 5, children: "Contr\u00F4les utilisateur " }), _jsx(ControlPreview, {}), _jsx(Divider, {}), _jsx(Title, { level: 5, children: "Palette " }), _jsx(PalettePreview, {})] })] }));
23
+ return (_jsxs(_Fragment, { children: [_jsx(FloatButton, { icon: _jsx(BugOutlined, {}), type: "primary", onClick: () => setIsModalOpen(true), style: { top: 5 }, className: "debugFloatButton" }), ";", _jsxs(Modal, { title: "Information concepteur", width: "90%", centered: true, styles: { content: { 'width': "100%", padding: 36 } }, closable: { 'aria-label': 'Custom Close Button' }, open: isModalOpen, onCancel: () => setIsModalOpen(false), footer: null, children: [_jsx(Title, { level: 5, children: "Jeux de donn\u00E9es " }), _jsx(Collapse, { accordion: true, items: items }), _jsx(Divider, {}), _jsx(Title, { level: 5, children: "Contr\u00F4les utilisateur " }), _jsx(ControlPreview, {}), _jsx(Divider, {}), _jsx(Title, { level: 5, children: "Palette " }), _jsx(PalettePreview, {})] })] }));
24
24
  };
@@ -2,8 +2,8 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
2
2
  import { useRef } from 'react';
3
3
  import { Button, Card, Typography } from "antd";
4
4
  import { useState } from "react";
5
- import { BsInfoCircle, BsInfoCircleFill } from "react-icons/bs";
6
5
  import { cardStyles } from "../../utils/cardStyles";
6
+ import { InfoCircleFilled, InfoCircleOutlined } from "@ant-design/icons";
7
7
  const { Text } = Typography;
8
8
  /**
9
9
  * Une card qui peux se retourner et afficher des informations a son verso
@@ -19,7 +19,7 @@ const FlipCard = ({ title, information, children }) => {
19
19
  width: "100%",
20
20
  };
21
21
  const InfoButton = ({ filled = false }) => {
22
- return (_jsx(Button, { type: "text", shape: "circle", "aria-label": "info", onClick: toggleFlipped, children: filled ? _jsx(BsInfoCircleFill, {}) : _jsx(BsInfoCircle, {}) }));
22
+ return (_jsx(Button, { type: "text", shape: "circle", "aria-label": "info", onClick: toggleFlipped, children: filled ? _jsx(InfoCircleFilled, {}) : _jsx(InfoCircleOutlined, {}) }));
23
23
  };
24
24
  return (_jsxs("div", { style: { position: "relative", height: "100%" }, children: [_jsx(Card, { title: title, extra: _jsxs(_Fragment, { children: [information && _jsx(InfoButton, { filled: flipped }), " "] }), style: {
25
25
  transform: flipped ? "rotateY(180deg)" : "",
@@ -2,9 +2,9 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useContext, useState } from "react";
3
3
  import { Layout, Menu, theme, Row, Col, Button, Divider } from "antd";
4
4
  import { NavLink, useLocation } from "react-router-dom";
5
- import { MdOutlineKeyboardDoubleArrowLeft, MdOutlineKeyboardDoubleArrowRight } from "react-icons/md";
6
5
  import { generateMenuItems } from "../../utils/route_utils";
7
6
  import { AppContext } from "./DashboardApp";
7
+ import { Icon } from "@iconify/react";
8
8
  const style_img = {
9
9
  height: 52,
10
10
  maxWidth: "100%",
@@ -41,7 +41,7 @@ const DashboardSider = ({ style, logo, route_config }) => {
41
41
  }, children: [_jsx(NavLink, { to: "", style: {
42
42
  display: collapsed ? 'none' : undefined,
43
43
  marginTop: 8, marginLeft: 8
44
- }, children: _jsx("img", { style: style_img, src: appLogo, alt: title }) }), _jsx(Divider, { style: { display: collapsed ? 'none' : undefined }, type: "vertical" }), _jsx(Button, { type: "text", onClick: () => setCollapsed(!collapsed), icon: collapsed ? _jsx(MdOutlineKeyboardDoubleArrowRight, {}) : _jsx(MdOutlineKeyboardDoubleArrowLeft, {}), style: {
44
+ }, children: _jsx("img", { style: style_img, src: appLogo, alt: title }) }), _jsx(Divider, { style: { display: collapsed ? 'none' : undefined }, type: "vertical" }), _jsx(Button, { type: "text", onClick: () => setCollapsed(!collapsed), icon: collapsed ? _jsx(Icon, { icon: "material-symbols:keyboard-double-arrow-right-rounded" }) : _jsx(Icon, { icon: "material-symbols:keyboard-double-arrow-left-rounded" }), style: {
45
45
  fontSize: '28px',
46
46
  width: 32,
47
47
  height: 32,
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useEffect, useRef, useState } from "react";
3
3
  import { Empty, Spin, theme } from 'antd';
4
- import { PiEmptyFill } from "react-icons/pi";
4
+ import { Icon } from '@iconify/react';
5
5
  /**
6
6
  * Composant qui ajoute un effet de flou pendant le chargement (si temps de chargement > delay) et affiche un spinner au centre du contenu.
7
7
  * @param isLoading Indique si le chargement est en cours ou non
@@ -28,6 +28,6 @@ const LoadingContainer = ({ isFetching, children, blurRadius = '10px', delay = 5
28
28
  return (_jsxs(_Fragment, { children: [_jsx("div", { style: {
29
29
  filter: blur ? `blur(${blurRadius})` : undefined,
30
30
  display: noData ? "none" : undefined
31
- }, children: children }), noData && _jsx(Empty, { style: { position: "relative", top: "50%", right: "50%", marginBottom: 50, transform: "translate(50%, -50%)" }, description: "Pas de donn\u00E9es disponibles", image: _jsx(PiEmptyFill, { size: 80, color: token.colorPrimary }) }), blur ? _jsx(Spin, { size: "large", style: { position: 'absolute', left: '50%', top: '50%' } }) : _jsx(_Fragment, {})] }));
31
+ }, children: children }), noData && _jsx(Empty, { style: { position: "relative", top: "50%", right: "50%", marginBottom: 50, transform: "translate(50%, -50%)" }, description: "Pas de donn\u00E9es disponibles", image: _jsx(Icon, { icon: "ph:empty-fill", width: 80, color: token.colorPrimary }) }), blur ? _jsx(Spin, { size: "large", style: { position: 'absolute', left: '50%', top: '50%' } }) : _jsx(_Fragment, {})] }));
32
32
  };
33
33
  export default LoadingContainer;
@@ -0,0 +1,59 @@
1
+ import type { AnyLayer } from 'react-map-gl/maplibre';
2
+ import { AnyPaint } from 'mapbox-gl';
3
+ import React from 'react';
4
+ import 'maplibre-gl/dist/maplibre-gl.css';
5
+ type LayerType = AnyLayer["type"];
6
+ export declare const map_locale: {
7
+ 'CooperativeGesturesHandler.WindowsHelpText': string;
8
+ 'CooperativeGesturesHandler.MacHelpText': string;
9
+ 'CooperativeGesturesHandler.MobileHelpText': string;
10
+ };
11
+ /**
12
+ * Une carto simple avec un layer
13
+ *
14
+ * */
15
+ interface MapProps extends MapLayerProps {
16
+ /** Afficher une popup après un click sur la carte */
17
+ popup?: boolean;
18
+ /** Titre du graphique */
19
+ title?: string;
20
+ }
21
+ export declare const Map: React.FC<MapProps>;
22
+ interface MapLayerProps {
23
+ /** Identifiant du jeu de données */
24
+ dataset: string;
25
+ /** Couleur des symboles */
26
+ color?: string;
27
+ /** Layer Type */
28
+ type?: LayerType;
29
+ /** Les paint properties de maplibre cf. https://maplibre.org/maplibre-style-spec/layers/#paint */
30
+ paint?: AnyPaint;
31
+ /** Colonne contenant la variable à représenter */
32
+ categoryKey?: string;
33
+ /** Colonne contenant la coordonnée x / longitude */
34
+ xKey?: string;
35
+ /** Colonne contenant la coordonnées y / latitude */
36
+ yKey?: string;
37
+ }
38
+ /**
39
+ * Composant à utiliser comme enfant d'une <Map>
40
+ * Ajoute une couche (layer) à partir d'un dataset
41
+ *
42
+ * @param { MapLayerProps } props
43
+ * @returns { ReactElement }
44
+ */
45
+ export declare const MapLayer: React.FC<MapLayerProps>;
46
+ export interface IMapBaseLayerProps {
47
+ layer: 'osm' | 'ortho';
48
+ tileSize?: number;
49
+ }
50
+ /**
51
+ * Composant à utiliser comme enfant d'une <Map>
52
+ * Permet d'ajouter un fond de plan (OSM ou orthophoto)
53
+ * devnote : couches spécifiques Hauts-de-France
54
+ *
55
+ * @param { IMapBaseLayerProps } props
56
+ * @returns { ReactElement }
57
+ */
58
+ export declare const BaseLayer: React.FC<IMapBaseLayerProps>;
59
+ export {};
@@ -0,0 +1,147 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ // Composant carto
3
+ import Maplibre, { Layer, Source, useMap, Popup } from 'react-map-gl/maplibre';
4
+ import { useEffect, useRef, useState } from "react";
5
+ import { useDataset } from '../Dataset/hooks';
6
+ import bbox from '@turf/bbox';
7
+ import { getType } from '@turf/invariant';
8
+ import { featureCollection, point } from '@turf/helpers';
9
+ import { usePalette } from '../Palette/Palette';
10
+ import { from, op } from 'arquero';
11
+ import 'maplibre-gl/dist/maplibre-gl.css';
12
+ import { LegendControl } from '../MapLegend/MapLegend';
13
+ import { useBlockConfig } from '../DashboardPage/Block';
14
+ import { parseNumber } from '../../utils/parsers';
15
+ export const map_locale = {
16
+ 'CooperativeGesturesHandler.WindowsHelpText': 'Utilisez Ctrl + molette pour zommer sur la carte.',
17
+ 'CooperativeGesturesHandler.MacHelpText': 'Utilisez ⌘ + molette pour zommer sur la carte.',
18
+ 'CooperativeGesturesHandler.MobileHelpText': 'Utilisez deux doights pour déplacer la carte.',
19
+ };
20
+ /** Construire un geojson a partir d'un tableau de données*/
21
+ const build_geojson = (params) => {
22
+ const { data, xKey, yKey } = params;
23
+ const features_collection = featureCollection(data.map((e) => {
24
+ const [x, y] = [parseNumber(e[xKey]), parseNumber(e[yKey])];
25
+ return point([x, y], { ...e });
26
+ }));
27
+ return features_collection;
28
+ };
29
+ export const Map = ({ dataset, color, type, paint, categoryKey, popup = false, title, xKey, yKey }) => {
30
+ const mapRef = useRef(null);
31
+ const [clickedFeature, setClickedFeature] = useState(undefined);
32
+ useBlockConfig({ title: title });
33
+ const onClickMap = (evt) => {
34
+ setClickedFeature({ ...evt.features[0], ...{ lngLat: evt.lngLat } });
35
+ };
36
+ const onMouseMoveMap = (evt) => {
37
+ if (!mapRef.current) {
38
+ return;
39
+ }
40
+ if (evt?.features.length > 0 && popup) {
41
+ mapRef.current.getCanvasContainer().style.cursor = 'pointer';
42
+ }
43
+ else {
44
+ mapRef.current.getCanvasContainer().style.cursor = 'grab';
45
+ }
46
+ };
47
+ return (_jsxs(Maplibre, { cooperativeGestures: true, locale: map_locale, ref: mapRef, interactiveLayerIds: [dataset], onClick: onClickMap, onMouseMove: onMouseMoveMap, style: { width: '100%', height: '500px' }, children: [_jsx(BaseLayer, { layer: "osm" }), _jsx(MapLayer, { dataset: dataset, color: color, type: type, paint: paint, categoryKey: categoryKey, xKey: xKey, yKey: yKey }), clickedFeature?.properties && categoryKey && popup &&
48
+ _jsxs(Popup, { longitude: clickedFeature.lngLat.lng, latitude: clickedFeature.lngLat.lat, onClose: () => { setClickedFeature(null); }, children: [_jsxs("div", { children: [" ", clickedFeature.properties[categoryKey], " "] }), " "] })] }));
49
+ };
50
+ /**
51
+ * Composant à utiliser comme enfant d'une <Map>
52
+ * Ajoute une couche (layer) à partir d'un dataset
53
+ *
54
+ * @param { MapLayerProps } props
55
+ * @returns { ReactElement }
56
+ */
57
+ export const MapLayer = ({ dataset, categoryKey, color = 'red', type = 'circle', paint, xKey, yKey }) => {
58
+ const { current: map } = useMap();
59
+ const data = useDataset(dataset);
60
+ // src (lib proj4 pour convertir)
61
+ // Si x et y sont definie, on construit le geojson
62
+ const geojson = xKey && yKey && data?.data ?
63
+ build_geojson({ data: data.data, xKey: xKey, yKey: yKey })
64
+ : data?.geojson; // Sinon on utilise le geojson (fournisseur wfs)
65
+ const geom_type = geojson?.features?.[0] && getType(geojson?.features?.[0]);
66
+ /** Type de données dans categoryKey (string ou number) */
67
+ const type_value = categoryKey && typeof (data?.data?.[0][categoryKey]);
68
+ /** Valeurs distinctes (si type string) */
69
+ const values = (type_value === 'string') && categoryKey && data?.data && from(data?.data).rollup({ a: op.array_agg_distinct(categoryKey) }).get('a', 0) || undefined;
70
+ /** Couleurs de la palette */
71
+ const colors = usePalette({ nColors: Array.isArray(values) ? values?.length : 1 });
72
+ const match = Array.isArray(values) ? values?.map((v, i) => ({
73
+ val: v,
74
+ color: colors?.[i],
75
+ })) : undefined;
76
+ /** Expression mapLibre qui permet de mapper les valeurs et les couleurs de la palette */
77
+ const expression = match && categoryKey
78
+ ? [
79
+ "match",
80
+ ["get", categoryKey],
81
+ ...match?.flatMap((s) => [s.val, s.color]),
82
+ "purple" // fallback
83
+ ]
84
+ : undefined;
85
+ const legendItems = match?.map((e) => ({ color: e.color, label: e.val })).sort((a, b) => a.label.localeCompare(b.label)) || [];
86
+ const layers = [];
87
+ /** POINT */
88
+ if (geom_type === 'Point' || geom_type === 'MultiPoint') {
89
+ const default_paint = { "circle-color": expression ?? color ?? colors[0] };
90
+ type = 'circle';
91
+ layers.push(_jsx(Layer, { id: dataset, type: "circle", paint: (paint ?? default_paint) }, dataset));
92
+ }
93
+ /** POLYGON */
94
+ else if (geom_type === 'Polygon' || geom_type === 'MultiPolygon') {
95
+ const default_paint = { "fill-color": expression ?? color ?? colors[0] };
96
+ type = 'fill';
97
+ layers.push(_jsx(Layer, { id: dataset, type: "fill", paint: (paint ?? default_paint) }, dataset));
98
+ layers.push(_jsx(Layer, { id: dataset + '_line', type: 'line', paint: { "line-width": 0.5, "line-color": '#fff' } }, dataset + '_line'));
99
+ }
100
+ /** LINESTRING */
101
+ else if (geom_type === 'LineString' || geom_type === 'MultiLineString') {
102
+ const default_paint = { "line-color": expression ?? color ?? colors[0] };
103
+ type = 'line';
104
+ layers.push(_jsx(Layer, { id: dataset, type: "line", paint: (paint ?? default_paint) }, dataset));
105
+ }
106
+ //devnote : regarder la colonne contenant les valeurs pour proposer une représentation (catégorie ou choroplèthe)
107
+ useEffect(() => {
108
+ if (geojson) {
109
+ const box = bbox(geojson).slice(0, 4);
110
+ map?.fitBounds(box, { padding: 20 });
111
+ }
112
+ }, [geojson, map]);
113
+ return (_jsxs(_Fragment, { children: [geojson &&
114
+ _jsx(Source, { type: "geojson", data: geojson, children: layers }), _jsx(LegendControl, { items: legendItems })] }));
115
+ };
116
+ /**
117
+ * Composant à utiliser comme enfant d'une <Map>
118
+ * Permet d'ajouter un fond de plan (OSM ou orthophoto)
119
+ * devnote : couches spécifiques Hauts-de-France
120
+ *
121
+ * @param { IMapBaseLayerProps } props
122
+ * @returns { ReactElement }
123
+ */
124
+ export const BaseLayer = ({ layer, tileSize = 256 }) => {
125
+ //TODO : ne pas utiliser par défaut le fond de plan geo2france ?
126
+ const t = (() => {
127
+ switch (layer) {
128
+ case 'osm':
129
+ return `https://osm.geo2france.fr/mapcache/?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&FORMAT=image%2Fpng&TRANSPARENT=false&LAYERS=grey&TILED=true&WIDTH=${tileSize}&HEIGHT=${tileSize}&SRS=EPSG%3A3857&STYLES=&BBOX={bbox-epsg-3857}`;
130
+ case 'ortho':
131
+ return `https://www.geo2france.fr/geoserver/geo2france/ows/?bbox={bbox-epsg-3857}&format=image/png&service=WMS&version=1.3.0&request=GetMap&srs=EPSG:3857&transparent=true&width=${tileSize}&height=${tileSize}&layers=ortho_regionale_2018_rvb`;
132
+ }
133
+ })();
134
+ const source_raster = {
135
+ type: 'raster',
136
+ attribution: 'OpenStreetMap', //fixme
137
+ tiles: [
138
+ t
139
+ ],
140
+ tileSize: tileSize
141
+ };
142
+ const layer_raster = {
143
+ 'type': 'raster',
144
+ 'paint': {}
145
+ };
146
+ return (_jsx(Source, { ...source_raster, children: _jsx(Layer, { ...layer_raster }) }));
147
+ };
@@ -10,3 +10,9 @@ interface MapLegendProps {
10
10
  }
11
11
  declare const MapLegend: React.FC<MapLegendProps>;
12
12
  export default MapLegend;
13
+ interface LegendControlProps {
14
+ /** Elements de légende */
15
+ items: LegendItem[];
16
+ }
17
+ /** Un control pour Maplibre qui permet d'afficher une légende */
18
+ export declare const LegendControl: React.FC<LegendControlProps>;
@@ -1,4 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useRef } from "react";
3
+ import { createRoot } from "react-dom/client";
4
+ import { useControl } from "react-map-gl/maplibre";
2
5
  const default_style = {
3
6
  backgroundColor: 'rgba(256,256,256,0.8)',
4
7
  padding: '10px',
@@ -17,3 +20,29 @@ const MapLegend = ({ items, style }) => {
17
20
  } }), _jsx("span", { children: item.label })] }, index))) }));
18
21
  };
19
22
  export default MapLegend;
23
+ /** Un control pour Maplibre qui permet d'afficher une légende */
24
+ export const LegendControl = ({ items }) => {
25
+ const rootRef = useRef(null);
26
+ useControl(() => {
27
+ const container = document.createElement("div");
28
+ //container.className = "maplibregl-ctrl"; // pour hériter du style par défaut
29
+ const root = createRoot(container);
30
+ rootRef.current = root;
31
+ const control = {
32
+ onAdd: (_map) => {
33
+ root.render(_jsx(MapLegend, { items: items }));
34
+ return container;
35
+ },
36
+ onRemove: () => {
37
+ container.parentNode?.removeChild(container);
38
+ },
39
+ };
40
+ return control;
41
+ }, { position: "top-right" });
42
+ useEffect(() => {
43
+ if (rootRef.current) {
44
+ rootRef.current.render(_jsx(MapLegend, { items: items }));
45
+ }
46
+ }, [items]);
47
+ return null;
48
+ };
@@ -27,7 +27,7 @@ const NextPrevSelect = ({ name, options: input_options = [], style, value, defau
27
27
  const [current_value, setCurrent_value] = useState(value);
28
28
  const form = Form.useFormInstance();
29
29
  useEffect(() => {
30
- setCurrent_value(value);
30
+ value && handleChange(value);
31
31
  }, [value]);
32
32
  const options = list_to_options(input_options);
33
33
  const current_index = options?.findIndex((o) => o.value == form?.getFieldValue(name) || o.value == current_value);
@@ -16,4 +16,7 @@ import { Palette, usePalette, PalettePreview } from "../components/Palette/Palet
16
16
  import { Debug } from "../components/Debug/Debug";
17
17
  import { Join } from "../components/Dataset/Join";
18
18
  import { ChartEcharts } from "../components/Charts/ChartEcharts";
19
- export { Dashboard, Dataset, Provider, Transform, Join, Filter, DataPreview, ChartEcharts, ChartPie, ChartYearSerie, useDataset, useDatasets, useAllDatasets, Producer, Control, useControl, useAllControls, Radio, Select, Input, Palette, usePalette, PalettePreview, Debug, };
19
+ import { useBlockConfig } from "../components/DashboardPage/Block";
20
+ import { Statistics, StatisticsCollection } from "../components/Charts/Statistics";
21
+ import { MapLayer, Map } from "../components/Map/Map";
22
+ export { Dashboard, Dataset, Provider, Transform, Join, Filter, DataPreview, ChartEcharts, ChartPie, ChartYearSerie, Statistics, StatisticsCollection, useDataset, useDatasets, useAllDatasets, useBlockConfig, Producer, Control, useControl, useAllControls, Radio, Select, Input, Palette, usePalette, PalettePreview, Debug, Map, MapLayer };
package/dist/dsl/index.js CHANGED
@@ -16,4 +16,7 @@ import { Palette, usePalette, PalettePreview } from "../components/Palette/Palet
16
16
  import { Debug } from "../components/Debug/Debug";
17
17
  import { Join } from "../components/Dataset/Join";
18
18
  import { ChartEcharts } from "../components/Charts/ChartEcharts";
19
- export { Dashboard, Dataset, Provider, Transform, Join, Filter, DataPreview, ChartEcharts, ChartPie, ChartYearSerie, useDataset, useDatasets, useAllDatasets, Producer, Control, useControl, useAllControls, Radio, Select, Input, Palette, usePalette, PalettePreview, Debug, };
19
+ import { useBlockConfig } from "../components/DashboardPage/Block";
20
+ import { Statistics, StatisticsCollection } from "../components/Charts/Statistics";
21
+ import { MapLayer, Map } from "../components/Map/Map";
22
+ export { Dashboard, Dataset, Provider, Transform, Join, Filter, DataPreview, ChartEcharts, ChartPie, ChartYearSerie, Statistics, StatisticsCollection, useDataset, useDatasets, useAllDatasets, useBlockConfig, Producer, Control, useControl, useAllControls, Radio, Select, Input, Palette, usePalette, PalettePreview, Debug, Map, MapLayer };
@@ -0,0 +1,2 @@
1
+ /** Parser automatiquement un nombre au format : 0.6, "0.6" ou "0,6" */
2
+ export declare const parseNumber: (value: string | number) => number;
@@ -0,0 +1,14 @@
1
+ /** Parser automatiquement un nombre au format : 0.6, "0.6" ou "0,6" */
2
+ export const parseNumber = (value) => {
3
+ if (typeof value === "number") {
4
+ return value;
5
+ }
6
+ if (typeof value === "string") {
7
+ const normalized = value.replace(",", ".");
8
+ const num = parseFloat(normalized);
9
+ if (!isNaN(num)) {
10
+ return num;
11
+ }
12
+ }
13
+ return NaN;
14
+ };
@@ -4,5 +4,8 @@ interface useMapControlProps {
4
4
  legendElement: React.ReactElement;
5
5
  position?: ControlPosition;
6
6
  }
7
+ /** A déprécier ? utiliser plutôt le composant LegendControl ?
8
+ * Uniquement pour legacy
9
+ */
7
10
  export declare const useMapControl: ({ mapRef, legendElement, position }: useMapControlProps) => void;
8
11
  export {};
@@ -1,6 +1,9 @@
1
1
  // Ajouter un control (element HTML) sur une carte
2
2
  import { useEffect } from "react";
3
3
  import { createRoot } from 'react-dom/client';
4
+ /** A déprécier ? utiliser plutôt le composant LegendControl ?
5
+ * Uniquement pour legacy
6
+ */
4
7
  export const useMapControl = ({ mapRef, legendElement, position = 'top-right' }) => {
5
8
  useEffect(() => {
6
9
  if (mapRef?.current) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geo2france/api-dashboard",
3
- "version": "1.8.0",
3
+ "version": "1.10.0",
4
4
  "private": false,
5
5
  "description": "Build dashboards with JSX/TSX",
6
6
  "main": "dist/index.js",
@@ -45,18 +45,24 @@
45
45
  "test": "jest --watchAll"
46
46
  },
47
47
  "dependencies": {
48
+ "@iconify/react": "^6.0.1",
49
+ "@turf/bbox": "^7.2.0",
50
+ "@turf/helpers": "^7.2.0",
51
+ "@turf/invariant": "^7.2.0",
48
52
  "alasql": "^4.6.6",
49
53
  "arquero": "^8.0.3",
50
- "axios": "^1.7.4",
54
+ "axios": "^1.12.2",
51
55
  "chroma-js": "^3.1.2",
52
- "echarts": "^5.5.1",
53
- "echarts-for-react": "^3.0.2",
56
+ "echarts": "^6.0.0",
57
+ "echarts-for-react": "^3.0.4",
54
58
  "query-string": "~7.1.3",
55
59
  "react-helmet": "^6.1.0",
56
60
  "react-helmet-async": "^2.0.5",
57
61
  "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz"
58
62
  },
59
63
  "devDependencies": {
64
+ "@ant-design/icons": "^6.0.2",
65
+ "@iconify/json": "^2.2.382",
60
66
  "@tanstack/react-query": "^5.51.11",
61
67
  "@testing-library/dom": "^10.4.0",
62
68
  "@testing-library/jest-dom": "^6.5.0",
@@ -76,7 +82,9 @@
76
82
  "antd": "^5.24.3",
77
83
  "jest": "^29.7.0",
78
84
  "jest-environment-jsdom": "^29.7.0",
85
+ "maplibre-gl": "^4.7.1",
79
86
  "react": "^18.3.1",
87
+ "react-map-gl": "^7.1.9",
80
88
  "react-router-dom": "^6.25.1",
81
89
  "ts-jest": "^29.2.5",
82
90
  "ts-node": "^10.9.2",
@@ -86,12 +94,13 @@
86
94
  "vite-plugin-svgr": "^4.2.0"
87
95
  },
88
96
  "peerDependencies": {
97
+ "@ant-design/icons": "^6.0.2",
89
98
  "@tanstack/react-query": "^5.51.11",
90
99
  "antd": "^5.18.3",
100
+ "maplibre-gl": "^4.7.1",
91
101
  "react": "^18.3.1",
92
102
  "react-dom": "^18.3.1",
93
- "react-icons": "5.4",
94
- "react-map-gl": "^7.1.7",
103
+ "react-map-gl": "^7.1.9",
95
104
  "react-router-dom": "^6.25.1"
96
105
  }
97
106
  }
@@ -1 +0,0 @@
1
- export declare const mapOperator: (operator: any) => string;
@@ -1,36 +0,0 @@
1
- export const mapOperator = (operator) => {
2
- switch (operator) {
3
- case "ne":
4
- return '<>';
5
- case "gte":
6
- return '>=';
7
- case "gt":
8
- return '>';
9
- case "lte":
10
- return `<=`;
11
- case "lt":
12
- return `<`;
13
- case "eq":
14
- return "=";
15
- case "contains":
16
- case "startswith":
17
- case "endswith":
18
- return "ilike";
19
- case "containss":
20
- case "startswiths":
21
- case "endswiths":
22
- return "like";
23
- case "ncontains":
24
- case "nstartswith":
25
- case "nendswith":
26
- return "not ilike";
27
- case "ncontainss":
28
- case "nstartswiths":
29
- case "nendswiths":
30
- return "not like";
31
- case "in":
32
- return operator;
33
- default:
34
- return "";
35
- }
36
- };