@inseefr/lunatic 0.3.2-experimental → 0.3.6-experimental
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/lib/index.js +38 -82
- package/lib/index.js.map +1 -1
- package/package.json +2 -2
- package/src/components/breadcrumb/component.js +29 -29
- package/src/components/button/component.js +53 -53
- package/src/components/button/index.js +1 -1
- package/src/components/checkbox/index.js +3 -3
- package/src/components/datepicker/index.js +1 -1
- package/src/components/declarations/index.js +1 -1
- package/src/components/declarations/wrappers/input-declarations-wrapper.js +28 -7
- package/src/components/declarations/wrappers/list-declarations-wrapper.js +232 -232
- package/src/components/dropdown/commons/components/dropdown.js +21 -0
- package/src/components/dropdown/dropdown-edit/dropdown-edit.js +4 -1
- package/src/components/dropdown/dropdown-simple/dropdown.js +3 -1
- package/src/components/filter-description/component.js +42 -42
- package/src/components/icon/component.js +33 -33
- package/src/components/input/index.js +2 -2
- package/src/components/input/input-number.js +2 -1
- package/src/components/loop/index.js +1 -1
- package/src/components/loop-constructor/wrapper/body-component.js +13 -1
- package/src/components/radio/index.js +1 -1
- package/src/components/sequence/index.js +1 -1
- package/src/components/subsequence/index.js +1 -1
- package/src/components/suggester/check-store.js +70 -70
- package/src/components/suggester/components/suggester-content.js +42 -42
- package/src/components/suggester/components/suggester.js +43 -3
- package/src/components/suggester/idb-suggester.js +7 -1
- package/src/components/suggester/lunatic-suggester.js +1 -0
- package/src/components/suggester/suggester-wrapper.js +6 -0
- package/src/components/tooltip/response.js +52 -52
- package/src/stories/checkbox-boolean/data-forced.json +48 -48
- package/src/stories/icons/icons.stories.js +16 -16
- package/src/stories/questionnaire/kish.json +275 -0
- package/src/stories/questionnaire/logement-queen.json +23390 -23390
- package/src/stories/questionnaire/logement-s2.json +46027 -44536
- package/src/stories/questionnaire/questionnaire.stories.js +14 -2
- package/src/stories/utils/custom-lunatic.scss +23 -23
- package/src/stories/utils/orchestrator-split.js +4 -2
- package/src/stories/utils/orchestrator.js +4 -2
- package/src/tests/components/breadcrumb.spec.js +13 -13
- package/src/tests/components/button.spec.js +11 -11
- package/src/tests/components/checkbox-boolean.spec.js +45 -45
- package/src/tests/components/checkbox-group.spec.js +53 -53
- package/src/tests/components/checkbox-one.spec.js +32 -32
- package/src/tests/components/datepicker.spec.js +22 -22
- package/src/tests/components/declarations-wrappers/input-declarations-wrapper.spec.js +67 -67
- package/src/tests/components/declarations-wrappers/list-declarations-wrapper.spec.js +52 -52
- package/src/tests/components/declarations-wrappers/simple-declarations-wrapper.spec.js +21 -21
- package/src/tests/components/declarations.spec.js +46 -46
- package/src/tests/components/input.spec.js +18 -18
- package/src/tests/components/loops/loop-static.json +66 -66
- package/src/tests/components/loops/loop.json +258 -258
- package/src/tests/components/loops/loop.spec.js +30 -30
- package/src/tests/components/loops/roster-for-loop.spec.js +18 -18
- package/src/tests/components/progress-bar.spec.js +15 -15
- package/src/tests/components/radio.spec.js +27 -27
- package/src/tests/components/sequence.spec.js +9 -9
- package/src/tests/components/subsequence.spec.js +9 -9
- package/src/tests/components/table.spec.js +11 -11
- package/src/tests/components/textarea.spec.js +18 -18
- package/src/tests/components/tooltip.spec.js +25 -25
- package/src/tests/setup/setupTests.js +4 -4
- package/src/tests/utils/lib/alphabet.spec.js +36 -36
- package/src/tests/utils/lib/array.spec.js +22 -22
- package/src/tests/utils/lib/checkbox/group.spec.js +72 -72
- package/src/tests/utils/lib/decorator/title-decorator.spec.js +12 -12
- package/src/tests/utils/lib/input-number.spec.js +18 -18
- package/src/tests/utils/lib/items-positioning.spec.js +17 -17
- package/src/tests/utils/lib/label-position.spec.js +22 -22
- package/src/tests/utils/lib/loops/bindings.spec.js +75 -75
- package/src/tests/utils/lib/loops/shared.spec.js +82 -82
- package/src/tests/utils/lib/missing/missing.spec.js +74 -74
- package/src/tests/utils/lib/missing/mock.js +137 -137
- package/src/tests/utils/lib/pagination/shared.spec.js +42 -42
- package/src/tests/utils/lib/responses.spec.js +64 -64
- package/src/tests/utils/lib/style.spec.js +26 -26
- package/src/tests/utils/lib/tooltip/build-response.spec.js +95 -95
- package/src/tests/utils/lib/tooltip/content.spec.js +109 -109
- package/src/tests/utils/to-expose/handler/handler.spec.js +94 -94
- package/src/tests/utils/to-expose/handler/questionnaire.json +158 -158
- package/src/tests/utils/to-expose/handler/results/index.js +6 -6
- package/src/tests/utils/to-expose/handler/results/res-double.json +158 -158
- package/src/tests/utils/to-expose/handler/results/res-input-collected.json +158 -158
- package/src/tests/utils/to-expose/handler/results/res-input-edited.json +158 -158
- package/src/tests/utils/to-expose/handler/results/res-loop.json +158 -158
- package/src/tests/utils/to-expose/handler/results/res-matrix.json +158 -158
- package/src/tests/utils/to-expose/handler/results/res-responses.json +158 -158
- package/src/tests/utils/to-expose/hooks/use-lunatic.spec.js +46 -46
- package/src/tests/utils/to-expose/init-questionnaire/data.json +12 -12
- package/src/tests/utils/to-expose/init-questionnaire/init-questionnaire.spec.js +19 -19
- package/src/tests/utils/to-expose/interpret/interpret.spec.js +48 -48
- package/src/tests/utils/to-expose/state/questionnaire.json +61 -61
- package/src/tests/utils/to-expose/state/results.js +78 -78
- package/src/utils/lib/splitting.js +55 -23
- package/src/utils/lib/tooltip/build-response.js +41 -41
- package/src/utils/store-tools/create/index.js +1 -1
- package/src/utils/store-tools/create/update-store-info.js +26 -26
- package/src/utils/store-tools/index.js +5 -5
- package/src/utils/to-expose/handler.js +12 -14
- package/src/utils/to-expose/hooks/lunatic-split.js +44 -27
- package/src/utils/to-expose/hooks/lunatic.js +12 -5
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
CheckboxChecked,
|
|
4
|
-
CheckboxUnchecked,
|
|
5
|
-
RadioChecked,
|
|
6
|
-
RadioUnchecked,
|
|
7
|
-
} from './assets';
|
|
8
|
-
import './icon.scss';
|
|
9
|
-
|
|
10
|
-
const Content = ({ type, checked }) => {
|
|
11
|
-
if (type === 'radio') {
|
|
12
|
-
if (checked) return <RadioChecked />;
|
|
13
|
-
return <RadioUnchecked />;
|
|
14
|
-
}
|
|
15
|
-
if (type === 'checkbox') {
|
|
16
|
-
if (checked) return <CheckboxChecked />;
|
|
17
|
-
return <CheckboxUnchecked />;
|
|
18
|
-
}
|
|
19
|
-
return null;
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
const Icon = ({ type, checked, disabled, children }) => (
|
|
23
|
-
<>
|
|
24
|
-
<span className={`list-icon-wrapper`}>
|
|
25
|
-
<span className={`list-icon ${disabled ? 'list-icon-disabled' : ''}`}>
|
|
26
|
-
<Content type={type} checked={checked} />
|
|
27
|
-
</span>
|
|
28
|
-
{children}
|
|
29
|
-
</span>
|
|
30
|
-
</>
|
|
31
|
-
);
|
|
32
|
-
|
|
33
|
-
export default Icon;
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {
|
|
3
|
+
CheckboxChecked,
|
|
4
|
+
CheckboxUnchecked,
|
|
5
|
+
RadioChecked,
|
|
6
|
+
RadioUnchecked,
|
|
7
|
+
} from './assets';
|
|
8
|
+
import './icon.scss';
|
|
9
|
+
|
|
10
|
+
const Content = ({ type, checked }) => {
|
|
11
|
+
if (type === 'radio') {
|
|
12
|
+
if (checked) return <RadioChecked />;
|
|
13
|
+
return <RadioUnchecked />;
|
|
14
|
+
}
|
|
15
|
+
if (type === 'checkbox') {
|
|
16
|
+
if (checked) return <CheckboxChecked />;
|
|
17
|
+
return <CheckboxUnchecked />;
|
|
18
|
+
}
|
|
19
|
+
return null;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const Icon = ({ type, checked, disabled, children }) => (
|
|
23
|
+
<>
|
|
24
|
+
<span className={`list-icon-wrapper`}>
|
|
25
|
+
<span className={`list-icon ${disabled ? 'list-icon-disabled' : ''}`}>
|
|
26
|
+
<Content type={type} checked={checked} />
|
|
27
|
+
</span>
|
|
28
|
+
{children}
|
|
29
|
+
</span>
|
|
30
|
+
</>
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
export default Icon;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { default as Input } from './input';
|
|
2
|
-
export { default as InputNumber } from './input-number';
|
|
1
|
+
export { default as Input } from './input';
|
|
2
|
+
export { default as InputNumber } from './input-number';
|
|
@@ -6,11 +6,12 @@ import { areEqual } from '../../utils/lib';
|
|
|
6
6
|
import { getTypeControls } from '../component-wrapper/controls/validators';
|
|
7
7
|
import './input.scss';
|
|
8
8
|
|
|
9
|
-
const InputNumber = ({ numberAsTextfield, ...props }) => (
|
|
9
|
+
const InputNumber = ({ numberAsTextfield, decimals, ...props }) => (
|
|
10
10
|
<InputDeclarationsWrapper
|
|
11
11
|
type={numberAsTextfield ? 'text' : 'number'}
|
|
12
12
|
roleType="input"
|
|
13
13
|
{...props}
|
|
14
|
+
decimals={decimals || 0}
|
|
14
15
|
isInputNumber
|
|
15
16
|
numberAsTextfield
|
|
16
17
|
validators={[getTypeControls]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { default } from './wrapper';
|
|
1
|
+
export { default } from './wrapper';
|
|
@@ -23,6 +23,7 @@ const BodyComponent = ({
|
|
|
23
23
|
components,
|
|
24
24
|
headers,
|
|
25
25
|
});
|
|
26
|
+
const featuresWithoutMD = features.filter((f) => f !== 'MD');
|
|
26
27
|
if (componentType === 'RosterForLoop')
|
|
27
28
|
return (
|
|
28
29
|
<table id={`table-${mainId}`} className="table-lunatic">
|
|
@@ -38,10 +39,16 @@ const BodyComponent = ({
|
|
|
38
39
|
componentType,
|
|
39
40
|
id,
|
|
40
41
|
rowNumber,
|
|
42
|
+
conditionFilter,
|
|
41
43
|
...componentProps
|
|
42
44
|
} = component;
|
|
43
45
|
const localBindings =
|
|
44
46
|
U.buildBindingsForDeeperComponents(rowNumber)(bindings);
|
|
47
|
+
if (conditionFilter) {
|
|
48
|
+
const { value = '' } = conditionFilter;
|
|
49
|
+
if (!interpret(featuresWithoutMD)(localBindings)(value))
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
45
52
|
if (componentType) {
|
|
46
53
|
const Component = lunatic[componentType];
|
|
47
54
|
return (
|
|
@@ -101,7 +108,12 @@ const BodyComponent = ({
|
|
|
101
108
|
const localBindings =
|
|
102
109
|
U.buildBindingsForDeeperComponents(i)(bindings);
|
|
103
110
|
// ensure to have only N-1 missingResponse
|
|
104
|
-
const { missingResponse } = componentProps;
|
|
111
|
+
const { missingResponse, conditionFilter } = componentProps;
|
|
112
|
+
if (conditionFilter) {
|
|
113
|
+
const { value = '' } = conditionFilter;
|
|
114
|
+
if (!interpret(featuresWithoutMD)(localBindings)(value))
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
105
117
|
return (
|
|
106
118
|
<div className="block-component" key={`${id}-row-${i}`}>
|
|
107
119
|
<Component
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { default } from './component';
|
|
1
|
+
export { default } from './component';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { default } from './component';
|
|
1
|
+
export { default } from './component';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { default } from './component';
|
|
1
|
+
export { default } from './component';
|
|
@@ -1,70 +1,70 @@
|
|
|
1
|
-
import React, { useEffect, useState, useCallback } from 'react';
|
|
2
|
-
import { openDb, getEntity } from '../../utils/idb-tools';
|
|
3
|
-
import { CONSTANTES } from '../../utils/store-tools';
|
|
4
|
-
|
|
5
|
-
function CheckStore({ storeName, version, setStore, children }) {
|
|
6
|
-
const [ready, setReady] = useState(0);
|
|
7
|
-
const [refresh, setRefresh] = useState(false);
|
|
8
|
-
const [disabled, setDisabled] = useState(false);
|
|
9
|
-
|
|
10
|
-
const checkStore = useCallback(
|
|
11
|
-
async function () {
|
|
12
|
-
try {
|
|
13
|
-
const db = await openDb(storeName, version);
|
|
14
|
-
const info = await getEntity(db, CONSTANTES.STORE_INFO_NAME, storeName);
|
|
15
|
-
|
|
16
|
-
if (db && info) {
|
|
17
|
-
setReady(200);
|
|
18
|
-
setStore(info);
|
|
19
|
-
}
|
|
20
|
-
} catch (e) {
|
|
21
|
-
setReady(400);
|
|
22
|
-
}
|
|
23
|
-
},
|
|
24
|
-
[storeName, version, setStore]
|
|
25
|
-
);
|
|
26
|
-
|
|
27
|
-
useEffect(
|
|
28
|
-
function () {
|
|
29
|
-
checkStore();
|
|
30
|
-
},
|
|
31
|
-
[checkStore]
|
|
32
|
-
);
|
|
33
|
-
|
|
34
|
-
useEffect(
|
|
35
|
-
function () {
|
|
36
|
-
if (refresh) {
|
|
37
|
-
setRefresh(false);
|
|
38
|
-
setDisabled(true);
|
|
39
|
-
async function go() {
|
|
40
|
-
await checkStore();
|
|
41
|
-
setDisabled(false);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
go();
|
|
45
|
-
}
|
|
46
|
-
},
|
|
47
|
-
[refresh]
|
|
48
|
-
);
|
|
49
|
-
|
|
50
|
-
if (ready === 0) {
|
|
51
|
-
return (
|
|
52
|
-
<div className="lunatic-suggester-in-progress">
|
|
53
|
-
Le store {storeName} est en cour de chargement.
|
|
54
|
-
</div>
|
|
55
|
-
);
|
|
56
|
-
}
|
|
57
|
-
if (ready === 200) {
|
|
58
|
-
return children;
|
|
59
|
-
}
|
|
60
|
-
return (
|
|
61
|
-
<div className="lunatic-suggester-unvailable">
|
|
62
|
-
Le store {storeName} n'est pas disponible.
|
|
63
|
-
<button disabled={disabled} onClick={() => setRefresh(true)}>
|
|
64
|
-
Refresh
|
|
65
|
-
</button>
|
|
66
|
-
</div>
|
|
67
|
-
);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export default CheckStore;
|
|
1
|
+
import React, { useEffect, useState, useCallback } from 'react';
|
|
2
|
+
import { openDb, getEntity } from '../../utils/idb-tools';
|
|
3
|
+
import { CONSTANTES } from '../../utils/store-tools';
|
|
4
|
+
|
|
5
|
+
function CheckStore({ storeName, version, setStore, children }) {
|
|
6
|
+
const [ready, setReady] = useState(0);
|
|
7
|
+
const [refresh, setRefresh] = useState(false);
|
|
8
|
+
const [disabled, setDisabled] = useState(false);
|
|
9
|
+
|
|
10
|
+
const checkStore = useCallback(
|
|
11
|
+
async function () {
|
|
12
|
+
try {
|
|
13
|
+
const db = await openDb(storeName, version);
|
|
14
|
+
const info = await getEntity(db, CONSTANTES.STORE_INFO_NAME, storeName);
|
|
15
|
+
|
|
16
|
+
if (db && info) {
|
|
17
|
+
setReady(200);
|
|
18
|
+
setStore(info);
|
|
19
|
+
}
|
|
20
|
+
} catch (e) {
|
|
21
|
+
setReady(400);
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
[storeName, version, setStore]
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
useEffect(
|
|
28
|
+
function () {
|
|
29
|
+
checkStore();
|
|
30
|
+
},
|
|
31
|
+
[checkStore]
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
useEffect(
|
|
35
|
+
function () {
|
|
36
|
+
if (refresh) {
|
|
37
|
+
setRefresh(false);
|
|
38
|
+
setDisabled(true);
|
|
39
|
+
async function go() {
|
|
40
|
+
await checkStore();
|
|
41
|
+
setDisabled(false);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
go();
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
[refresh]
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
if (ready === 0) {
|
|
51
|
+
return (
|
|
52
|
+
<div className="lunatic-suggester-in-progress">
|
|
53
|
+
Le store {storeName} est en cour de chargement.
|
|
54
|
+
</div>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
if (ready === 200) {
|
|
58
|
+
return children;
|
|
59
|
+
}
|
|
60
|
+
return (
|
|
61
|
+
<div className="lunatic-suggester-unvailable">
|
|
62
|
+
Le store {storeName} n'est pas disponible.
|
|
63
|
+
<button disabled={disabled} onClick={() => setRefresh(true)}>
|
|
64
|
+
Refresh
|
|
65
|
+
</button>
|
|
66
|
+
</div>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export default CheckStore;
|
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
import React, { useRef, useCallback } from 'react';
|
|
2
|
-
import classnames from 'classnames';
|
|
3
|
-
import useDocumentAddEventListener from '../../../utils/to-expose/hooks/use-document-add-event-listener';
|
|
4
|
-
|
|
5
|
-
function SuggesterContent({
|
|
6
|
-
children,
|
|
7
|
-
id,
|
|
8
|
-
focused,
|
|
9
|
-
onFocus,
|
|
10
|
-
onBlur,
|
|
11
|
-
onKeyDown,
|
|
12
|
-
}) {
|
|
13
|
-
const ref = useRef();
|
|
14
|
-
const onClick = useCallback(
|
|
15
|
-
function (e) {
|
|
16
|
-
const { current } = ref;
|
|
17
|
-
if (!current.contains(e.target)) {
|
|
18
|
-
onBlur();
|
|
19
|
-
}
|
|
20
|
-
},
|
|
21
|
-
[ref, onBlur]
|
|
22
|
-
);
|
|
23
|
-
|
|
24
|
-
useDocumentAddEventListener('mousedown', onClick);
|
|
25
|
-
|
|
26
|
-
return (
|
|
27
|
-
<div
|
|
28
|
-
className={classnames('lunatic-suggester', {
|
|
29
|
-
focused,
|
|
30
|
-
})}
|
|
31
|
-
onFocus={onFocus}
|
|
32
|
-
onKeyDown={onKeyDown}
|
|
33
|
-
ref={ref}
|
|
34
|
-
>
|
|
35
|
-
<div className={classnames('lunatic-suggester-content', { focused })}>
|
|
36
|
-
{children}
|
|
37
|
-
</div>
|
|
38
|
-
</div>
|
|
39
|
-
);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export default SuggesterContent;
|
|
1
|
+
import React, { useRef, useCallback } from 'react';
|
|
2
|
+
import classnames from 'classnames';
|
|
3
|
+
import useDocumentAddEventListener from '../../../utils/to-expose/hooks/use-document-add-event-listener';
|
|
4
|
+
|
|
5
|
+
function SuggesterContent({
|
|
6
|
+
children,
|
|
7
|
+
id,
|
|
8
|
+
focused,
|
|
9
|
+
onFocus,
|
|
10
|
+
onBlur,
|
|
11
|
+
onKeyDown,
|
|
12
|
+
}) {
|
|
13
|
+
const ref = useRef();
|
|
14
|
+
const onClick = useCallback(
|
|
15
|
+
function (e) {
|
|
16
|
+
const { current } = ref;
|
|
17
|
+
if (!current.contains(e.target) && focused) {
|
|
18
|
+
onBlur();
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
[ref, focused, onBlur]
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
useDocumentAddEventListener('mousedown', onClick);
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<div
|
|
28
|
+
className={classnames('lunatic-suggester', {
|
|
29
|
+
focused,
|
|
30
|
+
})}
|
|
31
|
+
onFocus={onFocus}
|
|
32
|
+
onKeyDown={onKeyDown}
|
|
33
|
+
ref={ref}
|
|
34
|
+
>
|
|
35
|
+
<div className={classnames('lunatic-suggester-content', { focused })}>
|
|
36
|
+
{children}
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export default SuggesterContent;
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, {
|
|
2
|
+
useCallback,
|
|
3
|
+
useContext,
|
|
4
|
+
useRef,
|
|
5
|
+
useMemo,
|
|
6
|
+
useEffect,
|
|
7
|
+
useState,
|
|
8
|
+
} from 'react';
|
|
2
9
|
import classnames from 'classnames';
|
|
3
10
|
import { actions, SuggesterContext } from '../state-management';
|
|
4
11
|
import SuggesterContent from './suggester-content';
|
|
@@ -6,6 +13,8 @@ import Selection from './selection';
|
|
|
6
13
|
import Panel from './panel';
|
|
7
14
|
import createOnKeyDownCallback from './create-on-keydown-callback';
|
|
8
15
|
import Delete from './selection/delete';
|
|
16
|
+
import * as C from '../../../constants';
|
|
17
|
+
import * as U from '../../../utils/lib';
|
|
9
18
|
import './suggester.scss';
|
|
10
19
|
|
|
11
20
|
function Suggester({
|
|
@@ -16,23 +25,54 @@ function Suggester({
|
|
|
16
25
|
labelRenderer,
|
|
17
26
|
onSelect,
|
|
18
27
|
value,
|
|
28
|
+
focused: initFocused,
|
|
29
|
+
response,
|
|
30
|
+
logFunction,
|
|
19
31
|
}) {
|
|
20
32
|
const inputEl = useRef();
|
|
21
33
|
const [state, dispatch] = useContext(SuggesterContext);
|
|
22
34
|
const { focused, id, messageError, search, disabled } = state;
|
|
23
35
|
|
|
36
|
+
const [init, setInit] = useState(false);
|
|
37
|
+
|
|
38
|
+
const createEventFocus = (focusIn = true) =>
|
|
39
|
+
U.createObjectEvent(
|
|
40
|
+
`suggester-${id}`,
|
|
41
|
+
C.INPUT_CATEGORY,
|
|
42
|
+
focusIn ? C.EVENT_FOCUS_IN : C.EVENT_FOCUS_OUT,
|
|
43
|
+
U.getResponseName(response),
|
|
44
|
+
value
|
|
45
|
+
);
|
|
46
|
+
|
|
24
47
|
const onFocus = useCallback(
|
|
25
48
|
function () {
|
|
26
|
-
if (!disabled) {
|
|
49
|
+
if (!focused && !disabled) {
|
|
27
50
|
if (inputEl.current !== document.activeElement) {
|
|
28
51
|
}
|
|
29
52
|
inputEl.current.focus();
|
|
30
53
|
dispatch(actions.onFocus());
|
|
31
54
|
}
|
|
32
55
|
},
|
|
33
|
-
[dispatch,
|
|
56
|
+
[disabled, dispatch, focused]
|
|
34
57
|
);
|
|
35
58
|
|
|
59
|
+
// Handle focused props of Component
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
if (!init && id) {
|
|
62
|
+
if (initFocused && !focused) onFocus();
|
|
63
|
+
setInit(true);
|
|
64
|
+
}
|
|
65
|
+
}, [focused, init, initFocused, onFocus, id]);
|
|
66
|
+
|
|
67
|
+
// log info when focus change
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
if (init && id && focused && U.isFunction(logFunction))
|
|
70
|
+
logFunction(createEventFocus());
|
|
71
|
+
if (init && id && !focused && U.isFunction(logFunction))
|
|
72
|
+
logFunction(createEventFocus(false));
|
|
73
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
74
|
+
}, [focused, id, init]);
|
|
75
|
+
|
|
36
76
|
const onDelete = useCallback(
|
|
37
77
|
function () {
|
|
38
78
|
dispatch(actions.onDeleteSearch());
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { useMemo, useState } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import SuggesterWrapper from './suggester-wrapper';
|
|
4
4
|
import createSearching from './searching';
|
|
@@ -15,6 +15,9 @@ function IDBSuggester({
|
|
|
15
15
|
onSelect,
|
|
16
16
|
disabled,
|
|
17
17
|
value,
|
|
18
|
+
focused,
|
|
19
|
+
response,
|
|
20
|
+
logFunction,
|
|
18
21
|
}) {
|
|
19
22
|
const [store, setStore] = useState(undefined);
|
|
20
23
|
const searching = useMemo(
|
|
@@ -44,6 +47,9 @@ function IDBSuggester({
|
|
|
44
47
|
storeName={storeName}
|
|
45
48
|
disabled={disabled}
|
|
46
49
|
value={value}
|
|
50
|
+
focused={focused}
|
|
51
|
+
response={response}
|
|
52
|
+
logFunction={logFunction}
|
|
47
53
|
/>
|
|
48
54
|
</CheckStore>
|
|
49
55
|
);
|
|
@@ -30,6 +30,9 @@ function SuggesterWrapper({
|
|
|
30
30
|
labelRenderer,
|
|
31
31
|
disabled,
|
|
32
32
|
value,
|
|
33
|
+
focused,
|
|
34
|
+
response,
|
|
35
|
+
logFunction,
|
|
33
36
|
}) {
|
|
34
37
|
const [state, dispatch] = useReducer(reducer, INITIAL_STATE);
|
|
35
38
|
const { search, selectedIndex, options, expended } = state;
|
|
@@ -82,6 +85,9 @@ function SuggesterWrapper({
|
|
|
82
85
|
labelRenderer={labelRenderer}
|
|
83
86
|
onSelect={onSelect}
|
|
84
87
|
value={value}
|
|
88
|
+
focused={focused}
|
|
89
|
+
response={response}
|
|
90
|
+
logFunction={logFunction}
|
|
85
91
|
/>
|
|
86
92
|
</SuggesterContext.Provider>
|
|
87
93
|
);
|
|
@@ -1,52 +1,52 @@
|
|
|
1
|
-
import React, { useState, useEffect } from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
|
-
import ReactTooltip from 'react-tooltip';
|
|
4
|
-
import * as U from '../../utils/lib';
|
|
5
|
-
import * as img from './img';
|
|
6
|
-
import './tooltip.scss';
|
|
7
|
-
|
|
8
|
-
const TooltipResponse = ({ id, response }) => {
|
|
9
|
-
const [tooltipElements, setTooltipElements] = useState(() =>
|
|
10
|
-
U.buildTooltip(response)
|
|
11
|
-
);
|
|
12
|
-
|
|
13
|
-
useEffect(() => {
|
|
14
|
-
setTooltipElements(U.buildTooltip(response));
|
|
15
|
-
}, [response]);
|
|
16
|
-
|
|
17
|
-
const { content, imgName } = tooltipElements;
|
|
18
|
-
|
|
19
|
-
if (!content) return null;
|
|
20
|
-
|
|
21
|
-
const text = content
|
|
22
|
-
.map(({ key, value }) => `${key} : ${value}<br />`)
|
|
23
|
-
.join('');
|
|
24
|
-
|
|
25
|
-
return (
|
|
26
|
-
<div className="tooltip-lunatic">
|
|
27
|
-
<span
|
|
28
|
-
data-for={`${id}-management-tooltip`}
|
|
29
|
-
data-tip={text}
|
|
30
|
-
data-multiline
|
|
31
|
-
>
|
|
32
|
-
<img id={id} alt="img-tooltip" src={img[imgName].src || img[imgName]} />
|
|
33
|
-
</span>
|
|
34
|
-
<ReactTooltip
|
|
35
|
-
id={`${id}-management-tooltip`}
|
|
36
|
-
className="tooltip-text"
|
|
37
|
-
place="left"
|
|
38
|
-
/>
|
|
39
|
-
</div>
|
|
40
|
-
);
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
TooltipResponse.defaultProps = {
|
|
44
|
-
response: {},
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
TooltipResponse.propTypes = {
|
|
48
|
-
id: PropTypes.string,
|
|
49
|
-
response: U.responsePropTypes,
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
export default TooltipResponse;
|
|
1
|
+
import React, { useState, useEffect } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import ReactTooltip from 'react-tooltip';
|
|
4
|
+
import * as U from '../../utils/lib';
|
|
5
|
+
import * as img from './img';
|
|
6
|
+
import './tooltip.scss';
|
|
7
|
+
|
|
8
|
+
const TooltipResponse = ({ id, response }) => {
|
|
9
|
+
const [tooltipElements, setTooltipElements] = useState(() =>
|
|
10
|
+
U.buildTooltip(response)
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
setTooltipElements(U.buildTooltip(response));
|
|
15
|
+
}, [response]);
|
|
16
|
+
|
|
17
|
+
const { content, imgName } = tooltipElements;
|
|
18
|
+
|
|
19
|
+
if (!content) return null;
|
|
20
|
+
|
|
21
|
+
const text = content
|
|
22
|
+
.map(({ key, value }) => `${key} : ${value}<br />`)
|
|
23
|
+
.join('');
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<div className="tooltip-lunatic">
|
|
27
|
+
<span
|
|
28
|
+
data-for={`${id}-management-tooltip`}
|
|
29
|
+
data-tip={text}
|
|
30
|
+
data-multiline
|
|
31
|
+
>
|
|
32
|
+
<img id={id} alt="img-tooltip" src={img[imgName].src || img[imgName]} />
|
|
33
|
+
</span>
|
|
34
|
+
<ReactTooltip
|
|
35
|
+
id={`${id}-management-tooltip`}
|
|
36
|
+
className="tooltip-text"
|
|
37
|
+
place="left"
|
|
38
|
+
/>
|
|
39
|
+
</div>
|
|
40
|
+
);
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
TooltipResponse.defaultProps = {
|
|
44
|
+
response: {},
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
TooltipResponse.propTypes = {
|
|
48
|
+
id: PropTypes.string,
|
|
49
|
+
response: U.responsePropTypes,
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export default TooltipResponse;
|