@geo2france/api-dashboard 1.11.1 → 1.11.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -25,6 +25,7 @@ type dataset = {
25
25
  isError: boolean;
26
26
  producers?: any[];
27
27
  geojson?: any;
28
+ dataHash?: number;
28
29
  };
29
30
  type ControlContextType = {
30
31
  values: Record<string, any>;
@@ -4,11 +4,12 @@ import { useApi } from "../..";
4
4
  import { ControlContext, DatasetRegistryContext } from "../DashboardPage/Page";
5
5
  import { Producer } from "./Producer";
6
6
  import React from "react";
7
- import { Filter, Transform, useAllDatasets } from "../../dsl";
7
+ import { Filter, Transform, useAllDatasets, useDatasets } from "../../dsl";
8
8
  import alasql from "alasql";
9
9
  import { DataProviderContext, getProviderFromType } from "./Provider";
10
10
  import { Join } from "./Join";
11
11
  import { from } from "arquero";
12
+ import hashCode from "../../utils/hash_data";
12
13
  export const DSL_Dataset = ({ children, id, provider: provider_input, type: providerType = 'file', url: providerUrl, resource, pageSize, meta }) => {
13
14
  const getTransformerFn = (component) => {
14
15
  /*
@@ -37,9 +38,16 @@ export const DSL_Dataset = ({ children, id, provider: provider_input, type: prov
37
38
  inner: { left: false, right: false },
38
39
  }[join_type] ?? { left: false, right: false };
39
40
  const otherData = allDatasets?.find((d) => d.id === props.dataset)?.data;
40
- if (!otherData || otherData.length < 1)
41
+ // Return undefinied if otherData is Fetching ?
42
+ if (!otherData || !data)
41
43
  return undefined; // prevent arquero from crash on missed data
42
- return from(data).join(from(otherData), props.joinKey, undefined, aq_join_option).objects();
44
+ //fallback if one of dataset is empty. Build a 1 row table with existing joinKey
45
+ const [leftKey, rightKey] = Array.isArray(props.joinKey) // joinKey can be a string or un string[]
46
+ ? props.joinKey
47
+ : [props.joinKey, props.joinKey];
48
+ const leftTable = data.length >= 1 ? data : [{ [leftKey]: null }];
49
+ const rightTable = otherData.length >= 1 ? otherData : [{ [rightKey]: null }];
50
+ return from(leftTable).join(from(rightTable), props.joinKey, undefined, aq_join_option).objects();
43
51
  };
44
52
  return funct;
45
53
  }
@@ -49,7 +57,6 @@ export const DSL_Dataset = ({ children, id, provider: provider_input, type: prov
49
57
  };
50
58
  const datasetRegistryContext = useContext(DatasetRegistryContext);
51
59
  const allDatasets = useAllDatasets();
52
- const someFetching = !!allDatasets?.some(d => d.isFetching);
53
60
  const controlContext = useContext(ControlContext);
54
61
  const controls = controlContext?.values;
55
62
  const providerContext = useContext(DataProviderContext);
@@ -70,12 +77,15 @@ export const DSL_Dataset = ({ children, id, provider: provider_input, type: prov
70
77
  });
71
78
  });
72
79
  const { data, isFetching, isError } = useApi({ dataProvider: provider, resource: resource, filters: filters, pagination: { pageSize: pageSize }, meta: meta });
80
+ const dep_dataset_id = []; // Dependencies
73
81
  const transformers = [];
74
82
  /* Récuperer les fonctions transformers */
75
83
  React.Children.toArray(children)
76
84
  .filter((c) => React.isValidElement(c))
77
85
  .filter((c) => typeof c.type != 'string' && (c.type.name == Transform.name || c.type.name == Join.name)).forEach((c) => {
78
86
  transformers.push(getTransformerFn(c));
87
+ if (typeof c.type != 'string' && c.type.name == Join.name)
88
+ dep_dataset_id.push(c.props.dataset); // Add joint dataset in dep list
79
89
  });
80
90
  const producers = [];
81
91
  React.Children.toArray(children)
@@ -83,12 +93,24 @@ export const DSL_Dataset = ({ children, id, provider: provider_input, type: prov
83
93
  .filter((c) => typeof c.type != 'string' && c.type.name == Producer.name).forEach((c) => {
84
94
  producers.push({ nom: c.props.children, url: c.props.url });
85
95
  });
96
+ const depDataset = useDatasets(dep_dataset_id);
97
+ const depDataHash = depDataset?.map(d => d?.dataHash); //Build hash array from data
98
+ const someDepsAreFetching = depDataset?.some(d => d?.isFetching);
86
99
  useEffect(() => {
87
100
  const finalData = data?.data && transformers.reduce((datat, fn) => fn(datat), data.data);
88
101
  if (datasetRegistryContext) {
89
- datasetRegistryContext({ id: id, resource: resource, data: finalData, isFetching: isFetching, isError: isError, producers: producers, geojson: data?.geojson });
102
+ datasetRegistryContext({
103
+ id: id,
104
+ resource: resource,
105
+ data: finalData,
106
+ isFetching: !!isFetching || !!someDepsAreFetching,
107
+ isError: isError,
108
+ producers: producers,
109
+ geojson: data?.geojson,
110
+ dataHash: hashCode(finalData)
111
+ });
90
112
  //Ajouter une info pour distinguer les erreurs du fourniseurs et celles des transformers ?
91
113
  }
92
- }, [resource, data, isFetching, someFetching, children]);
114
+ }, [resource, data, (!!isFetching || !!someDepsAreFetching), hashCode(depDataHash), children]);
93
115
  return (_jsx(_Fragment, { children: children }));
94
116
  };
@@ -6,6 +6,7 @@ export declare const useDataset: (dataset_id?: string) => {
6
6
  isError: boolean;
7
7
  producers?: any[];
8
8
  geojson?: any;
9
+ dataHash?: number;
9
10
  } | undefined;
10
11
  export declare const useDatasets: (dataset_ids?: string[]) => {
11
12
  id: string;
@@ -15,6 +16,7 @@ export declare const useDatasets: (dataset_ids?: string[]) => {
15
16
  isError: boolean;
16
17
  producers?: any[];
17
18
  geojson?: any;
19
+ dataHash?: number;
18
20
  }[] | undefined;
19
21
  export declare const useAllDatasets: () => {
20
22
  id: string;
@@ -24,4 +26,5 @@ export declare const useAllDatasets: () => {
24
26
  isError: boolean;
25
27
  producers?: any[];
26
28
  geojson?: any;
29
+ dataHash?: number;
27
30
  }[] | undefined;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Returns a hash code from a string
3
+ * From https://stackoverflow.com/a/8831937/10995624
4
+ * @param {String} str The string to hash.
5
+ * @return {Number} A 32bit integer
6
+ * @see http://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/
7
+ */
8
+ declare function hashCode(input: any): number | undefined;
9
+ export default hashCode;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Returns a hash code from a string
3
+ * From https://stackoverflow.com/a/8831937/10995624
4
+ * @param {String} str The string to hash.
5
+ * @return {Number} A 32bit integer
6
+ * @see http://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/
7
+ */
8
+ function hashCode(input) {
9
+ if (input === undefined)
10
+ return undefined;
11
+ let hash = 0;
12
+ const str = JSON.stringify(input);
13
+ for (let i = 0, len = str.length; i < len; i++) {
14
+ let chr = str.charCodeAt(i);
15
+ hash = (hash << 5) - hash + chr;
16
+ hash |= 0; // Convert to 32bit integer
17
+ }
18
+ return hash;
19
+ }
20
+ export default hashCode;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geo2france/api-dashboard",
3
- "version": "1.11.1",
3
+ "version": "1.11.2",
4
4
  "private": false,
5
5
  "description": "Build dashboards with JSX/TSX",
6
6
  "main": "dist/index.js",