@geo2france/api-dashboard 1.5.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.
- package/README.MD +192 -0
- package/dist/components/Attributions/Attribution.test.d.ts +1 -0
- package/dist/components/Attributions/Attribution.test.js +19 -0
- package/dist/components/Attributions/Attributions.d.ts +17 -0
- package/dist/components/Attributions/Attributions.js +30 -0
- package/dist/components/Charts/ChartEcharts.d.ts +7 -0
- package/dist/components/Charts/ChartEcharts.js +35 -0
- package/dist/components/Charts/Pie.d.ts +10 -0
- package/dist/components/Charts/Pie.js +35 -0
- package/dist/components/Charts/YearSerie.d.ts +16 -0
- package/dist/components/Charts/YearSerie.js +70 -0
- package/dist/components/Control/Control.d.ts +21 -0
- package/dist/components/Control/Control.js +84 -0
- package/dist/components/Control/Radio.d.ts +19 -0
- package/dist/components/Control/Radio.js +27 -0
- package/dist/components/Control/Select.d.ts +15 -0
- package/dist/components/Control/Select.js +25 -0
- package/dist/components/DashboardChart/DashboardChart.d.ts +11 -0
- package/dist/components/DashboardChart/DashboardChart.js +42 -0
- package/dist/components/DashboardElement/DashboardElement.d.ts +21 -0
- package/dist/components/DashboardElement/DashboardElement.js +108 -0
- package/dist/components/DashboardElement/hooks.d.ts +28 -0
- package/dist/components/DashboardElement/hooks.js +29 -0
- package/dist/components/DashboardPage/Block.d.ts +15 -0
- package/dist/components/DashboardPage/Block.js +40 -0
- package/dist/components/DashboardPage/DashboardPage.test.d.ts +1 -0
- package/dist/components/DashboardPage/DashboardPage.test.js +40 -0
- package/dist/components/DashboardPage/Page.d.ts +42 -0
- package/dist/components/DashboardPage/Page.js +80 -0
- package/dist/components/Dataset/DataPreview.d.ts +12 -0
- package/dist/components/Dataset/DataPreview.js +21 -0
- package/dist/components/Dataset/Dataset.d.ts +17 -0
- package/dist/components/Dataset/Dataset.js +94 -0
- package/dist/components/Dataset/Filter.d.ts +9 -0
- package/dist/components/Dataset/Filter.js +7 -0
- package/dist/components/Dataset/Join.d.ts +8 -0
- package/dist/components/Dataset/Join.js +7 -0
- package/dist/components/Dataset/Producer.d.ts +18 -0
- package/dist/components/Dataset/Producer.js +27 -0
- package/dist/components/Dataset/Provider.d.ts +21 -0
- package/dist/components/Dataset/Provider.js +22 -0
- package/dist/components/Dataset/Transform.d.ts +6 -0
- package/dist/components/Dataset/Transform.js +7 -0
- package/dist/components/Dataset/hooks.d.ts +24 -0
- package/dist/components/Dataset/hooks.js +19 -0
- package/dist/components/Debug/Debug.d.ts +1 -0
- package/dist/components/Debug/Debug.js +24 -0
- package/dist/components/FlipCard/FlipCard.d.ts +12 -0
- package/dist/components/FlipCard/FlipCard.js +38 -0
- package/dist/components/FlipCard/FlipCard.test.d.ts +1 -0
- package/dist/components/FlipCard/FlipCard.test.js +36 -0
- package/dist/components/KeyFigure/KeyFigure.d.ts +18 -0
- package/dist/components/KeyFigure/KeyFigure.js +13 -0
- package/dist/components/Layout/DashboardApp.d.ts +18 -0
- package/dist/components/Layout/DashboardApp.js +46 -0
- package/dist/components/Layout/Error.d.ts +2 -0
- package/dist/components/Layout/Error.js +6 -0
- package/dist/components/Layout/Footer.d.ts +6 -0
- package/dist/components/Layout/Footer.js +47 -0
- package/dist/components/Layout/Sider.d.ts +9 -0
- package/dist/components/Layout/Sider.js +48 -0
- package/dist/components/LoadingContainer/LoadingContainer.d.ts +17 -0
- package/dist/components/LoadingContainer/LoadingContainer.js +33 -0
- package/dist/components/MapLegend/MapLegend.d.ts +12 -0
- package/dist/components/MapLegend/MapLegend.js +19 -0
- package/dist/components/NextPrevSelect/NextPrevSelect.d.ts +17 -0
- package/dist/components/NextPrevSelect/NextPrevSelect.js +49 -0
- package/dist/components/Palette/Palette.d.ts +18 -0
- package/dist/components/Palette/Palette.js +29 -0
- package/dist/data_providers/datafair/datafair.test.d.ts +1 -0
- package/dist/data_providers/datafair/datafair.test.js +39 -0
- package/dist/data_providers/datafair/index.d.ts +15 -0
- package/dist/data_providers/datafair/index.js +33 -0
- package/dist/data_providers/datafair/utils/axios.d.ts +2 -0
- package/dist/data_providers/datafair/utils/axios.js +13 -0
- package/dist/data_providers/datafair/utils/generateFilter.d.ts +1 -0
- package/dist/data_providers/datafair/utils/generateFilter.js +40 -0
- package/dist/data_providers/datafair/utils/generateSort.d.ts +1 -0
- package/dist/data_providers/datafair/utils/generateSort.js +19 -0
- package/dist/data_providers/datafair/utils/index.d.ts +4 -0
- package/dist/data_providers/datafair/utils/index.js +4 -0
- package/dist/data_providers/datafair/utils/mapOperator.d.ts +1 -0
- package/dist/data_providers/datafair/utils/mapOperator.js +13 -0
- package/dist/data_providers/file/index.d.ts +6 -0
- package/dist/data_providers/file/index.js +25 -0
- package/dist/data_providers/file/utils/axios.d.ts +2 -0
- package/dist/data_providers/file/utils/axios.js +26 -0
- package/dist/data_providers/types.d.ts +52 -0
- package/dist/data_providers/types.js +2 -0
- package/dist/data_providers/wfs/index.d.ts +3 -0
- package/dist/data_providers/wfs/index.js +43 -0
- package/dist/data_providers/wfs/utils/axios.d.ts +2 -0
- package/dist/data_providers/wfs/utils/axios.js +26 -0
- package/dist/data_providers/wfs/utils/generateFilter.d.ts +4 -0
- package/dist/data_providers/wfs/utils/generateFilter.js +45 -0
- package/dist/data_providers/wfs/utils/generateSort.d.ts +1 -0
- package/dist/data_providers/wfs/utils/generateSort.js +20 -0
- package/dist/data_providers/wfs/utils/index.d.ts +4 -0
- package/dist/data_providers/wfs/utils/index.js +4 -0
- package/dist/data_providers/wfs/utils/mapOperator.d.ts +1 -0
- package/dist/data_providers/wfs/utils/mapOperator.js +36 -0
- package/dist/data_providers/wfs/wfs.test.d.ts +1 -0
- package/dist/data_providers/wfs/wfs.test.js +60 -0
- package/dist/dsl/index.d.ts +19 -0
- package/dist/dsl/index.js +19 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.js +33 -0
- package/dist/types.d.ts +15 -0
- package/dist/types.js +1 -0
- package/dist/utils/baserecordtogeojsonpoint.d.ts +13 -0
- package/dist/utils/baserecordtogeojsonpoint.js +17 -0
- package/dist/utils/cardStyles.d.ts +2 -0
- package/dist/utils/cardStyles.js +12 -0
- package/dist/utils/deepmerge.d.ts +2 -0
- package/dist/utils/deepmerge.js +24 -0
- package/dist/utils/route_utils.d.ts +6 -0
- package/dist/utils/route_utils.js +14 -0
- package/dist/utils/useApi.d.ts +12 -0
- package/dist/utils/useApi.js +14 -0
- package/dist/utils/useMapControl.d.ts +8 -0
- package/dist/utils/useMapControl.js +24 -0
- package/dist/utils/useSearchParamsState.d.ts +11 -0
- package/dist/utils/useSearchParamsState.js +18 -0
- package/dist/utils/usechartexports.d.ts +17 -0
- package/dist/utils/usechartexports.js +39 -0
- package/dist/utils/usecharthightlight.d.ts +25 -0
- package/dist/utils/usecharthightlight.js +44 -0
- package/package.json +98 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
//import {render, screen} from '@testing-library/react'
|
|
2
|
+
import '@testing-library/jest-dom';
|
|
3
|
+
//import userEvent from '@testing-library/user-event'
|
|
4
|
+
import { QueryClient } from '@tanstack/react-query';
|
|
5
|
+
import { /*useApi,*/ WfsProvider } from '../..';
|
|
6
|
+
const test_provider_url = "https://www.geo2france.fr/geoserver/ows";
|
|
7
|
+
const test_page_size = 3;
|
|
8
|
+
const test_filter_field = "siren_epci";
|
|
9
|
+
const test_filter_value = "200067999";
|
|
10
|
+
const resource = "odema:destination_dma_epci";
|
|
11
|
+
const filters = [
|
|
12
|
+
{
|
|
13
|
+
field: test_filter_field,
|
|
14
|
+
operator: "eq",
|
|
15
|
+
value: test_filter_value,
|
|
16
|
+
},
|
|
17
|
+
];
|
|
18
|
+
const pagination = {
|
|
19
|
+
mode: "server",
|
|
20
|
+
pageSize: test_page_size,
|
|
21
|
+
};
|
|
22
|
+
const sorters = [{ field: "fid", order: "asc" }];
|
|
23
|
+
const queryClient = new QueryClient();
|
|
24
|
+
//TODO tester dans un composant
|
|
25
|
+
/*const component_using_api:React.FC = () => {
|
|
26
|
+
const provider = WfsProvider("https://www.geo2france.fr/geoserver/ows")
|
|
27
|
+
const data = useApi({
|
|
28
|
+
dataProvider:provider,
|
|
29
|
+
resource:"odema:destination_dma_epci ",
|
|
30
|
+
pagination:{
|
|
31
|
+
mode:"off"
|
|
32
|
+
},
|
|
33
|
+
filters:[
|
|
34
|
+
{
|
|
35
|
+
field:"siren_epci",
|
|
36
|
+
operator:"eq",
|
|
37
|
+
value:"200067999"
|
|
38
|
+
}]
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
return <></>
|
|
42
|
+
}*/
|
|
43
|
+
describe("WFS Provider", () => {
|
|
44
|
+
test("basic filter & pagination", async () => {
|
|
45
|
+
const provider = WfsProvider(test_provider_url);
|
|
46
|
+
const queryKey = [provider.getApiUrl, resource, filters, pagination, sorters, undefined];
|
|
47
|
+
const result = await queryClient.fetchQuery({
|
|
48
|
+
queryKey: queryKey,
|
|
49
|
+
queryFn: () => provider.getList({
|
|
50
|
+
resource: resource,
|
|
51
|
+
filters: filters,
|
|
52
|
+
pagination: pagination,
|
|
53
|
+
sorters: sorters
|
|
54
|
+
}),
|
|
55
|
+
});
|
|
56
|
+
expect(result).toHaveProperty('data');
|
|
57
|
+
expect(result.data).toHaveLength(test_page_size);
|
|
58
|
+
expect(result.data[0][test_filter_field]).toEqual(test_filter_value);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { DSL_DashboardPage as Dashboard } from "../components/DashboardPage/Page";
|
|
2
|
+
import { DSL_Dataset as Dataset } from "../components/Dataset/Dataset";
|
|
3
|
+
import { DSL_DataPreview as DataPreview } from "../components/Dataset/DataPreview";
|
|
4
|
+
import { DSL_Transform as Transform } from "../components/Dataset/Transform";
|
|
5
|
+
import { DSL_Filter as Filter } from "../components/Dataset/Filter";
|
|
6
|
+
import { Provider } from "../components/Dataset/Provider";
|
|
7
|
+
import { useAllDatasets, useDataset, useDatasets } from "../components/Dataset/hooks";
|
|
8
|
+
import { ChartPie } from "../components/Charts/Pie";
|
|
9
|
+
import { ChartYearSerie } from "../components/Charts/YearSerie";
|
|
10
|
+
import { Producer } from "../components/Dataset/Producer";
|
|
11
|
+
import { DSL_Control as Control, useAllControls, useControl } from "../components/Control/Control";
|
|
12
|
+
import { Radio } from "../components/Control/Radio";
|
|
13
|
+
import { Select } from "../components/Control/Select";
|
|
14
|
+
import { Input } from "antd";
|
|
15
|
+
import { Palette, usePalette, PalettePreview } from "../components/Palette/Palette";
|
|
16
|
+
import { Debug } from "../components/Debug/Debug";
|
|
17
|
+
import { Join } from "../components/Dataset/Join";
|
|
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, };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { DSL_DashboardPage as Dashboard } from "../components/DashboardPage/Page";
|
|
2
|
+
import { DSL_Dataset as Dataset } from "../components/Dataset/Dataset";
|
|
3
|
+
import { DSL_DataPreview as DataPreview } from "../components/Dataset/DataPreview";
|
|
4
|
+
import { DSL_Transform as Transform } from "../components/Dataset/Transform";
|
|
5
|
+
import { DSL_Filter as Filter } from "../components/Dataset/Filter";
|
|
6
|
+
import { Provider } from "../components/Dataset/Provider";
|
|
7
|
+
import { useAllDatasets, useDataset, useDatasets } from "../components/Dataset/hooks";
|
|
8
|
+
import { ChartPie } from "../components/Charts/Pie";
|
|
9
|
+
import { ChartYearSerie } from "../components/Charts/YearSerie";
|
|
10
|
+
import { Producer } from "../components/Dataset/Producer";
|
|
11
|
+
import { DSL_Control as Control, useAllControls, useControl } from "../components/Control/Control";
|
|
12
|
+
import { Radio } from "../components/Control/Radio";
|
|
13
|
+
import { Select } from "../components/Control/Select";
|
|
14
|
+
import { Input } from "antd";
|
|
15
|
+
import { Palette, usePalette, PalettePreview } from "../components/Palette/Palette";
|
|
16
|
+
import { Debug } from "../components/Debug/Debug";
|
|
17
|
+
import { Join } from "../components/Dataset/Join";
|
|
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, };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export { useChartEvents, useChartActionHightlight } from "./utils/usecharthightlight";
|
|
2
|
+
export { useSearchParamsState } from "./utils/useSearchParamsState";
|
|
3
|
+
export { useChartExport } from "./utils/usechartexports";
|
|
4
|
+
export { useApi } from "./utils/useApi";
|
|
5
|
+
export { useChartData, useDashboardElement, useNoData } from "./components/DashboardElement/hooks";
|
|
6
|
+
export { useMapControl } from "./utils/useMapControl";
|
|
7
|
+
export { BaseRecordToGeojsonPoint } from "./utils/baserecordtogeojsonpoint";
|
|
8
|
+
export { cardStyles } from "./utils/cardStyles";
|
|
9
|
+
import KeyFigure from "./components/KeyFigure/KeyFigure";
|
|
10
|
+
import LoadingContainer from "./components/LoadingContainer/LoadingContainer";
|
|
11
|
+
import FlipCard from "./components/FlipCard/FlipCard";
|
|
12
|
+
import Attribution from "./components/Attributions/Attributions";
|
|
13
|
+
import NextPrevSelect from "./components/NextPrevSelect/NextPrevSelect";
|
|
14
|
+
import Control from "./components/Control/Control";
|
|
15
|
+
import DashboardChart from "./components/DashboardChart/DashboardChart";
|
|
16
|
+
import MapLegend from "./components/MapLegend/MapLegend";
|
|
17
|
+
import DashboardApp from "./components/Layout/DashboardApp";
|
|
18
|
+
import DashboardSider from "./components/Layout/Sider";
|
|
19
|
+
import DashboardPage from "./components/DashboardPage/Page";
|
|
20
|
+
import DashboardElement from "./components/DashboardElement/DashboardElement";
|
|
21
|
+
export { KeyFigure, DashboardElement, LoadingContainer, FlipCard, Attribution, NextPrevSelect, Control, DashboardChart, DashboardPage, MapLegend, DashboardSider, DashboardApp, };
|
|
22
|
+
import { dataProvider as WfsProvider } from "./data_providers/wfs";
|
|
23
|
+
import { dataProvider as DatafairProvider } from "./data_providers/datafair";
|
|
24
|
+
import { dataProvider as FileProvider } from "./data_providers/file";
|
|
25
|
+
export { WfsProvider, DatafairProvider, FileProvider };
|
|
26
|
+
export type { SimpleRecord, Partner, RouteConfig } from "./types";
|
|
27
|
+
export type { LegendItem } from "./components/MapLegend/MapLegend";
|
|
28
|
+
import * as DSL from './dsl';
|
|
29
|
+
export { DSL };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Hooks
|
|
2
|
+
export { useChartEvents, useChartActionHightlight } from "./utils/usecharthightlight";
|
|
3
|
+
export { useSearchParamsState } from "./utils/useSearchParamsState";
|
|
4
|
+
export { useChartExport } from "./utils/usechartexports";
|
|
5
|
+
export { useApi } from "./utils/useApi";
|
|
6
|
+
export { useChartData, useDashboardElement, useNoData } from "./components/DashboardElement/hooks";
|
|
7
|
+
export { useMapControl } from "./utils/useMapControl";
|
|
8
|
+
// Helpers
|
|
9
|
+
export { BaseRecordToGeojsonPoint } from "./utils/baserecordtogeojsonpoint";
|
|
10
|
+
export { cardStyles } from "./utils/cardStyles";
|
|
11
|
+
// Components
|
|
12
|
+
import KeyFigure from "./components/KeyFigure/KeyFigure";
|
|
13
|
+
import LoadingContainer from "./components/LoadingContainer/LoadingContainer";
|
|
14
|
+
import FlipCard from "./components/FlipCard/FlipCard";
|
|
15
|
+
import Attribution from "./components/Attributions/Attributions";
|
|
16
|
+
import NextPrevSelect from "./components/NextPrevSelect/NextPrevSelect";
|
|
17
|
+
import Control from "./components/Control/Control";
|
|
18
|
+
import DashboardChart from "./components/DashboardChart/DashboardChart";
|
|
19
|
+
import MapLegend from "./components/MapLegend/MapLegend";
|
|
20
|
+
// Layout
|
|
21
|
+
import DashboardApp from "./components/Layout/DashboardApp";
|
|
22
|
+
import DashboardSider from "./components/Layout/Sider";
|
|
23
|
+
import DashboardPage from "./components/DashboardPage/Page";
|
|
24
|
+
import DashboardElement from "./components/DashboardElement/DashboardElement";
|
|
25
|
+
export { KeyFigure, DashboardElement, LoadingContainer, FlipCard, Attribution, NextPrevSelect, Control, DashboardChart, DashboardPage, MapLegend, DashboardSider, DashboardApp, };
|
|
26
|
+
// DataProviders
|
|
27
|
+
import { dataProvider as WfsProvider } from "./data_providers/wfs";
|
|
28
|
+
import { dataProvider as DatafairProvider } from "./data_providers/datafair";
|
|
29
|
+
import { dataProvider as FileProvider } from "./data_providers/file";
|
|
30
|
+
export { WfsProvider, DatafairProvider, FileProvider };
|
|
31
|
+
// DSL
|
|
32
|
+
import * as DSL from './dsl';
|
|
33
|
+
export { DSL };
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type SimpleRecord = Record<string, any>;
|
|
2
|
+
export type License = ('CC' | 'BY' | 'SA' | 'NC' | 'ZERO' | 'PD' | 'NC');
|
|
3
|
+
export type RouteConfig = {
|
|
4
|
+
path: string;
|
|
5
|
+
label?: string;
|
|
6
|
+
icon?: React.ReactNode;
|
|
7
|
+
element: React.ReactNode;
|
|
8
|
+
children?: RouteConfig[];
|
|
9
|
+
hidden?: boolean;
|
|
10
|
+
};
|
|
11
|
+
export type Partner = {
|
|
12
|
+
logo: string;
|
|
13
|
+
name: string;
|
|
14
|
+
url?: string;
|
|
15
|
+
};
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { FeatureCollection } from "geojson";
|
|
2
|
+
export interface IBaseRecordToGeojsonPoint {
|
|
3
|
+
data: {
|
|
4
|
+
[key: string]: any;
|
|
5
|
+
}[];
|
|
6
|
+
x: string;
|
|
7
|
+
y: string;
|
|
8
|
+
crs_name?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface FeatureCollection_crs extends FeatureCollection {
|
|
11
|
+
crs?: any;
|
|
12
|
+
}
|
|
13
|
+
export declare const BaseRecordToGeojsonPoint: ({ data, x, y, crs_name }: IBaseRecordToGeojsonPoint) => FeatureCollection_crs;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
;
|
|
2
|
+
export const BaseRecordToGeojsonPoint = ({ data, x, y, crs_name }) => {
|
|
3
|
+
//Tester maplibre avec CRS != 4326
|
|
4
|
+
const features = data.map((e) => ({
|
|
5
|
+
type: "Feature",
|
|
6
|
+
properties: { ...e },
|
|
7
|
+
geometry: {
|
|
8
|
+
type: "Point",
|
|
9
|
+
coordinates: [e[y], e[x]]
|
|
10
|
+
}
|
|
11
|
+
}));
|
|
12
|
+
const geojson = { "type": "FeatureCollection", features: features };
|
|
13
|
+
if (crs_name) {
|
|
14
|
+
geojson.crs = { type: "name", properties: { "name": crs_name } }; //no longer supported in geoJSON ? https://github.com/DefinitelyTyped/DefinitelyTyped/issues/21794
|
|
15
|
+
}
|
|
16
|
+
return geojson;
|
|
17
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// From https://www.geeksforgeeks.org/how-to-deep-merge-two-objects-in-typescript/
|
|
2
|
+
function isObject(item) {
|
|
3
|
+
return item !== null && typeof item === 'object' && !Array.isArray(item);
|
|
4
|
+
}
|
|
5
|
+
function deepMerge(target, ...sources) {
|
|
6
|
+
if (!sources.length)
|
|
7
|
+
return target;
|
|
8
|
+
const source = sources.shift();
|
|
9
|
+
if (isObject(target) && isObject(source)) {
|
|
10
|
+
for (const key in source) {
|
|
11
|
+
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
12
|
+
const sourceValue = source[key];
|
|
13
|
+
if (isObject(sourceValue) && isObject(target[key])) {
|
|
14
|
+
target[key] = deepMerge(target[key], sourceValue);
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
target[key] = sourceValue;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return deepMerge(target, ...sources);
|
|
23
|
+
}
|
|
24
|
+
export default deepMerge;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { RouteConfig } from "../types";
|
|
2
|
+
import type { MenuProps } from 'antd';
|
|
3
|
+
type MenuItem = Required<MenuProps>['items'][number];
|
|
4
|
+
export declare const generateRoutes: (routes: RouteConfig[]) => import("react/jsx-runtime").JSX.Element[];
|
|
5
|
+
export declare const generateMenuItems: (routes: RouteConfig[], parentPath?: string) => MenuItem[];
|
|
6
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
//Retourne les routes et le menu
|
|
3
|
+
import { NavLink, Route } from "react-router-dom";
|
|
4
|
+
export const generateRoutes = (routes) => routes.map((route) => (_jsx(Route, { path: route.path, element: !route.children && route.element, children: route.children && generateRoutes(route.children) }, route.path)));
|
|
5
|
+
export const generateMenuItems = (routes, parentPath = "") => routes.filter((route) => route.hidden != true).map((route) => {
|
|
6
|
+
const fullPath = `${parentPath}/${route.path}`;
|
|
7
|
+
const menuItem = {
|
|
8
|
+
key: fullPath,
|
|
9
|
+
label: route.children ? _jsxs(_Fragment, { children: [" ", route.label || route.path] }) : _jsx(NavLink, { to: fullPath, children: route.label || route.path }),
|
|
10
|
+
icon: route.icon,
|
|
11
|
+
...(route.children && { children: generateMenuItems(route.children, fullPath) }), // Ajout conditionnel des enfants
|
|
12
|
+
};
|
|
13
|
+
return menuItem;
|
|
14
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { CrudFilters, CrudSorting, DataProvider, Pagination } from "../data_providers/types";
|
|
2
|
+
interface useApiProps {
|
|
3
|
+
dataProvider: DataProvider;
|
|
4
|
+
resource: string;
|
|
5
|
+
filters?: CrudFilters;
|
|
6
|
+
pagination?: Pagination;
|
|
7
|
+
sorters?: CrudSorting;
|
|
8
|
+
meta?: any;
|
|
9
|
+
enabled?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare const useApi: ({ dataProvider, resource, filters, pagination, sorters, meta, enabled }: useApiProps) => import("@tanstack/react-query").UseQueryResult<import("../data_providers/types").GetListResponse, Error>;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { useQuery } from "@tanstack/react-query";
|
|
2
|
+
export const useApi = ({ dataProvider, resource, filters, pagination, sorters, meta, enabled = true }) => (useQuery({
|
|
3
|
+
queryKey: [dataProvider.getApiUrl, resource, filters, pagination, sorters, meta],
|
|
4
|
+
queryFn: () => dataProvider.getList({
|
|
5
|
+
resource: resource,
|
|
6
|
+
filters: filters,
|
|
7
|
+
pagination: pagination,
|
|
8
|
+
sorters: sorters,
|
|
9
|
+
meta: meta
|
|
10
|
+
}),
|
|
11
|
+
enabled: enabled,
|
|
12
|
+
placeholderData: (prev) => prev,
|
|
13
|
+
staleTime: 5 * 60 * 1e3, //Default staletime 5min
|
|
14
|
+
}));
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ControlPosition } from 'react-map-gl/maplibre';
|
|
2
|
+
interface useMapControlProps {
|
|
3
|
+
mapRef: React.MutableRefObject<any>;
|
|
4
|
+
legendElement: React.ReactElement;
|
|
5
|
+
position?: ControlPosition;
|
|
6
|
+
}
|
|
7
|
+
export declare const useMapControl: ({ mapRef, legendElement, position }: useMapControlProps) => void;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// Ajouter un control (element HTML) sur une carte
|
|
2
|
+
import { useEffect } from "react";
|
|
3
|
+
import { createRoot } from 'react-dom/client';
|
|
4
|
+
export const useMapControl = ({ mapRef, legendElement, position = 'top-right' }) => {
|
|
5
|
+
useEffect(() => {
|
|
6
|
+
if (mapRef?.current) {
|
|
7
|
+
const controlDiv = document.createElement('div');
|
|
8
|
+
const root = createRoot(controlDiv);
|
|
9
|
+
const customControl = {
|
|
10
|
+
onAdd: () => {
|
|
11
|
+
root.render(legendElement);
|
|
12
|
+
return controlDiv;
|
|
13
|
+
},
|
|
14
|
+
onRemove: () => {
|
|
15
|
+
controlDiv.parentNode?.removeChild(controlDiv);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
mapRef?.current?.getMap().addControl(customControl, position);
|
|
19
|
+
return () => {
|
|
20
|
+
customControl.onRemove();
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
}, [mapRef?.current]);
|
|
24
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* See https://blog.logrocket.com/use-state-url-persist-state-usesearchparams/
|
|
3
|
+
*
|
|
4
|
+
* @param searchParamName
|
|
5
|
+
* @param defaultValue
|
|
6
|
+
* @returns searchParamsState & setSearchParamsState
|
|
7
|
+
*/
|
|
8
|
+
export declare function useSearchParamsState(searchParamName: string, defaultValue: string): readonly [
|
|
9
|
+
searchParamsState: string,
|
|
10
|
+
setSearchParamsState: (newState: string) => void
|
|
11
|
+
];
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { useSearchParams } from "react-router-dom";
|
|
2
|
+
/**
|
|
3
|
+
* See https://blog.logrocket.com/use-state-url-persist-state-usesearchparams/
|
|
4
|
+
*
|
|
5
|
+
* @param searchParamName
|
|
6
|
+
* @param defaultValue
|
|
7
|
+
* @returns searchParamsState & setSearchParamsState
|
|
8
|
+
*/
|
|
9
|
+
export function useSearchParamsState(searchParamName, defaultValue) {
|
|
10
|
+
const [searchParams, setSearchParams] = useSearchParams();
|
|
11
|
+
const acquiredSearchParam = searchParams.get(searchParamName);
|
|
12
|
+
const searchParamsState = acquiredSearchParam ?? defaultValue;
|
|
13
|
+
const setSearchParamsState = (newState) => {
|
|
14
|
+
const next = Object.assign({}, [...searchParams.entries()].reduce((o, [key, value]) => ({ ...o, [key]: value }), {}), { [searchParamName]: newState });
|
|
15
|
+
setSearchParams(next);
|
|
16
|
+
};
|
|
17
|
+
return [searchParamsState, setSearchParamsState];
|
|
18
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { MutableRefObject } from "react";
|
|
2
|
+
export interface useChartExportProps {
|
|
3
|
+
chartRef?: MutableRefObject<any>;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Hook personnalisé pour exporter une image à partir d'une instance ECharts.
|
|
7
|
+
* @param {Object} props - Les propriétés du hook.
|
|
8
|
+
* @param {MutableRefObject<any>} props.chartRef - La référence de l'instance ECharts.
|
|
9
|
+
* @returns {Object} - Un objet contenant l'URL de l'image générée et la fonction pour déclencher l'export.
|
|
10
|
+
*
|
|
11
|
+
* @exemple
|
|
12
|
+
* const {img64, exportImage} = useChartExport({chartRef:chartRef})
|
|
13
|
+
*/
|
|
14
|
+
export declare const useChartExport: ({ chartRef }: useChartExportProps) => {
|
|
15
|
+
img64: undefined;
|
|
16
|
+
exportImage: () => void;
|
|
17
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Fonction pour obtenir l'export (img64) d'un echarts ou d'un maplibre
|
|
4
|
+
* @param ref - Référence de l'objet (echarts ou maplibre)
|
|
5
|
+
* @returns - L'image en base64
|
|
6
|
+
*/
|
|
7
|
+
const getDataURL = (ref) => {
|
|
8
|
+
if ('getCanvas' in ref.current) { //maplibre
|
|
9
|
+
return ref.current.getCanvas().toDataURL();
|
|
10
|
+
}
|
|
11
|
+
else if ('getEchartsInstance' in ref.current) { //Echart
|
|
12
|
+
return ref.current.getEchartsInstance().getDataURL({ backgroundColor: '#fff' });
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Hook personnalisé pour exporter une image à partir d'une instance ECharts.
|
|
17
|
+
* @param {Object} props - Les propriétés du hook.
|
|
18
|
+
* @param {MutableRefObject<any>} props.chartRef - La référence de l'instance ECharts.
|
|
19
|
+
* @returns {Object} - Un objet contenant l'URL de l'image générée et la fonction pour déclencher l'export.
|
|
20
|
+
*
|
|
21
|
+
* @exemple
|
|
22
|
+
* const {img64, exportImage} = useChartExport({chartRef:chartRef})
|
|
23
|
+
*/
|
|
24
|
+
export const useChartExport = ({ chartRef }) => {
|
|
25
|
+
const [img64, setImage64] = useState();
|
|
26
|
+
const [exportRequested, setExportRequested] = useState(false); // Suivre l'état de l'export
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
if (chartRef?.current && exportRequested) {
|
|
29
|
+
const dataURL = getDataURL(chartRef);
|
|
30
|
+
setImage64(dataURL);
|
|
31
|
+
setExportRequested(false);
|
|
32
|
+
}
|
|
33
|
+
}, [chartRef, exportRequested]);
|
|
34
|
+
const exportImage = () => {
|
|
35
|
+
console.log('called');
|
|
36
|
+
setExportRequested(true);
|
|
37
|
+
};
|
|
38
|
+
return { img64, exportImage };
|
|
39
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { MutableRefObject } from "react";
|
|
2
|
+
export interface useChartEventsProps {
|
|
3
|
+
/** La référence du graphique */
|
|
4
|
+
chartRef: MutableRefObject<any>;
|
|
5
|
+
/** Fonction appelée lors du click Généralement c'est un setStat() */
|
|
6
|
+
onClick?: Function;
|
|
7
|
+
/** Fonction appelée lors du mouse-over ET mouse-out (avec paramètre null pour le mouse-out). Généralement c'est un setStat() */
|
|
8
|
+
onFocus?: (e: any) => void;
|
|
9
|
+
}
|
|
10
|
+
/** Hook permettant de récupérer les évenements click et mouseover/mouseout d'un graphique ECharts
|
|
11
|
+
* @category Hook
|
|
12
|
+
*/
|
|
13
|
+
export declare const useChartEvents: ({ chartRef, onClick, onFocus }: useChartEventsProps) => void;
|
|
14
|
+
export interface useChartActionProps {
|
|
15
|
+
/** La référence du graphique */
|
|
16
|
+
chartRef: MutableRefObject<any>;
|
|
17
|
+
/** La cible à focus (cf. https://echarts.apache.org/en/api.html#action.highlight). En general {name:value} pour les donut et sankey, {seriesName} pour les bar et line */
|
|
18
|
+
target: Partial<{
|
|
19
|
+
[key in 'seriesIndex' | 'seriesId' | 'seriesName' | 'name' | 'dataIndex']: any;
|
|
20
|
+
}>;
|
|
21
|
+
}
|
|
22
|
+
/** Hook permettant de highlight un élément d'un graphique ECharts
|
|
23
|
+
* @category Hook
|
|
24
|
+
*/
|
|
25
|
+
export declare const useChartActionHightlight: ({ chartRef, target }: useChartActionProps) => void;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
/** Hook permettant de récupérer les évenements click et mouseover/mouseout d'un graphique ECharts
|
|
3
|
+
* @category Hook
|
|
4
|
+
*/
|
|
5
|
+
export const useChartEvents = ({ chartRef, onClick, onFocus }) => {
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
if (chartRef.current) { //Factoriser pour les différents type d'évenment ?
|
|
8
|
+
const mychart = chartRef.current.getEchartsInstance();
|
|
9
|
+
const handleMouseOver = onFocus ? (e) => onFocus(e) : undefined;
|
|
10
|
+
const handleMouseOut = onFocus ? () => onFocus(null) : undefined; //Retourner plutôt un '' ?
|
|
11
|
+
const handleClick = onClick ? (e) => onClick(e) : undefined;
|
|
12
|
+
if (handleMouseOver) {
|
|
13
|
+
mychart.on('mouseover', handleMouseOver);
|
|
14
|
+
mychart.on('mouseout', handleMouseOut);
|
|
15
|
+
}
|
|
16
|
+
if (handleClick) {
|
|
17
|
+
mychart.on('click', handleClick);
|
|
18
|
+
}
|
|
19
|
+
return () => {
|
|
20
|
+
if (onFocus) {
|
|
21
|
+
mychart.off('mouseover', handleMouseOver);
|
|
22
|
+
mychart.off('mouseout', handleMouseOut);
|
|
23
|
+
}
|
|
24
|
+
if (onClick) {
|
|
25
|
+
mychart.off('mouseover', handleClick);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
}, [chartRef, onClick, onFocus]);
|
|
30
|
+
};
|
|
31
|
+
/** Hook permettant de highlight un élément d'un graphique ECharts
|
|
32
|
+
* @category Hook
|
|
33
|
+
*/
|
|
34
|
+
export const useChartActionHightlight = ({ chartRef, target }) => {
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
if (chartRef.current) {
|
|
37
|
+
const mychart = chartRef.current.getEchartsInstance();
|
|
38
|
+
mychart.dispatchAction({ type: 'downplay' });
|
|
39
|
+
if (target.seriesIndex || target.seriesId || target.seriesName || target.name || target.dataIndex) {
|
|
40
|
+
mychart.dispatchAction({ type: 'highlight', ...target });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}, [chartRef, target]);
|
|
44
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@geo2france/api-dashboard",
|
|
3
|
+
"version": "1.5.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"description": "Build dashboards with JSX/TSX",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+ssh://git@github.com/geo2france/api-dashboard.git"
|
|
11
|
+
},
|
|
12
|
+
"author": {
|
|
13
|
+
"name": "Jean-Baptiste Desbas",
|
|
14
|
+
"email": "jb@desbas.fr",
|
|
15
|
+
"url": "http://jb.desbas.fr"
|
|
16
|
+
},
|
|
17
|
+
"licence": "MIT",
|
|
18
|
+
"keywords": [
|
|
19
|
+
"dashboard",
|
|
20
|
+
"territories",
|
|
21
|
+
"dataviz"
|
|
22
|
+
],
|
|
23
|
+
"files": [
|
|
24
|
+
"dist"
|
|
25
|
+
],
|
|
26
|
+
"exports": {
|
|
27
|
+
".": {
|
|
28
|
+
"import": "./dist/index.js",
|
|
29
|
+
"types": "./dist/index.d.ts"
|
|
30
|
+
},
|
|
31
|
+
"./dsl": {
|
|
32
|
+
"import": "./dist/dsl/index.js",
|
|
33
|
+
"types": "./dist/dsl/index.d.ts"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"typesVersions": {
|
|
37
|
+
"*": {
|
|
38
|
+
"dsl": [
|
|
39
|
+
"dist/dsl/index.d.ts"
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"scripts": {
|
|
44
|
+
"tsc": "tsc",
|
|
45
|
+
"test": "jest --watchAll"
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"alasql": "^4.6.6",
|
|
49
|
+
"arquero": "^8.0.3",
|
|
50
|
+
"axios": "^1.7.4",
|
|
51
|
+
"chroma-js": "^3.1.2",
|
|
52
|
+
"echarts": "^5.5.1",
|
|
53
|
+
"echarts-for-react": "^3.0.2",
|
|
54
|
+
"query-string": "~7.1.3",
|
|
55
|
+
"react-helmet": "^6.1.0",
|
|
56
|
+
"react-helmet-async": "^2.0.5",
|
|
57
|
+
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz"
|
|
58
|
+
},
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"@tanstack/react-query": "^5.51.11",
|
|
61
|
+
"@testing-library/dom": "^10.4.0",
|
|
62
|
+
"@testing-library/jest-dom": "^6.5.0",
|
|
63
|
+
"@testing-library/react": "^16.0.1",
|
|
64
|
+
"@testing-library/user-event": "^14.5.2",
|
|
65
|
+
"@types/chroma-js": "^3.1.1",
|
|
66
|
+
"@types/geojson": "^7946.0.14",
|
|
67
|
+
"@types/jest": "^29.5.13",
|
|
68
|
+
"@types/node": "^22.7.4",
|
|
69
|
+
"@types/react": "^18.3.10",
|
|
70
|
+
"@types/react-dom": "^18.3.0",
|
|
71
|
+
"@types/react-helmet-async": "^1.0.1",
|
|
72
|
+
"@types/react-icons": "^2.2.7",
|
|
73
|
+
"@typescript-eslint/eslint-plugin": "^7.16.1",
|
|
74
|
+
"@typescript-eslint/parser": "^7.16.1",
|
|
75
|
+
"@vitejs/plugin-react": "^4.3.1",
|
|
76
|
+
"antd": "^5.24.3",
|
|
77
|
+
"jest": "^29.7.0",
|
|
78
|
+
"jest-environment-jsdom": "^29.7.0",
|
|
79
|
+
"react": "^18.3.1",
|
|
80
|
+
"react-router-dom": "^6.25.1",
|
|
81
|
+
"ts-jest": "^29.2.5",
|
|
82
|
+
"ts-node": "^10.9.2",
|
|
83
|
+
"tsup": "^8.5.0",
|
|
84
|
+
"typescript": "^5.5.2",
|
|
85
|
+
"vite": "^5.3.4",
|
|
86
|
+
"vite-plugin-svgr": "^4.2.0"
|
|
87
|
+
},
|
|
88
|
+
"peerDependencies": {
|
|
89
|
+
"@tanstack/react-query": "^5.51.11",
|
|
90
|
+
"antd": "^5.18.3",
|
|
91
|
+
"react": "^18.3.1",
|
|
92
|
+
"react-dom": "^18.3.1",
|
|
93
|
+
"react-icons": "5.4",
|
|
94
|
+
"react-map-gl": "^7.1.7",
|
|
95
|
+
"react-router-dom": "^6.25.1",
|
|
96
|
+
"recharts": "^2.15.3"
|
|
97
|
+
}
|
|
98
|
+
}
|