@flowerforce/flower-react 3.7.2 → 4.0.1-beta.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 +290 -199
- package/dist/index.cjs.js +427 -670
- package/dist/index.esm.js +409 -654
- package/dist/src/components/Flower.d.ts +3 -15
- package/dist/src/components/FlowerAction.d.ts +2 -3
- package/dist/src/components/FlowerComponent.d.ts +2 -4
- package/dist/src/components/FlowerFlow.d.ts +2 -3
- package/dist/src/components/FlowerNavigate/FlowerNavigate.d.ts +3 -0
- package/dist/src/components/FlowerNavigate/WrapperComponent.d.ts +3 -3
- package/dist/src/components/FlowerNavigate/index.d.ts +2 -4
- package/dist/src/components/FlowerNavigate/useFlowerNavigate.d.ts +1 -1
- package/dist/src/components/FlowerNode.d.ts +2 -3
- package/dist/src/components/FlowerRoute.d.ts +2 -3
- package/dist/src/components/FlowerServer.d.ts +2 -3
- package/dist/src/components/FlowerStart.d.ts +3 -4
- package/dist/src/components/hooks/eventsHandlers.d.ts +5 -0
- package/dist/src/components/hooks/index.d.ts +5 -0
- package/dist/src/components/hooks/types/index.d.ts +29 -0
- package/dist/src/components/hooks/useBrowserNavigationSync.d.ts +12 -0
- package/dist/src/components/hooks/useDestroyFlow.d.ts +2 -0
- package/dist/src/components/hooks/useInitDevtools.d.ts +2 -0
- package/dist/src/components/hooks/useInitNodes.d.ts +2 -0
- package/dist/src/components/hooks/useSelectorsClient.d.ts +6 -0
- package/dist/src/components/index.d.ts +10 -0
- package/dist/src/components/{useFlower.d.ts → useFlower/index.d.ts} +2 -3
- package/dist/src/components/useFlower/utils.d.ts +22 -0
- package/dist/src/features/index.d.ts +2 -0
- package/dist/src/features/reducer/flowerReducer.d.ts +7 -0
- package/dist/src/{selectors.d.ts → features/selectors/selectors.d.ts} +669 -383
- package/dist/src/index.d.ts +6 -33
- package/dist/src/provider/createSliceWithFlower.d.ts +2 -0
- package/dist/src/provider/createStoreWithFlower.d.ts +8 -0
- package/dist/src/provider/index.d.ts +3 -0
- package/dist/src/provider/provider.d.ts +7 -0
- package/dist/src/types/FlowContext.d.ts +6 -0
- package/dist/src/types/Flower.d.ts +15 -0
- package/dist/src/types/FlowerHooks.d.ts +27 -0
- package/dist/src/{components/types → types}/FlowerProvider.d.ts +3 -3
- package/dist/src/types/index.d.ts +10 -0
- package/dist/src/types/middlewares.d.ts +16 -0
- package/dist/src/types/utilsTypes.d.ts +4 -0
- package/dist/src/utils.d.ts +2 -10
- package/package.json +15 -7
- package/dist/src/components/FlowerField.d.ts +0 -4
- package/dist/src/components/FlowerRule.d.ts +0 -4
- package/dist/src/components/FlowerValue.d.ts +0 -4
- package/dist/src/components/types/FlowerField.d.ts +0 -124
- package/dist/src/components/types/FlowerHooks.d.ts +0 -72
- package/dist/src/components/types/FlowerRule.d.ts +0 -35
- package/dist/src/components/types/FlowerValue.d.ts +0 -33
- package/dist/src/components/useFlowerForm.d.ts +0 -26
- package/dist/src/context.d.ts +0 -10
- package/dist/src/provider.d.ts +0 -25
- package/dist/src/reducer.d.ts +0 -7
- /package/dist/src/{components/types → types}/DefaultNode.d.ts +0 -0
- /package/dist/src/{components/types → types}/FlowerComponent.d.ts +0 -0
- /package/dist/src/{components/types → types}/FlowerFlow.d.ts +0 -0
- /package/dist/src/{components/types → types}/FlowerNavigate.d.ts +0 -0
- /package/dist/src/{components/types → types}/FlowerNode.d.ts +0 -0
- /package/dist/src/{components/types → types}/FlowerRoute.d.ts +0 -0
- /package/dist/src/{components/types → types}/FlowerServer.d.ts +0 -0
package/dist/index.esm.js
CHANGED
@@ -1,122 +1,103 @@
|
|
1
|
-
import React, {
|
1
|
+
import React, { useEffect, memo, useRef, useState, useMemo, Children, useContext, useCallback } from 'react';
|
2
2
|
import _keyBy from 'lodash/keyBy';
|
3
|
-
import {
|
3
|
+
import { FlowUtils, FlowerCoreBaseReducers, REDUCER_NAME, FlowerCoreStateSelectors, FlowerStateUtils, Emitter, devtoolState } from '@flowerforce/flower-core';
|
4
|
+
import { FlowerReactProvider, FlowerReactContext } from '@flowerforce/flower-react-context';
|
4
5
|
import _get from 'lodash/get';
|
5
|
-
import {
|
6
|
+
import { reducerData, ReduxFlowerProvider, flowerDataActions, middlewares } from '@flowerforce/flower-react-store';
|
7
|
+
export { createApi } from '@flowerforce/flower-react-store';
|
8
|
+
import { createSlice, configureStore, combineReducers, createAction } from '@reduxjs/toolkit';
|
6
9
|
import { createSelector } from 'reselect';
|
7
|
-
import {
|
8
|
-
|
9
|
-
import
|
10
|
+
import { useHistoryContext } from '@flowerforce/flower-react-history-context';
|
11
|
+
export { HistoryContextProvider } from '@flowerforce/flower-react-history-context';
|
12
|
+
import { FlowerRule } from '@flowerforce/flower-react-shared';
|
13
|
+
import set from 'lodash/set';
|
10
14
|
|
11
|
-
const
|
12
|
-
|
13
|
-
const Provider = _context.Provider;
|
14
|
-
const Consumer = _context.Consumer;
|
15
|
-
|
16
|
-
// eslint-disable-next-line import/prefer-default-export
|
17
|
-
const convertElements = (nodes) => {
|
18
|
-
const res = CoreUtils.generateNodesForFlowerJson(nodes);
|
19
|
-
return res;
|
15
|
+
const getRulesExists = (rules) => {
|
16
|
+
return Object.keys(rules).length ? FlowUtils.mapEdge(rules) : undefined;
|
20
17
|
};
|
18
|
+
function hasDisplayName(type) {
|
19
|
+
return (!!type &&
|
20
|
+
typeof type === 'object' &&
|
21
|
+
'displayName' in type &&
|
22
|
+
typeof type.displayName === 'string');
|
23
|
+
}
|
24
|
+
const generateNodesForFlowerJson = (nodes) => nodes
|
25
|
+
.filter((child) => typeof child === 'object' && child !== null && 'props' in child)
|
26
|
+
.filter((e) => !!_get(e, 'props.id'))
|
27
|
+
.map((e) => {
|
28
|
+
const rules = FlowUtils.makeRules(e.props.to ?? {});
|
29
|
+
const nextRules = getRulesExists(rules);
|
30
|
+
const children = e.props.data?.children;
|
31
|
+
const nodeType = hasDisplayName(e.type)
|
32
|
+
? e.type.displayName
|
33
|
+
: e.props.as || 'FlowerNode';
|
34
|
+
return {
|
35
|
+
nodeId: e.props.id,
|
36
|
+
nodeType,
|
37
|
+
nodeTitle: _get(e.props, 'data.title'),
|
38
|
+
children,
|
39
|
+
nextRules,
|
40
|
+
retain: e.props.retain,
|
41
|
+
disabled: e.props.disabled
|
42
|
+
};
|
43
|
+
});
|
21
44
|
|
22
45
|
const flowerReducer = createSlice({
|
23
|
-
name:
|
46
|
+
name: REDUCER_NAME.FLOWER_FLOW,
|
24
47
|
initialState: {},
|
25
|
-
reducers:
|
48
|
+
reducers: FlowerCoreBaseReducers
|
26
49
|
});
|
27
|
-
const
|
50
|
+
const flowerActions = flowerReducer.actions;
|
51
|
+
const flowerFlowReducer = flowerReducer.reducer;
|
28
52
|
const reducerFlower = {
|
29
|
-
|
53
|
+
[REDUCER_NAME.FLOWER_FLOW]: flowerFlowReducer
|
54
|
+
};
|
55
|
+
const flowerReducers = {
|
56
|
+
...reducerFlower,
|
57
|
+
...reducerData
|
30
58
|
};
|
31
59
|
|
32
|
-
const {
|
33
|
-
const
|
34
|
-
const
|
35
|
-
const
|
36
|
-
|
37
|
-
const makeSelectNodesIds = (name) => createSelector(selectFlower(name), Selectors.makeSelectNodesIds);
|
38
|
-
const makeSelectStartNodeId = (name) => createSelector(selectFlower(name), Selectors.makeSelectStartNodeId);
|
39
|
-
const makeSelectCurrentNodeId = (name) => createSelector(selectFlower(name), makeSelectStartNodeId(name), Selectors.makeSelectCurrentNodeId);
|
40
|
-
const makeSelectPrevNodeRetain = (name) => createSelector(makeSelectNodesIds(name), selectFlowerHistory(name), makeSelectCurrentNodeId(name), Selectors.makeSelectPrevNodeRetain);
|
41
|
-
const makeSelectCurrentNodeDisabled = (name) => createSelector(makeSelectNodesIds(name), makeSelectCurrentNodeId(name), Selectors.makeSelectCurrentNodeDisabled);
|
42
|
-
// dati nel flow selezionato
|
43
|
-
const getDataByFlow = (name) => createSelector(selectFlower(name), Selectors.getDataByFlow);
|
44
|
-
// selettore per recuperare i dati di un flow specifico e id specifico
|
45
|
-
const getDataFromState = (name, id) => createSelector(getDataByFlow(name), Selectors.getDataFromState(id));
|
46
|
-
const makeSelectNodeErrors = (name, currentNodeId) => createSelector(selectFlowerFormNode(name, currentNodeId), Selectors.makeSelectNodeErrors);
|
47
|
-
const makeSelectNodeFieldTouched = (name, currentNodeId, fieldId) => createSelector(selectFlowerFormNode(name, currentNodeId), Selectors.makeSelectNodeFormFieldTouched(fieldId));
|
48
|
-
const makeSelectNodeFieldFocused = (name, currentNodeId, fieldId) => createSelector(selectFlowerFormNode(name, currentNodeId), Selectors.makeSelectNodeFormFieldFocused(fieldId));
|
49
|
-
const makeSelectNodeFieldDirty = (name, currentNodeId, fieldId) => createSelector(selectFlowerFormNode(name, currentNodeId), Selectors.makeSelectNodeFormFieldDirty(fieldId));
|
50
|
-
const makeSelectNodeFormSubmitted = (name, currentNodeId) => createSelector(selectFlowerFormNode(name, currentNodeId), Selectors.makeSelectNodeFormSubmitted);
|
51
|
-
const getAllData = createSelector(selectGlobal, mapData);
|
52
|
-
const selectFlowerFormCurrentNode = (name) => createSelector(selectFlower(name), makeSelectCurrentNodeId(name), (data, current) => {
|
53
|
-
return _get(data, ['form', current]);
|
54
|
-
});
|
55
|
-
const makeSelectFieldError = (name, id, validate) => createSelector(getAllData, selectFlowerFormCurrentNode(name), Selectors.makeSelectFieldError(name, id, validate));
|
56
|
-
const selectorRulesDisabled = (id, rules, keys, flowName, value, currentNode) => createSelector(getAllData, makeSelectNodeErrors(flowName, currentNode), Selectors.selectorRulesDisabled(id, rules, keys, flowName, value));
|
57
|
-
|
58
|
-
//TODO check reduxContext type due to remove all any types
|
59
|
-
const reduxContext = createContext(null);
|
60
|
-
const useDispatch = createDispatchHook(reduxContext);
|
61
|
-
const useSelector = createSelectorHook(reduxContext);
|
62
|
-
const useStore = createStoreHook(reduxContext);
|
63
|
-
const store = ({ enableDevtool }) => configureStore({
|
64
|
-
reducer: reducerFlower,
|
65
|
-
devTools: enableDevtool ? { name: 'flower' } : false
|
60
|
+
const { selectGlobal, selectGlobalData } = FlowerCoreStateSelectors;
|
61
|
+
const selectFlower = (name) => createSelector(selectGlobal, FlowerCoreStateSelectors.selectFlower(name));
|
62
|
+
const selectFlowerData = selectGlobalData;
|
63
|
+
const selectFlowerDataNode = (name) => createSelector(selectFlowerData, (data) => {
|
64
|
+
return data[name];
|
66
65
|
});
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
66
|
+
const selectFlowerHistory = (name) => createSelector(selectFlower(name), FlowerCoreStateSelectors.selectFlowerHistory);
|
67
|
+
const makeSelectNodesIds = (name) => createSelector(selectFlower(name), FlowerCoreStateSelectors.makeSelectNodesIds);
|
68
|
+
const makeSelectStartNodeId = (name) => createSelector(selectFlower(name), FlowerCoreStateSelectors.makeSelectStartNodeId);
|
69
|
+
const makeSelectCurrentNodeId = (name) => createSelector(selectFlower(name), makeSelectStartNodeId(name), FlowerCoreStateSelectors.makeSelectCurrentNodeId);
|
70
|
+
const makeSelectIsCurrentNode = (name) => createSelector(selectFlower(name), makeSelectCurrentNodeId(name), (flower, current) => flower.nodes[current]);
|
71
|
+
const makeSelectPrevNodeRetain = (name) => createSelector(makeSelectNodesIds(name), selectFlowerHistory(name), makeSelectCurrentNodeId(name), FlowerCoreStateSelectors.makeSelectPrevNodeRetain);
|
72
|
+
const makeSelectCurrentNodeDisabled = (name) => createSelector(makeSelectNodesIds(name), makeSelectCurrentNodeId(name), FlowerCoreStateSelectors.makeSelectCurrentNodeDisabled);
|
73
|
+
// dati nel flow selezionato
|
74
|
+
const makeSelectData = (name) => createSelector(selectFlowerDataNode(name), (data) => data?.data ?? {});
|
75
|
+
createSelector(selectGlobalData, FlowerStateUtils.getAllData);
|
77
76
|
|
78
|
-
|
79
|
-
|
80
|
-
/**
|
81
|
-
* FlowerClient
|
82
|
-
*/
|
83
|
-
const FlowerClient = ({ children, name, destroyOnUnmount = true, startId = null, initialData = {}, initialState = {} }) => {
|
84
|
-
const flowName = name;
|
85
|
-
const dispatch = useDispatch();
|
86
|
-
const one = useRef(false);
|
87
|
-
const [wsDevtools, setWsDevtools] = useState(devtoolState && _get(devtoolState, '__FLOWER_DEVTOOLS_INITIALIZED__', false));
|
88
|
-
// TODO rivedere il giro, potremmo fare le trasformazioni in CoreUtils.generateNodesForFlowerJson
|
89
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps, max-len
|
90
|
-
const nodes = useMemo(() => convertElements(Children.toArray(children)), [children]);
|
91
|
-
const nodeById = useMemo(() => _keyBy(Children.toArray(children), 'props.id'), [children]);
|
92
|
-
const isInitialized = useSelector(makeSelectStartNodeId(name));
|
93
|
-
const history = useSelector(selectFlowerHistory(name));
|
94
|
-
const current = useSelector(makeSelectCurrentNodeId(flowName));
|
95
|
-
const isDisabled = useSelector(makeSelectCurrentNodeDisabled(flowName));
|
96
|
-
const prevFlowerNodeId = useSelector(makeSelectPrevNodeRetain(flowName));
|
97
|
-
const store = useStore();
|
77
|
+
const useInitNodes = ({ one, nodes, name, startId, persist = false, initialData, initialState = {} }) => {
|
78
|
+
const { dispatch } = ReduxFlowerProvider.getReduxHooks();
|
98
79
|
useEffect(() => {
|
99
80
|
if (nodes.length > 0 && one.current === false) {
|
100
81
|
one.current = true;
|
101
|
-
dispatch(
|
102
|
-
name
|
103
|
-
// @ts-expect-error FIX ME
|
82
|
+
dispatch(flowerActions.initNodes({
|
83
|
+
name,
|
104
84
|
nodes,
|
105
85
|
startId: startId ?? '',
|
106
|
-
persist
|
107
|
-
initialData,
|
86
|
+
persist,
|
108
87
|
initialState
|
109
88
|
}));
|
110
89
|
}
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
90
|
+
if (initialData) {
|
91
|
+
dispatch(flowerDataActions.initData({
|
92
|
+
rootName: name,
|
93
|
+
initialData: initialData ?? {}
|
94
|
+
}));
|
95
|
+
}
|
96
|
+
}, [dispatch, name, nodes, startId, initialData, initialState, persist]);
|
97
|
+
};
|
98
|
+
|
99
|
+
const useInitDevtools = ({ devtoolState, setWsDevtools, flowName, }) => {
|
100
|
+
const { dispatch } = ReduxFlowerProvider.getReduxHooks();
|
120
101
|
useEffect(() => {
|
121
102
|
/* istanbul ignore next */
|
122
103
|
const eventCb = (msg) => {
|
@@ -127,14 +108,14 @@ const FlowerClient = ({ children, name, destroyOnUnmount = true, startId = null,
|
|
127
108
|
setWsDevtools(true);
|
128
109
|
}
|
129
110
|
if (msg.action === 'SELECTED_NODE' && msg.name === flowName) {
|
130
|
-
dispatch(
|
131
|
-
}
|
132
|
-
if (msg.action === 'REPLACE_DATA' && msg.name === flowName) {
|
133
|
-
dispatch(actions.replaceData({ flowName: msg.name, value: msg.data }));
|
134
|
-
}
|
135
|
-
if (msg.action === 'ADD_DATA' && msg.name === flowName) {
|
136
|
-
dispatch(actions.addData({ flowName: msg.name, value: msg.data }));
|
111
|
+
dispatch(flowerActions.setCurrentNode({ name: msg.name, node: msg.id }));
|
137
112
|
}
|
113
|
+
// if (msg.action === 'REPLACE_DATA' && msg.name === flowName) {
|
114
|
+
// dispatch(actions.replaceData({ flowName: msg.name, value: msg.data }))
|
115
|
+
// }
|
116
|
+
// if (msg.action === 'ADD_DATA' && msg.name === flowName) {
|
117
|
+
// dispatch(actions.addData({ flowName: msg.name, value: msg.data }))
|
118
|
+
// }
|
138
119
|
};
|
139
120
|
/* istanbul ignore next */
|
140
121
|
if (devtoolState && _get(devtoolState, '__FLOWER_DEVTOOLS__')) {
|
@@ -147,13 +128,22 @@ const FlowerClient = ({ children, name, destroyOnUnmount = true, startId = null,
|
|
147
128
|
}
|
148
129
|
};
|
149
130
|
}, [dispatch, flowName]);
|
131
|
+
};
|
132
|
+
|
133
|
+
const useDestroyFlow = ({ flowName, one, persist }) => {
|
134
|
+
const { dispatch } = ReduxFlowerProvider.getReduxHooks();
|
150
135
|
useEffect(() => () => {
|
151
|
-
|
152
|
-
|
136
|
+
if (persist)
|
137
|
+
return;
|
138
|
+
if (one.current === true) {
|
153
139
|
one.current = false;
|
154
|
-
dispatch(
|
140
|
+
dispatch(flowerActions.destroy({ name: flowName }));
|
155
141
|
}
|
156
|
-
}, [dispatch, flowName,
|
142
|
+
}, [dispatch, flowName, persist]);
|
143
|
+
};
|
144
|
+
|
145
|
+
const useClientInitEvent = ({ flowName, isInitialized, wsDevtools }) => {
|
146
|
+
const { store } = ReduxFlowerProvider.getReduxHooks();
|
157
147
|
useEffect(() => {
|
158
148
|
/* istanbul ignore next */
|
159
149
|
if (isInitialized &&
|
@@ -169,7 +159,11 @@ const FlowerClient = ({ children, name, destroyOnUnmount = true, startId = null,
|
|
169
159
|
getState: store.getState
|
170
160
|
});
|
171
161
|
}
|
172
|
-
}, [
|
162
|
+
}, [flowName, wsDevtools, isInitialized, store]);
|
163
|
+
};
|
164
|
+
const useSetHistoryEvent = ({ flowName, isInitialized, wsDevtools }) => {
|
165
|
+
const { useSelector } = ReduxFlowerProvider.getReduxHooks();
|
166
|
+
const history = useSelector(selectFlowerHistory(flowName));
|
173
167
|
useEffect(() => {
|
174
168
|
/* istanbul ignore next */
|
175
169
|
if (isInitialized &&
|
@@ -183,7 +177,9 @@ const FlowerClient = ({ children, name, destroyOnUnmount = true, startId = null,
|
|
183
177
|
history
|
184
178
|
});
|
185
179
|
}
|
186
|
-
}, [
|
180
|
+
}, [flowName, history, wsDevtools, isInitialized]);
|
181
|
+
};
|
182
|
+
const useSetCurrentEvent = ({ current, flowName, isInitialized, wsDevtools }) => {
|
187
183
|
useEffect(() => {
|
188
184
|
if (!current)
|
189
185
|
return;
|
@@ -203,6 +199,9 @@ const FlowerClient = ({ children, name, destroyOnUnmount = true, startId = null,
|
|
203
199
|
});
|
204
200
|
}
|
205
201
|
}, [flowName, current, wsDevtools, isInitialized]);
|
202
|
+
};
|
203
|
+
const useFlowerNavigateEvent = ({ current, flowName, isInitialized, wsDevtools, isDisabled }) => {
|
204
|
+
const { dispatch } = ReduxFlowerProvider.getReduxHooks();
|
206
205
|
useEffect(() => {
|
207
206
|
if (!current)
|
208
207
|
return;
|
@@ -210,7 +209,7 @@ const FlowerClient = ({ children, name, destroyOnUnmount = true, startId = null,
|
|
210
209
|
if (!isInitialized)
|
211
210
|
return;
|
212
211
|
if (isDisabled) {
|
213
|
-
dispatch({ type:
|
212
|
+
dispatch({ type: `${REDUCER_NAME.FLOWER_FLOW}/next`, payload: { flowName, disabled: true } });
|
214
213
|
// eslint-disable-next-line no-underscore-dangle, no-undef
|
215
214
|
/* istanbul ignore next */
|
216
215
|
if (wsDevtools &&
|
@@ -242,43 +241,72 @@ const FlowerClient = ({ children, name, destroyOnUnmount = true, startId = null,
|
|
242
241
|
time: new Date()
|
243
242
|
});
|
244
243
|
}
|
245
|
-
}, [
|
246
|
-
|
247
|
-
|
244
|
+
}, [dispatch, flowName, current, isDisabled, wsDevtools, isInitialized]);
|
245
|
+
};
|
246
|
+
|
247
|
+
const useSelectorsClient = (flowName) => {
|
248
|
+
const { useSelector } = ReduxFlowerProvider.getReduxHooks();
|
249
|
+
const isInitialized = useSelector(makeSelectStartNodeId(flowName));
|
250
|
+
const current = useSelector(makeSelectCurrentNodeId(flowName));
|
251
|
+
const isDisabled = useSelector(makeSelectCurrentNodeDisabled(flowName));
|
252
|
+
const prevFlowerNodeId = useSelector(makeSelectPrevNodeRetain(flowName));
|
253
|
+
return {
|
254
|
+
isInitialized,
|
248
255
|
current,
|
249
256
|
isDisabled,
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
257
|
+
prevFlowerNodeId
|
258
|
+
};
|
259
|
+
};
|
260
|
+
|
261
|
+
/*
|
262
|
+
* FlowerClient
|
263
|
+
*/
|
264
|
+
const FlowerClient = ({ children, name, destroyOnUnmount = true, persist = false, startId = null, initialState = {}, initialData }) => {
|
265
|
+
const flowName = name;
|
266
|
+
const _persist = persist || !destroyOnUnmount;
|
267
|
+
const one = useRef(false);
|
268
|
+
const [wsDevtools, setWsDevtools] = useState(devtoolState && _get(devtoolState, '__FLOWER_DEVTOOLS_INITIALIZED__', false));
|
269
|
+
const nodes = useMemo(() => generateNodesForFlowerJson(Children.toArray(children)), [children]);
|
270
|
+
const nodeById = useMemo(() => _keyBy(Children.toArray(children), 'props.id'), [children]);
|
271
|
+
const { current, isDisabled, isInitialized, prevFlowerNodeId } = useSelectorsClient(flowName);
|
272
|
+
useInitNodes({
|
273
|
+
name,
|
274
|
+
nodes,
|
275
|
+
one,
|
276
|
+
initialData,
|
277
|
+
initialState,
|
278
|
+
persist: _persist,
|
279
|
+
startId
|
280
|
+
});
|
281
|
+
useDestroyFlow({ flowName, one, persist: _persist });
|
282
|
+
useInitDevtools({ devtoolState, setWsDevtools, flowName });
|
283
|
+
useClientInitEvent({ flowName, isInitialized, wsDevtools });
|
284
|
+
useSetHistoryEvent({ flowName, isInitialized, wsDevtools });
|
285
|
+
useSetCurrentEvent({ current, flowName, isInitialized, wsDevtools });
|
286
|
+
useFlowerNavigateEvent({
|
287
|
+
current,
|
288
|
+
flowName,
|
289
|
+
isDisabled,
|
290
|
+
isInitialized,
|
291
|
+
wsDevtools
|
292
|
+
});
|
254
293
|
const currentNodeId = prevFlowerNodeId || current;
|
255
294
|
const contextValues = useMemo(() => ({
|
256
|
-
flowName,
|
257
|
-
initialData,
|
295
|
+
name: flowName,
|
258
296
|
currentNode: current
|
259
|
-
}), [flowName,
|
297
|
+
}), [flowName, current]);
|
260
298
|
const prevContextValues = useMemo(() => ({
|
261
|
-
flowName,
|
262
|
-
initialData,
|
299
|
+
name: flowName,
|
263
300
|
currentNode: currentNodeId
|
264
|
-
}), [flowName,
|
301
|
+
}), [flowName, currentNodeId]);
|
265
302
|
return isInitialized ? (React.createElement(React.Fragment, null,
|
266
|
-
React.createElement(
|
267
|
-
React.createElement(
|
268
|
-
};
|
269
|
-
const component$c = memo(FlowerClient);
|
270
|
-
|
271
|
-
const FlowerNode = ({ children, onEnter, onExit }) => {
|
272
|
-
useEffect(() => {
|
273
|
-
onEnter?.();
|
274
|
-
return () => {
|
275
|
-
onExit?.();
|
276
|
-
};
|
277
|
-
}, [onEnter, onExit]);
|
278
|
-
return children;
|
303
|
+
React.createElement(FlowerReactProvider, { value: prevContextValues }, nodeById[currentNodeId]),
|
304
|
+
React.createElement(FlowerReactProvider, { value: contextValues }, !isDisabled && current !== currentNodeId && nodeById[current]))) : null;
|
279
305
|
};
|
280
|
-
const component$
|
281
|
-
component$
|
306
|
+
const component$8 = memo(FlowerClient);
|
307
|
+
component$8.displayName = 'Flower';
|
308
|
+
// workaround for let typescript read JSX component as a valid JSX element using react 19(?)
|
309
|
+
const Flower = component$8;
|
282
310
|
|
283
311
|
const FlowAction = ({ children, onEnter, onExit }) => {
|
284
312
|
useEffect(() => {
|
@@ -287,400 +315,39 @@ const FlowAction = ({ children, onEnter, onExit }) => {
|
|
287
315
|
onExit?.();
|
288
316
|
};
|
289
317
|
}, [onEnter, onExit]);
|
290
|
-
return children;
|
318
|
+
return React.createElement(React.Fragment, null, children);
|
291
319
|
};
|
292
|
-
const component$
|
293
|
-
component$
|
320
|
+
const component$7 = React.memo(FlowAction);
|
321
|
+
component$7.displayName = 'FlowerAction';
|
322
|
+
const FlowerAction = component$7;
|
294
323
|
|
295
|
-
const
|
296
|
-
|
297
|
-
};
|
298
|
-
const component$9 = React.memo(FlowerServer);
|
299
|
-
component$9.displayName = 'FlowerServer';
|
324
|
+
const _FlowerComponent = ({ children }) => children;
|
325
|
+
memo(_FlowerComponent);
|
300
326
|
|
301
|
-
const
|
327
|
+
const _FlowerFlow = ({ children, onEnter, onExit }) => {
|
302
328
|
useEffect(() => {
|
303
329
|
onEnter?.();
|
304
330
|
return () => {
|
305
331
|
onExit?.();
|
306
332
|
};
|
307
333
|
}, [onEnter, onExit]);
|
308
|
-
return children;
|
309
|
-
};
|
310
|
-
const component$8 = React.memo(FlowerFlow);
|
311
|
-
component$8.displayName = 'FlowerFlow';
|
312
|
-
|
313
|
-
function FlowerStart() {
|
314
|
-
const dispatch = useDispatch();
|
315
|
-
const one = useRef(false);
|
316
|
-
const { flowName, autostart = true, currentNode } = useContext(context);
|
317
|
-
const startNodeId = useSelector(makeSelectStartNodeId(flowName ?? ''));
|
318
|
-
useEffect(() => {
|
319
|
-
if (startNodeId === currentNode && autostart && one.current === false) {
|
320
|
-
one.current = true;
|
321
|
-
dispatch({ type: 'flower/next', payload: { flowName, isStart: true } });
|
322
|
-
// if (global.window
|
323
|
-
// // eslint-disable-next-line no-underscore-dangle, no-undef
|
324
|
-
// && global.window.__FLOWER_DEVTOOLS__ && global.window.__FLOWER_DEVTOOLS__AUTO) {
|
325
|
-
// Emitter.emit('flower-devtool-from-client', {
|
326
|
-
// source: 'flower-client',
|
327
|
-
// action: 'START_FLOWER',
|
328
|
-
// name: flowName,
|
329
|
-
// });
|
330
|
-
// }
|
331
|
-
}
|
332
|
-
}, [dispatch, autostart, startNodeId, currentNode, flowName]);
|
333
|
-
return null;
|
334
|
-
}
|
335
|
-
const component$7 = React.memo(FlowerStart);
|
336
|
-
component$7.displayName = 'FlowerStart';
|
337
|
-
|
338
|
-
const FlowerRoute = ({ autostart = true, children, onEnter, onExit }) => {
|
339
|
-
const dispatch = useDispatch();
|
340
|
-
const one = useRef(false);
|
341
|
-
const { flowName } = useContext(context);
|
342
|
-
useEffect(() => {
|
343
|
-
onEnter?.();
|
344
|
-
return () => {
|
345
|
-
onExit?.();
|
346
|
-
};
|
347
|
-
}, [onEnter, onExit]);
|
348
|
-
useEffect(() => {
|
349
|
-
if (autostart && one.current === false) {
|
350
|
-
one.current = true;
|
351
|
-
dispatch({ type: 'flower/next', payload: { flowName } });
|
352
|
-
}
|
353
|
-
}, [dispatch, flowName, autostart]);
|
354
|
-
return children;
|
355
|
-
};
|
356
|
-
const component$6 = React.memo(FlowerRoute);
|
357
|
-
component$6.displayName = 'FlowerRoute';
|
358
|
-
|
359
|
-
const FlowerRule = ({ children, rules, value, alwaysDisplay, flowName, id, onUpdate }) => {
|
360
|
-
const { flowName: flowNameContext, currentNode } = useContext(context);
|
361
|
-
const name = flowName || flowNameContext;
|
362
|
-
const keys = MatchRules.utils.getKeys(rules, { prefix: name });
|
363
|
-
const hidden = useSelector(selectorRulesDisabled(id ?? '', rules, keys ?? [], name ?? '', value, currentNode ?? ''));
|
364
|
-
useEffect(() => {
|
365
|
-
if (onUpdate) {
|
366
|
-
onUpdate(hidden);
|
367
|
-
}
|
368
|
-
}, [hidden, onUpdate]);
|
369
|
-
if (typeof children === 'function') {
|
370
|
-
if (alwaysDisplay && hidden) {
|
371
|
-
return children({ hidden });
|
372
|
-
}
|
373
|
-
if (hidden) {
|
374
|
-
return undefined;
|
375
|
-
}
|
376
|
-
return children({});
|
377
|
-
}
|
378
|
-
if (alwaysDisplay && hidden) {
|
379
|
-
return React.Children.map(children, (child, i) => {
|
380
|
-
if (React.isValidElement(child)) {
|
381
|
-
const { props, type } = child;
|
382
|
-
const Component = type;
|
383
|
-
// eslint-disable-next-line react/jsx-props-no-spreading
|
384
|
-
return Component && React.createElement(Component, { key: i, hidden: true, ...props });
|
385
|
-
}
|
386
|
-
return child;
|
387
|
-
});
|
388
|
-
}
|
389
|
-
return hidden
|
390
|
-
? undefined
|
391
|
-
: React.Children.map(children, (child, i) => {
|
392
|
-
if (React.isValidElement(child)) {
|
393
|
-
const { props, type } = child;
|
394
|
-
const Component = type;
|
395
|
-
// eslint-disable-next-line react/jsx-props-no-spreading
|
396
|
-
return Component && React.createElement(Component, { key: i, ...props });
|
397
|
-
}
|
398
|
-
return child;
|
399
|
-
});
|
334
|
+
return React.createElement(React.Fragment, null, children);
|
400
335
|
};
|
401
|
-
const component$
|
402
|
-
component$
|
403
|
-
|
404
|
-
/* eslint-disable */
|
405
|
-
function isIntrinsicElement$1(x) {
|
406
|
-
return typeof x === 'string';
|
407
|
-
}
|
408
|
-
//TODO make types for wrapper function props
|
409
|
-
function Wrapper$1({ Component, id, flowName, currentNode, validate, asyncDebounce = 0, asyncValidate, asyncInitialError, asyncWaitingError, destroyValue, destroyOnHide, onBlur, onFocus, hidden, onUpdate, defaultValue, ...props }) {
|
410
|
-
const dispatch = useDispatch();
|
411
|
-
const [customAsyncErrors, setCustomAsyncErrors] = useState(asyncValidate && asyncInitialError && [asyncInitialError]);
|
412
|
-
const [isValidating, setIsValidating] = useState(undefined);
|
413
|
-
const { flowNameFromPath = flowName, path } = useMemo(() => CoreUtils.getPath(id), [id]);
|
414
|
-
const value = useSelector(getDataFromState(flowNameFromPath, path));
|
415
|
-
const errors = useSelector(makeSelectFieldError(flowName, id, validate), CoreUtils.allEqual);
|
416
|
-
const dirty = useSelector(makeSelectNodeFieldDirty(flowName, currentNode, id));
|
417
|
-
const touched = useSelector(makeSelectNodeFieldTouched(flowName, currentNode, id));
|
418
|
-
const focused = useSelector(makeSelectNodeFieldFocused(flowName, currentNode, id));
|
419
|
-
const refValue = useRef();
|
420
|
-
const isSubmitted = useSelector(makeSelectNodeFormSubmitted(flowName, currentNode));
|
421
|
-
const allErrors = useMemo(() => hidden ? [] : [...errors, ...(customAsyncErrors || []).filter(Boolean)], [errors, hidden, customAsyncErrors]);
|
422
|
-
const setTouched = useCallback((touched) => {
|
423
|
-
dispatch({
|
424
|
-
type: 'flower/formFieldTouch',
|
425
|
-
payload: {
|
426
|
-
name: flowName,
|
427
|
-
id,
|
428
|
-
currentNode,
|
429
|
-
touched
|
430
|
-
}
|
431
|
-
});
|
432
|
-
}, [dispatch, flowName, currentNode, id]);
|
433
|
-
const setFocus = useCallback((focused) => {
|
434
|
-
dispatch({
|
435
|
-
type: 'flower/formFieldFocus',
|
436
|
-
payload: {
|
437
|
-
name: flowName,
|
438
|
-
id,
|
439
|
-
currentNode,
|
440
|
-
focused
|
441
|
-
}
|
442
|
-
});
|
443
|
-
}, [dispatch, flowName, currentNode, id]);
|
444
|
-
const validateFn = useCallback(async (value) => {
|
445
|
-
if (asyncWaitingError) {
|
446
|
-
setCustomAsyncErrors([asyncWaitingError]);
|
447
|
-
}
|
448
|
-
setIsValidating(true);
|
449
|
-
const state = FlowerStateUtils.getAllData(store);
|
450
|
-
const res = await asyncValidate(value, state, errors);
|
451
|
-
setIsValidating(false);
|
452
|
-
setCustomAsyncErrors(res);
|
453
|
-
}, [asyncWaitingError, errors]);
|
454
|
-
const debouncedValidation = useCallback(debounce(validateFn, asyncDebounce), [
|
455
|
-
validateFn
|
456
|
-
]);
|
457
|
-
const onChange = useCallback((val) => {
|
458
|
-
if (asyncValidate && asyncWaitingError) {
|
459
|
-
setCustomAsyncErrors([asyncWaitingError]);
|
460
|
-
}
|
461
|
-
dispatch({
|
462
|
-
type: `flower/addDataByPath`,
|
463
|
-
payload: {
|
464
|
-
flowName: flowNameFromPath,
|
465
|
-
id,
|
466
|
-
value: val,
|
467
|
-
dirty: defaultValue ? !isEqual(val, defaultValue) : true
|
468
|
-
}
|
469
|
-
});
|
470
|
-
}, [flowNameFromPath, id, dispatch, setCustomAsyncErrors, asyncValidate, asyncWaitingError]);
|
471
|
-
const onBlurInternal = useCallback((e) => {
|
472
|
-
setTouched(true);
|
473
|
-
setFocus(false);
|
474
|
-
onBlur && onBlur(e);
|
475
|
-
}, [onBlur, setTouched, setFocus]);
|
476
|
-
const onFocusInternal = useCallback((e) => {
|
477
|
-
setFocus(true);
|
478
|
-
onFocus && onFocus(e);
|
479
|
-
}, [onFocus, setFocus]);
|
480
|
-
useEffect(() => {
|
481
|
-
if (hidden)
|
482
|
-
return;
|
483
|
-
if (asyncValidate) {
|
484
|
-
if (refValue.current === value)
|
485
|
-
return;
|
486
|
-
refValue.current = value;
|
487
|
-
const hasValue = !MatchRules.utils.isEmpty(value);
|
488
|
-
if (!hasValue) {
|
489
|
-
setCustomAsyncErrors(asyncInitialError && [asyncInitialError]);
|
490
|
-
setIsValidating(false);
|
491
|
-
return;
|
492
|
-
}
|
493
|
-
setTouched(true);
|
494
|
-
debouncedValidation(value);
|
495
|
-
}
|
496
|
-
}, [asyncValidate, asyncInitialError, value, debouncedValidation, setTouched, hidden]);
|
497
|
-
useEffect(() => {
|
498
|
-
if (onUpdate) {
|
499
|
-
onUpdate(value);
|
500
|
-
}
|
501
|
-
}, [value, onUpdate]);
|
502
|
-
useEffect(() => {
|
503
|
-
dispatch({
|
504
|
-
type: 'flower/formAddErrors',
|
505
|
-
payload: {
|
506
|
-
name: flowName,
|
507
|
-
id,
|
508
|
-
currentNode,
|
509
|
-
errors: allErrors
|
510
|
-
}
|
511
|
-
});
|
512
|
-
}, [id, flowName, allErrors, currentNode, touched]);
|
513
|
-
useEffect(() => {
|
514
|
-
dispatch({
|
515
|
-
type: 'flower/setFormIsValidating',
|
516
|
-
payload: {
|
517
|
-
name: flowName,
|
518
|
-
currentNode,
|
519
|
-
isValidating
|
520
|
-
}
|
521
|
-
});
|
522
|
-
}, [flowName, currentNode, isValidating]);
|
523
|
-
const resetField = useCallback(() => {
|
524
|
-
dispatch({
|
525
|
-
type: 'flower/formFieldTouch',
|
526
|
-
payload: {
|
527
|
-
name: flowName,
|
528
|
-
id,
|
529
|
-
currentNode,
|
530
|
-
touched: false
|
531
|
-
}
|
532
|
-
});
|
533
|
-
dispatch({
|
534
|
-
type: 'flower/formFieldDirty',
|
535
|
-
payload: {
|
536
|
-
name: flowName,
|
537
|
-
id,
|
538
|
-
currentNode,
|
539
|
-
dirty: false
|
540
|
-
}
|
541
|
-
});
|
542
|
-
dispatch({
|
543
|
-
type: 'flower/formRemoveErrors',
|
544
|
-
payload: {
|
545
|
-
name: flowName,
|
546
|
-
id,
|
547
|
-
currentNode
|
548
|
-
}
|
549
|
-
});
|
550
|
-
}, [currentNode, id, flowName]);
|
551
|
-
useEffect(() => {
|
552
|
-
// destroy
|
553
|
-
return () => {
|
554
|
-
if (destroyValue) {
|
555
|
-
dispatch({
|
556
|
-
type: `flower/unsetData`,
|
557
|
-
payload: { flowName: flowNameFromPath, id: path }
|
558
|
-
});
|
559
|
-
}
|
560
|
-
resetField();
|
561
|
-
};
|
562
|
-
}, [destroyValue, id, flowNameFromPath, path, resetField]);
|
563
|
-
useEffect(() => {
|
564
|
-
if (hidden) {
|
565
|
-
if (destroyOnHide) {
|
566
|
-
dispatch({
|
567
|
-
type: `flower/unsetData`,
|
568
|
-
payload: { flowName: flowNameFromPath, id: path }
|
569
|
-
});
|
570
|
-
resetField();
|
571
|
-
}
|
572
|
-
}
|
573
|
-
}, [destroyOnHide, hidden, flowNameFromPath, path, resetField]);
|
574
|
-
useEffect(() => {
|
575
|
-
if (defaultValue && !dirty && !isEqual(value, defaultValue)) {
|
576
|
-
onChange(defaultValue);
|
577
|
-
}
|
578
|
-
}, [defaultValue, value, dirty, onChange]);
|
579
|
-
const newProps = useMemo(() => ({
|
580
|
-
...props,
|
581
|
-
id,
|
582
|
-
value,
|
583
|
-
errors: allErrors,
|
584
|
-
hasError: !!allErrors.length,
|
585
|
-
onChange,
|
586
|
-
onBlur: onBlurInternal,
|
587
|
-
onFocus: onFocusInternal,
|
588
|
-
focused: !!focused,
|
589
|
-
touched,
|
590
|
-
dirty,
|
591
|
-
hidden,
|
592
|
-
isValidating,
|
593
|
-
isSubmitted,
|
594
|
-
}), [
|
595
|
-
props,
|
596
|
-
id,
|
597
|
-
value,
|
598
|
-
allErrors,
|
599
|
-
touched,
|
600
|
-
dirty,
|
601
|
-
onChange,
|
602
|
-
onBlurInternal,
|
603
|
-
onFocusInternal,
|
604
|
-
hidden,
|
605
|
-
isValidating,
|
606
|
-
isSubmitted,
|
607
|
-
focused
|
608
|
-
]);
|
609
|
-
if (typeof Component === 'function') {
|
610
|
-
return Component(newProps);
|
611
|
-
}
|
612
|
-
// TODO si arriva in questa condizione quando si passa un componente primitivo es. div
|
613
|
-
// in questo caso non posso props custom di flower
|
614
|
-
if (isIntrinsicElement$1(Component)) {
|
615
|
-
return React.createElement(Component, { id: id, ...props });
|
616
|
-
}
|
617
|
-
return Component && React.createElement(Component, { ...newProps });
|
618
|
-
}
|
619
|
-
const FlowerField = ({ id, validate, asyncValidate, asyncDebounce, asyncInitialError, asyncWaitingError, rules, alwaysDisplay, value, children, defaultValue, destroyOnHide, destroyValue, flowName, onUpdate }) => {
|
620
|
-
const { flowName: flowNameContext, currentNode } = useContext(context);
|
621
|
-
const name = flowName || flowNameContext;
|
622
|
-
if (typeof children === 'function') {
|
623
|
-
return (React.createElement(component$5, { alwaysDisplay: alwaysDisplay, rules: rules, value: value, flowName: name, id: id }, ({ hidden }) => (React.createElement(Wrapper$1, { hidden: hidden, id: id, Component: children, flowName: name, currentNode: currentNode, validate: validate, asyncValidate: asyncValidate, asyncDebounce: asyncDebounce, asyncInitialError: asyncInitialError, asyncWaitingError: asyncWaitingError, destroyValue: destroyValue, onUpdate: onUpdate, defaultValue: defaultValue, destroyOnHide: destroyOnHide }))));
|
624
|
-
}
|
625
|
-
return React.Children.map(children, (child, i) => {
|
626
|
-
if (!React.isValidElement(child)) {
|
627
|
-
return child;
|
628
|
-
}
|
629
|
-
const { type, props } = child;
|
630
|
-
const Component = type;
|
631
|
-
return (React.createElement(component$5, { key: i, alwaysDisplay: alwaysDisplay, rules: rules, value: value, flowName: name }, ({ hidden }) => (React.createElement(Wrapper$1, { ...props, hidden: hidden, id: id, Component: Component, flowName: name, currentNode: currentNode, validate: validate, asyncValidate: asyncValidate, asyncDebounce: asyncDebounce, asyncInitialError: asyncInitialError, asyncWaitingError: asyncWaitingError, destroyValue: destroyValue, onUpdate: onUpdate, defaultValue: defaultValue }))));
|
632
|
-
});
|
633
|
-
};
|
634
|
-
const component$4 = React.memo(FlowerField);
|
635
|
-
component$4.displayName = 'FlowerField';
|
636
|
-
|
637
|
-
/* eslint-disable */
|
638
|
-
//TODO make types for wrapper function
|
639
|
-
function Wrapper({ Component, id, flowName, spreadValue, hidden, onUpdate, ...props }) {
|
640
|
-
const { flowNameFromPath = flowName, path } = useMemo(() => CoreUtils.getPath(id), [id]);
|
641
|
-
const value = useSelector(getDataFromState(flowNameFromPath, path));
|
642
|
-
const values = spreadValue && typeof value === 'object' && !Array.isArray(value)
|
643
|
-
? value
|
644
|
-
: { value };
|
645
|
-
useEffect(() => {
|
646
|
-
if (onUpdate) {
|
647
|
-
onUpdate(value);
|
648
|
-
}
|
649
|
-
}, [onUpdate, value]);
|
650
|
-
return (React.createElement(Component, { id: id, ...props, flowName: flowName, hidden: hidden, ...values }));
|
651
|
-
}
|
652
|
-
const RenderRules$1 = ({ id, alwaysDisplay, rules, value, Component, spreadValue, flowName, onUpdate, ...props }) => {
|
653
|
-
return (React.createElement(component$5, { alwaysDisplay: alwaysDisplay, rules: rules, value: value, flowName: flowName, id: id }, ({ hidden }) => (React.createElement(Wrapper, { ...props, hidden: hidden, id: id, Component: Component, spreadValue: spreadValue, flowName: flowName, onUpdate: onUpdate }))));
|
654
|
-
};
|
655
|
-
const FlowerValue = ({ id = '*', rules, alwaysDisplay, value, children, spreadValue, flowName, onUpdate, }) => {
|
656
|
-
const { flowName: flowNameContext } = useContext(context);
|
657
|
-
const name = flowName || flowNameContext;
|
658
|
-
if (typeof children === 'function') {
|
659
|
-
return (React.createElement(RenderRules$1, { id: id, alwaysDisplay: alwaysDisplay, rules: rules, value: value, spreadValue: spreadValue, Component: children, flowName: name, onUpdate: onUpdate }));
|
660
|
-
}
|
661
|
-
return React.Children.map(children, (child, i) => {
|
662
|
-
if (!React.isValidElement(child))
|
663
|
-
return child;
|
664
|
-
const { type, props } = child;
|
665
|
-
const Component = type;
|
666
|
-
// eslint-disable-next-line react/jsx-props-no-spreading
|
667
|
-
return (React.createElement(RenderRules$1, { key: i, id: id, alwaysDisplay: alwaysDisplay, rules: rules, value: value, spreadValue: spreadValue, flowName: name, Component: Component, ...props, onUpdate: onUpdate }));
|
668
|
-
});
|
669
|
-
};
|
670
|
-
const component$3 = React.memo(FlowerValue);
|
671
|
-
component$3.displayName = 'FlowerValue';
|
336
|
+
const component$6 = React.memo(_FlowerFlow);
|
337
|
+
component$6.displayName = 'FlowerFlow';
|
338
|
+
const FlowerFlow = component$6;
|
672
339
|
|
673
340
|
const ACTION_TYPES = {
|
674
|
-
back: ['
|
341
|
+
back: ['back', 'prevToNode'],
|
675
342
|
jump: ['node', 'node'],
|
676
343
|
next: ['next', 'next'],
|
677
344
|
restart: ['restart', 'restart'],
|
678
345
|
reset: ['reset', 'initializeFromNode']
|
679
346
|
};
|
680
|
-
const
|
347
|
+
const PAYLOAD_KEYS_NEEDED = {
|
681
348
|
back: ['node'],
|
682
349
|
jump: ['node', 'history'],
|
683
|
-
next: ['node', 'route', 'data'],
|
350
|
+
next: ['node', 'route', 'data', 'dataIn'],
|
684
351
|
restart: ['node'],
|
685
352
|
reset: ['node', 'initialData']
|
686
353
|
};
|
@@ -696,11 +363,49 @@ const makeActionPayload = (actions, keys) => (flowName, params) => {
|
|
696
363
|
payload
|
697
364
|
};
|
698
365
|
};
|
699
|
-
const
|
700
|
-
const makeActionPayloadOnReset = makeActionPayload(ACTION_TYPES.reset,
|
701
|
-
const makeActionPayloadOnNode = makeActionPayload(ACTION_TYPES.jump,
|
702
|
-
const makeActionPayloadOnNext = makeActionPayload(ACTION_TYPES.next,
|
703
|
-
const makeActionPayloadOnRestart = makeActionPayload(ACTION_TYPES.restart,
|
366
|
+
const makeActionPayloadOnBack = makeActionPayload(ACTION_TYPES.back, PAYLOAD_KEYS_NEEDED.back);
|
367
|
+
const makeActionPayloadOnReset = makeActionPayload(ACTION_TYPES.reset, PAYLOAD_KEYS_NEEDED.reset);
|
368
|
+
const makeActionPayloadOnNode = makeActionPayload(ACTION_TYPES.jump, PAYLOAD_KEYS_NEEDED.jump);
|
369
|
+
const makeActionPayloadOnNext = makeActionPayload(ACTION_TYPES.next, PAYLOAD_KEYS_NEEDED.next);
|
370
|
+
const makeActionPayloadOnRestart = makeActionPayload(ACTION_TYPES.restart, PAYLOAD_KEYS_NEEDED.restart);
|
371
|
+
const handleHistoryStackChange = (currentIndex, currentNode, flowName, withUrl) => {
|
372
|
+
const historyNode = `/${flowName}/${currentNode.nodeId}`;
|
373
|
+
if (currentNode.nodeType === 'FlowerAction')
|
374
|
+
return currentIndex;
|
375
|
+
const nextIndex = currentIndex + 1;
|
376
|
+
if (history.state?.index !== nextIndex) {
|
377
|
+
window.history.pushState({
|
378
|
+
index: nextIndex,
|
379
|
+
stack: [...(window.history.state.stack ?? []), historyNode]
|
380
|
+
}, '', withUrl ? historyNode : '');
|
381
|
+
}
|
382
|
+
return nextIndex;
|
383
|
+
};
|
384
|
+
|
385
|
+
const useHistorySync = ({ backAction, nextAction }) => {
|
386
|
+
const { dispatch } = ReduxFlowerProvider.getReduxHooks();
|
387
|
+
const { index, isActive, setIndex, withUrl } = useHistoryContext();
|
388
|
+
useEffect(() => {
|
389
|
+
if (!isActive)
|
390
|
+
return;
|
391
|
+
const initialIndex = window.history.state?.index ?? 0;
|
392
|
+
setIndex(initialIndex);
|
393
|
+
window.history.replaceState({ index: initialIndex, stack: [...(window.history.state?.stack ?? [])] }, withUrl ? '/' : '', '');
|
394
|
+
const onPopState = (event) => {
|
395
|
+
const newIndex = window.history.state?.index ?? 0;
|
396
|
+
if (newIndex > index) {
|
397
|
+
nextAction();
|
398
|
+
}
|
399
|
+
if (newIndex < index) {
|
400
|
+
backAction();
|
401
|
+
}
|
402
|
+
setIndex(newIndex);
|
403
|
+
};
|
404
|
+
window.addEventListener('popstate', onPopState);
|
405
|
+
return () => window.removeEventListener('popstate', onPopState);
|
406
|
+
}, [dispatch, backAction, nextAction]);
|
407
|
+
};
|
408
|
+
|
704
409
|
/** This hook allows you to read flow informations, such as the flowName and ID of the current node.
|
705
410
|
*
|
706
411
|
* It also exposes all the functions to navigate within the flow:
|
@@ -720,12 +425,19 @@ const makeActionPayloadOnRestart = makeActionPayload(ACTION_TYPES.restart, PAYLA
|
|
720
425
|
* @param {string} name - optional parameter, if flowName exist, name is not used
|
721
426
|
*/
|
722
427
|
const useFlower = ({ flowName: customFlowName, name } = {}) => {
|
723
|
-
const
|
724
|
-
const {
|
725
|
-
const store =
|
428
|
+
const { name: flowNameDefault, initialData } = useContext(FlowerReactContext);
|
429
|
+
const { index, isActive, setIndex, withUrl } = useHistoryContext();
|
430
|
+
const { store, dispatch, useSelector } = ReduxFlowerProvider.getReduxHooks();
|
726
431
|
const flowName = (customFlowName || name || flowNameDefault);
|
727
432
|
const nodeId = useSelector(makeSelectCurrentNodeId(flowName ?? ''));
|
433
|
+
const currentNode = useSelector(makeSelectIsCurrentNode(flowName ?? ''));
|
728
434
|
const startId = useSelector(makeSelectStartNodeId(flowName ?? ''));
|
435
|
+
useEffect(() => {
|
436
|
+
if (currentNode.nodeType === 'FlowerAction')
|
437
|
+
return;
|
438
|
+
window.history.replaceState({ ...window.history.state }, '', withUrl ? `/${flowName}/${nodeId}` : '');
|
439
|
+
}, [nodeId, flowName, withUrl, currentNode]);
|
440
|
+
const stack = useMemo(() => window.history.state?.stack?.map((path) => path.split('/')[1]), [window.history.state?.stack]);
|
729
441
|
const emitNavigateEvent = useCallback(
|
730
442
|
//TODO check this function is needed
|
731
443
|
(params) => {
|
@@ -743,42 +455,61 @@ const useFlower = ({ flowName: customFlowName, name } = {}) => {
|
|
743
455
|
}
|
744
456
|
}, [flowName, nodeId]);
|
745
457
|
const next = useCallback((param) => {
|
746
|
-
const params = typeof param === 'string' ? { route: param } : {
|
458
|
+
const params = typeof param === 'string' ? { route: param } : { dataIn: param };
|
747
459
|
const { type, payload } = makeActionPayloadOnNext(flowName, params);
|
748
460
|
dispatch({
|
749
|
-
type:
|
750
|
-
payload
|
461
|
+
type: `${REDUCER_NAME.FLOWER_FLOW}/${type}`,
|
462
|
+
payload: { ...payload, data: store.getState() }
|
751
463
|
});
|
464
|
+
if (isActive) {
|
465
|
+
setIndex(handleHistoryStackChange(index, currentNode, flowName, withUrl));
|
466
|
+
}
|
752
467
|
emitNavigateEvent({ type, payload });
|
753
|
-
}, [dispatch, emitNavigateEvent, flowName]);
|
468
|
+
}, [dispatch, emitNavigateEvent, flowName, store]);
|
469
|
+
/**
|
470
|
+
* By doing this, we have a full control over flower navigation from both our buttons and browser back and forward navigation
|
471
|
+
* In order to trigger back correctly, trigger a real history back
|
472
|
+
* If you use replaceState({ index: 2 }) while at index 3,
|
473
|
+
* you visually move to step 2, but the browser still sees you at step 3.
|
474
|
+
* As a result:
|
475
|
+
* - The browser's Forward button stays disabled
|
476
|
+
* - No popstate event is triggered
|
477
|
+
* - The history flow is broken
|
478
|
+
* Use history.back() instead to preserve proper browser navigation.
|
479
|
+
*/
|
480
|
+
const interceptBack = () => {
|
481
|
+
window.history.back();
|
482
|
+
};
|
754
483
|
const back = useCallback((param) => {
|
755
|
-
const { type, payload } =
|
756
|
-
dispatch({
|
484
|
+
const { type, payload } = makeActionPayloadOnBack(isActive ? (stack?.[stack?.length - 1] ?? flowName) : flowName, param);
|
485
|
+
dispatch({
|
486
|
+
type: `${REDUCER_NAME.FLOWER_FLOW}/${type}`,
|
487
|
+
payload
|
488
|
+
});
|
489
|
+
setIndex(index - 1);
|
757
490
|
emitNavigateEvent({ type, payload });
|
758
|
-
}, [dispatch, emitNavigateEvent, flowName]);
|
491
|
+
}, [dispatch, emitNavigateEvent, flowName, stack]);
|
492
|
+
useHistorySync({ backAction: back, nextAction: next });
|
759
493
|
const restart = useCallback((param) => {
|
760
494
|
const { type, payload } = makeActionPayloadOnRestart(flowName, param);
|
761
|
-
dispatch({ type:
|
495
|
+
dispatch({ type: `${REDUCER_NAME.FLOWER_FLOW}/${type}`, payload });
|
762
496
|
emitNavigateEvent({ type, payload });
|
763
497
|
}, [dispatch, emitNavigateEvent, flowName]);
|
764
498
|
const reset = useCallback((param) => {
|
765
499
|
const { type, payload } = makeActionPayloadOnReset(flowName, typeof param === 'string'
|
766
500
|
? { node: param, initialData }
|
767
|
-
: {
|
768
|
-
|
769
|
-
initialData
|
770
|
-
});
|
771
|
-
dispatch({ type: `flower/${type}`, payload });
|
501
|
+
: { ...param, initialData });
|
502
|
+
dispatch({ type: `${REDUCER_NAME.FLOWER_FLOW}/${type}`, payload });
|
772
503
|
emitNavigateEvent({ type, payload });
|
773
504
|
}, [dispatch, emitNavigateEvent, flowName, initialData]);
|
774
505
|
const jump = useCallback((param) => {
|
775
506
|
const { type, payload } = makeActionPayloadOnNode(flowName, param);
|
776
|
-
dispatch({ type:
|
507
|
+
dispatch({ type: `${REDUCER_NAME.FLOWER_FLOW}/${type}`, payload });
|
777
508
|
emitNavigateEvent({ type, payload });
|
778
509
|
}, [dispatch, emitNavigateEvent, flowName]);
|
779
510
|
const getCurrentNodeId = useCallback((customFlowName) => {
|
780
511
|
return _get(store.getState(), [
|
781
|
-
|
512
|
+
REDUCER_NAME.FLOWER_FLOW,
|
782
513
|
customFlowName || flowName,
|
783
514
|
'current'
|
784
515
|
]);
|
@@ -790,7 +521,7 @@ const useFlower = ({ flowName: customFlowName, name } = {}) => {
|
|
790
521
|
startId,
|
791
522
|
next,
|
792
523
|
jump,
|
793
|
-
back,
|
524
|
+
back: isActive ? interceptBack : back,
|
794
525
|
reset,
|
795
526
|
restart
|
796
527
|
};
|
@@ -819,7 +550,7 @@ const useFlower = ({ flowName: customFlowName, name } = {}) => {
|
|
819
550
|
// }
|
820
551
|
// );
|
821
552
|
const useFlowerNavigate = ({ flowName, action, route, node }) => {
|
822
|
-
const {
|
553
|
+
const { name: flowNameContext } = useContext(FlowerReactContext);
|
823
554
|
const name = flowName || flowNameContext;
|
824
555
|
const { next, jump, back, reset, restart } = useFlower({ flowName: name });
|
825
556
|
const onNavigate = useCallback(() => {
|
@@ -855,7 +586,7 @@ function isIntrinsicElement(x) {
|
|
855
586
|
return typeof x === 'string';
|
856
587
|
}
|
857
588
|
//TODO type FlowerNavigateWrapper props
|
858
|
-
function
|
589
|
+
function _FlowerNavigateWrapper({ hidden, Component, onNavigate, ...props }) {
|
859
590
|
const newProps = useMemo(() => ({
|
860
591
|
...props,
|
861
592
|
hidden,
|
@@ -874,136 +605,160 @@ function FlowerNavigateWrapper({ hidden, Component, onNavigate, ...props }) {
|
|
874
605
|
/* istanbul ignore next */
|
875
606
|
return Component && React.createElement(Component, { ...newProps });
|
876
607
|
}
|
877
|
-
const component$
|
608
|
+
const component$5 = React.memo(_FlowerNavigateWrapper);
|
609
|
+
const FlowerNavigateWrapper = component$5;
|
878
610
|
|
879
611
|
/* eslint-disable */
|
880
612
|
//TODO type RenderRules props
|
613
|
+
// ! Probably in this scenario we must replace `FlowerRule` or refactor `FlowerNavigate`
|
881
614
|
const RenderRules = ({ alwaysDisplay, rules, Component, flowName, onNavigate, ...props }) => {
|
882
|
-
return (React.createElement(
|
615
|
+
return (React.createElement(FlowerRule, { alwaysDisplay: alwaysDisplay, rules: rules, rootName: flowName }, ({ hidden }) => (React.createElement(FlowerNavigateWrapper, { ...props, Component: Component, hidden: hidden, onNavigate: onNavigate }))));
|
883
616
|
};
|
884
|
-
const
|
885
|
-
const { onNavigate, flowName } = useFlowerNavigate({
|
617
|
+
const _FlowerNavigate = ({ children, flowName: forceFlowName, action, route, node, rules, alwaysDisplay }) => {
|
618
|
+
const { onNavigate, flowName } = useFlowerNavigate({
|
619
|
+
flowName: forceFlowName,
|
620
|
+
action,
|
621
|
+
route,
|
622
|
+
node
|
623
|
+
});
|
886
624
|
if (typeof children === 'function') {
|
887
|
-
return React.createElement(RenderRules, { alwaysDisplay: alwaysDisplay, rules: rules, Component: children, flowName: flowName, onNavigate: onNavigate });
|
625
|
+
return (React.createElement(RenderRules, { alwaysDisplay: alwaysDisplay, rules: rules, Component: children, flowName: flowName, onNavigate: onNavigate }));
|
888
626
|
}
|
889
|
-
return React.Children.map(children, (child, i) => {
|
627
|
+
return (React.createElement(React.Fragment, null, React.Children.map(children, (child, i) => {
|
890
628
|
if (!React.isValidElement(child))
|
891
629
|
return child;
|
892
630
|
const { type, props } = child;
|
893
631
|
const Component = type;
|
894
|
-
|
895
|
-
|
896
|
-
});
|
632
|
+
return (React.createElement(RenderRules, { key: i, alwaysDisplay: alwaysDisplay, rules: rules, Component: Component, flowName: flowName, onNavigate: onNavigate, ...props }));
|
633
|
+
})));
|
897
634
|
};
|
898
|
-
const component$
|
899
|
-
component$
|
635
|
+
const component$4 = React.memo(_FlowerNavigate);
|
636
|
+
component$4.displayName = 'FlowerNavigate';
|
637
|
+
const FlowerNavigate = component$4;
|
900
638
|
|
901
|
-
const
|
902
|
-
|
639
|
+
const _FlowerNode = ({ children, onEnter, onExit }) => {
|
640
|
+
useEffect(() => {
|
641
|
+
onEnter?.();
|
642
|
+
return () => {
|
643
|
+
onExit?.();
|
644
|
+
};
|
645
|
+
}, [onEnter, onExit]);
|
646
|
+
return React.createElement(React.Fragment, null, children);
|
647
|
+
};
|
648
|
+
const component$3 = memo(_FlowerNode);
|
649
|
+
component$3.displayName = 'FlowerNode';
|
650
|
+
const FlowerNode = component$3;
|
903
651
|
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
652
|
+
const _FlowerRoute = ({ autostart = true, children, onEnter, onExit }) => {
|
653
|
+
const { dispatch } = ReduxFlowerProvider.getReduxHooks();
|
654
|
+
const one = useRef(false);
|
655
|
+
const { name } = useContext(FlowerReactContext);
|
656
|
+
useEffect(() => {
|
657
|
+
onEnter?.();
|
658
|
+
return () => {
|
659
|
+
onExit?.();
|
660
|
+
};
|
661
|
+
}, [onEnter, onExit]);
|
662
|
+
useEffect(() => {
|
663
|
+
if (autostart && one.current === false) {
|
664
|
+
one.current = true;
|
665
|
+
dispatch(flowerActions.next({ flowName: name }));
|
666
|
+
}
|
667
|
+
}, [dispatch, name, autostart]);
|
668
|
+
return React.createElement(React.Fragment, null, children);
|
669
|
+
};
|
670
|
+
const component$2 = React.memo(_FlowerRoute);
|
671
|
+
component$2.displayName = 'FlowerRoute';
|
672
|
+
const FlowerRoute = component$2;
|
673
|
+
|
674
|
+
const _FlowerServer = ({ children }) => {
|
675
|
+
return React.createElement(React.Fragment, null, children);
|
676
|
+
};
|
677
|
+
const component$1 = React.memo(_FlowerServer);
|
678
|
+
component$1.displayName = 'FlowerServer';
|
679
|
+
const FlowerServer = component$1;
|
680
|
+
|
681
|
+
function _FlowerStart() {
|
682
|
+
const { dispatch, useSelector } = ReduxFlowerProvider.getReduxHooks();
|
683
|
+
const one = useRef(false);
|
684
|
+
const { name, autostart = true, currentNode } = useContext(FlowerReactContext);
|
685
|
+
const startNodeId = useSelector(makeSelectStartNodeId(name ?? ''));
|
686
|
+
useEffect(() => {
|
687
|
+
if (startNodeId === currentNode && autostart && one.current === false) {
|
688
|
+
one.current = true;
|
689
|
+
dispatch(flowerActions.next({ flowName: name, isStart: true }));
|
690
|
+
// if (global.window
|
691
|
+
// // eslint-disable-next-line no-underscore-dangle, no-undef
|
692
|
+
// && global.window.__FLOWER_DEVTOOLS__ && global.window.__FLOWER_DEVTOOLS__AUTO) {
|
693
|
+
// Emitter.emit('flower-devtool-from-client', {
|
694
|
+
// source: 'flower-client',
|
695
|
+
// action: 'START_FLOWER',
|
696
|
+
// name: flowName,
|
697
|
+
// });
|
698
|
+
// }
|
699
|
+
}
|
700
|
+
}, [dispatch, autostart, startNodeId, currentNode, name]);
|
701
|
+
return null;
|
702
|
+
}
|
703
|
+
const component = React.memo(_FlowerStart);
|
704
|
+
component.displayName = 'FlowerStart';
|
705
|
+
const FlowerStart = component;
|
706
|
+
|
707
|
+
const FlowerProvider = ({ children, enableReduxDevtool, configureStore }) => {
|
708
|
+
const { reducer, ...rest } = configureStore ?? {
|
709
|
+
devTools: enableReduxDevtool
|
710
|
+
};
|
711
|
+
return (React.createElement(ReduxFlowerProvider, { configureStore: {
|
712
|
+
reducer: { ...reducerFlower, ...(reducer ?? {}) },
|
713
|
+
...rest,
|
714
|
+
devTools: enableReduxDevtool ?? rest?.devTools
|
715
|
+
} }, children));
|
716
|
+
};
|
717
|
+
|
718
|
+
/**
|
925
719
|
*
|
720
|
+
* @param {ConfigureStoreOptions} configureStore object to configure store - same structure as redux configureStore options
|
721
|
+
* @param {MiddlewareList} middlewaresBlacklist list of flower middlewares to blacklist
|
722
|
+
* @returns {Store} redux store instance
|
926
723
|
*/
|
927
|
-
const
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
|
932
|
-
const currentNode = useSelector(makeSelectCurrentNodeId(flowName));
|
933
|
-
const { errors, customErrors, isValid, isSubmitted, isDirty, hasFocus, isValidating } = useSelector(makeSelectNodeErrors(flowName, currentNode));
|
934
|
-
const getData = useCallback((path) => {
|
935
|
-
const { flowNameFromPath = flowName, path: newpath } = CoreUtils.getPath(path);
|
936
|
-
return _get(store.getState(), [
|
937
|
-
'flower',
|
938
|
-
flowNameFromPath,
|
939
|
-
'data',
|
940
|
-
...newpath
|
941
|
-
]);
|
942
|
-
}, [store, flowName]);
|
943
|
-
const getFormStatus = useCallback((path) => {
|
944
|
-
const { flowNameFromPath = flowName, path: newpath } = CoreUtils.getPath(path);
|
945
|
-
return _get(store.getState(), [
|
946
|
-
'flower',
|
947
|
-
flowNameFromPath,
|
948
|
-
'form',
|
949
|
-
...newpath
|
950
|
-
]);
|
951
|
-
}, [store, flowName]);
|
952
|
-
const setDataField = useCallback((id, val, dirty = true) => {
|
953
|
-
const { flowNameFromPath = flowName } = CoreUtils.getPath(id);
|
954
|
-
dispatch(actions.addDataByPath({
|
955
|
-
flowName: flowNameFromPath,
|
956
|
-
id,
|
957
|
-
value: val,
|
958
|
-
dirty
|
959
|
-
}));
|
960
|
-
return;
|
961
|
-
}, [flowName, dispatch]);
|
962
|
-
const setData = useCallback((val, id) => {
|
963
|
-
if (id) {
|
964
|
-
setDataField(id, val);
|
965
|
-
return;
|
966
|
-
}
|
967
|
-
dispatch(actions.addData({ flowName, value: val }));
|
968
|
-
}, [flowName, setDataField, dispatch]);
|
969
|
-
const unsetData = useCallback((path) => {
|
970
|
-
const { flowNameFromPath = flowName, path: newpath } = CoreUtils.getPath(path);
|
971
|
-
dispatch(actions.unsetData({ flowName: flowNameFromPath, id: newpath }));
|
972
|
-
}, [flowName, dispatch]);
|
973
|
-
const replaceData = useCallback((val) => {
|
974
|
-
dispatch(actions.replaceData({ flowName, value: val }));
|
975
|
-
}, [flowName, dispatch]);
|
976
|
-
const reset = useCallback((nodeId) => {
|
977
|
-
dispatch(actions.resetForm({ flowName, id: nodeId || currentNode }));
|
978
|
-
}, [flowName, currentNode, dispatch]);
|
979
|
-
const setCustomErrors = useCallback((field, errors, nodeId) => {
|
980
|
-
dispatch({
|
981
|
-
type: 'flower/formAddCustomErrors',
|
982
|
-
payload: {
|
983
|
-
name: flowName,
|
984
|
-
id: field,
|
985
|
-
currentNode: nodeId || currentNode,
|
986
|
-
errors
|
987
|
-
}
|
724
|
+
const createStoreWithFlower = (configureStore$1, middlewaresBlacklist) => {
|
725
|
+
if (!configureStore$1) {
|
726
|
+
return configureStore({
|
727
|
+
reducer: combineReducers({ ...reducerData, ...reducerFlower }),
|
728
|
+
devTools: true
|
988
729
|
});
|
989
|
-
}
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
|
994
|
-
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
730
|
+
}
|
731
|
+
const { reducer, ...configOptions } = configureStore$1 ?? {};
|
732
|
+
const combinedReducers = combineReducers({
|
733
|
+
...reducerData,
|
734
|
+
...reducerFlower,
|
735
|
+
...(reducer || {})
|
736
|
+
});
|
737
|
+
const flowerMiddlewares = middlewaresBlacklist && !!middlewaresBlacklist.length
|
738
|
+
? middlewares.filter((middleware) => !middlewaresBlacklist.includes(middleware.name))
|
739
|
+
: middlewares;
|
740
|
+
return configureStore({
|
741
|
+
reducer: combinedReducers,
|
742
|
+
...configOptions,
|
743
|
+
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(...flowerMiddlewares, ...(configOptions.middleware ?? []))
|
744
|
+
});
|
745
|
+
};
|
746
|
+
|
747
|
+
const updateAction = (reducerName) => createAction(`${reducerName}/flowerUpdateData`);
|
748
|
+
const createSliceWithFlower = (createSliceOptions) => {
|
749
|
+
const { name, reducers } = createSliceOptions;
|
750
|
+
updateAction(name);
|
751
|
+
const slice = createSlice({
|
752
|
+
...createSliceOptions,
|
753
|
+
reducers: {
|
754
|
+
...reducers,
|
755
|
+
flowerUpdateData: (state, { payload }) => {
|
756
|
+
const { path, value } = payload;
|
757
|
+
set(state, path, value);
|
758
|
+
}
|
759
|
+
}
|
760
|
+
});
|
761
|
+
return slice;
|
1007
762
|
};
|
1008
763
|
|
1009
|
-
export {
|
764
|
+
export { Flower, FlowerAction, FlowerFlow, FlowerNavigate, FlowerNode, FlowerProvider, FlowerRoute, FlowerServer, FlowerStart, createSliceWithFlower, createStoreWithFlower, flowerReducers, makeSelectData, reducerFlower, useFlower, useFlowerNavigate };
|