@beinformed/ui 1.48.1 → 1.49.3
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/CHANGELOG.md +23 -0
- package/esm/hooks/useForm.js +17 -2
- package/esm/hooks/useForm.js.map +1 -1
- package/esm/models/attributes/AttributeModel.js +2 -1
- package/esm/models/attributes/AttributeModel.js.map +1 -1
- package/esm/models/attributes/ChoiceAttributeModel.js +16 -1
- package/esm/models/attributes/ChoiceAttributeModel.js.map +1 -1
- package/esm/models/attributes/ChoiceAttributeOptionCollection.js +10 -3
- package/esm/models/attributes/ChoiceAttributeOptionCollection.js.map +1 -1
- package/esm/models/concepts/ConceptDetailModel.js +7 -0
- package/esm/models/concepts/ConceptDetailModel.js.map +1 -1
- package/esm/models/form/FormModel.js +22 -2
- package/esm/models/form/FormModel.js.map +1 -1
- package/esm/models/form/FormObjectModel.js +9 -1
- package/esm/models/form/FormObjectModel.js.map +1 -1
- package/esm/modularui/ModularUIRequest.js +1 -1
- package/esm/modularui/ModularUIRequest.js.map +1 -1
- package/esm/redux/_modularui/ModularUIActions.js +4 -10
- package/esm/redux/_modularui/ModularUIActions.js.map +1 -1
- package/esm/redux/actions/FormAttributeSet.js +22 -6
- package/esm/redux/actions/FormAttributeSet.js.map +1 -1
- package/esm/redux/actions/FormAutosubmit.js +9 -1
- package/esm/redux/actions/FormAutosubmit.js.map +1 -1
- package/esm/redux/actions/FormAutoupdate.js +29 -0
- package/esm/redux/actions/FormAutoupdate.js.map +1 -0
- package/esm/redux/connectors/FormAttributeSet.js +3 -2
- package/esm/redux/connectors/FormAttributeSet.js.map +1 -1
- package/esm/redux/types.js.map +1 -1
- package/esm/utils/fetch/types.js.map +1 -1
- package/lib/hooks/useForm.js +17 -2
- package/lib/hooks/useForm.js.flow +22 -7
- package/lib/hooks/useForm.js.map +1 -1
- package/lib/models/attributes/AttributeModel.js +2 -1
- package/lib/models/attributes/AttributeModel.js.flow +2 -1
- package/lib/models/attributes/AttributeModel.js.map +1 -1
- package/lib/models/attributes/ChoiceAttributeModel.js +16 -1
- package/lib/models/attributes/ChoiceAttributeModel.js.flow +23 -2
- package/lib/models/attributes/ChoiceAttributeModel.js.map +1 -1
- package/lib/models/attributes/ChoiceAttributeOptionCollection.js +10 -3
- package/lib/models/attributes/ChoiceAttributeOptionCollection.js.flow +16 -8
- package/lib/models/attributes/ChoiceAttributeOptionCollection.js.map +1 -1
- package/lib/models/concepts/ConceptDetailModel.js +7 -0
- package/lib/models/concepts/ConceptDetailModel.js.flow +8 -0
- package/lib/models/concepts/ConceptDetailModel.js.map +1 -1
- package/lib/models/form/FormModel.js +22 -2
- package/lib/models/form/FormModel.js.flow +25 -5
- package/lib/models/form/FormModel.js.map +1 -1
- package/lib/models/form/FormObjectModel.js +9 -1
- package/lib/models/form/FormObjectModel.js.flow +9 -1
- package/lib/models/form/FormObjectModel.js.map +1 -1
- package/lib/modularui/ModularUIRequest.js +1 -1
- package/lib/modularui/ModularUIRequest.js.flow +1 -1
- package/lib/modularui/ModularUIRequest.js.map +1 -1
- package/lib/redux/_modularui/ModularUIActions.js +4 -10
- package/lib/redux/_modularui/ModularUIActions.js.flow +8 -16
- package/lib/redux/_modularui/ModularUIActions.js.map +1 -1
- package/lib/redux/actions/FormAttributeSet.js +22 -6
- package/lib/redux/actions/FormAttributeSet.js.flow +36 -11
- package/lib/redux/actions/FormAttributeSet.js.map +1 -1
- package/lib/redux/actions/FormAutosubmit.js +10 -1
- package/lib/redux/actions/FormAutosubmit.js.flow +10 -3
- package/lib/redux/actions/FormAutosubmit.js.map +1 -1
- package/lib/redux/actions/FormAutoupdate.js +37 -0
- package/lib/redux/actions/FormAutoupdate.js.flow +43 -0
- package/lib/redux/actions/FormAutoupdate.js.map +1 -0
- package/lib/redux/connectors/FormAttributeSet.js +3 -2
- package/lib/redux/connectors/FormAttributeSet.js.flow +4 -2
- package/lib/redux/connectors/FormAttributeSet.js.map +1 -1
- package/lib/redux/types.js.flow +1 -0
- package/lib/redux/types.js.map +1 -1
- package/lib/utils/fetch/types.js.flow +2 -1
- package/lib/utils/fetch/types.js.map +1 -1
- package/package.json +1 -1
- package/src/hooks/useForm.js +22 -7
- package/src/models/attributes/AttributeModel.js +2 -1
- package/src/models/attributes/ChoiceAttributeModel.js +23 -2
- package/src/models/attributes/ChoiceAttributeOptionCollection.js +16 -8
- package/src/models/concepts/ConceptDetailModel.js +8 -0
- package/src/models/form/FormModel.js +25 -5
- package/src/models/form/FormObjectModel.js +9 -1
- package/src/modularui/ModularUIRequest.js +1 -1
- package/src/redux/_modularui/ModularUIActions.js +8 -16
- package/src/redux/actions/FormAttributeSet.js +36 -11
- package/src/redux/actions/FormAutosubmit.js +10 -3
- package/src/redux/actions/FormAutoupdate.js +43 -0
- package/src/redux/connectors/FormAttributeSet.js +4 -2
- package/src/redux/types.js +1 -0
- package/src/utils/fetch/types.js +2 -1
- package/types/hooks/useI18n.d.ts +1 -1
- package/types/models/application/ApplicationModel.d.ts +7 -0
- package/types/models/attributes/AttributeModel.d.ts +4 -3
- package/types/models/attributes/ChoiceAttributeModel.d.ts +4 -0
- package/types/models/attributes/ChoiceAttributeOptionCollection.d.ts +1 -1
- package/types/models/attributes/ChoiceAttributeOptionModel.d.ts +2 -1
- package/types/models/attributes/input-constraints/ConstraintModel.d.ts +1 -1
- package/types/models/base/ResourceCollection.d.ts +2 -1
- package/types/models/base/ResourceModel.d.ts +3 -2
- package/types/models/concepts/BusinessScenarioModel.d.ts +1 -1
- package/types/models/concepts/ConceptRelationModel.d.ts +19 -4
- package/types/models/content/ContentModel.d.ts +4 -0
- package/types/models/content/ContentTOCModel.d.ts +4 -0
- package/types/models/form/FormModel.d.ts +7 -1
- package/types/models/form/FormObjectModel.d.ts +11 -2
- package/types/models/links/normalizeLinkJSON.d.ts +2 -2
- package/types/models/list/ListModel.d.ts +4 -0
- package/types/models/panels/GroupingPanelModel.d.ts +4 -0
- package/types/models/tab/TabModel.d.ts +4 -0
- package/types/models/types.d.ts +2 -1
- package/types/models/user/UserServicesModel.d.ts +7 -0
- package/types/redux/types.d.ts +1 -0
- package/types/utils/fetch/types.d.ts +2 -1
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import { loadModularUI } from "../_modularui/ModularUIActions";
|
|
3
|
+
import { HTTP_METHODS } from "../../constants/Constants";
|
|
4
|
+
|
|
5
|
+
import FormModel from "../../models/form/FormModel";
|
|
6
|
+
|
|
7
|
+
import type { AttributeType, ModularUIModel } from "../../models/types";
|
|
8
|
+
import type { ThunkAction } from "../types";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
*/
|
|
12
|
+
export const autoupdateFormObject = (
|
|
13
|
+
form: FormModel,
|
|
14
|
+
attribute: AttributeType,
|
|
15
|
+
): ?ThunkAction => {
|
|
16
|
+
// As long as we have form objects,
|
|
17
|
+
// and the current attribute is not found in the current form object, go back.
|
|
18
|
+
// When a form has a result, the current form object is null
|
|
19
|
+
while (
|
|
20
|
+
form.allObjects.length > 0 &&
|
|
21
|
+
(!form.currentFormObject ||
|
|
22
|
+
!form.currentFormObject.hasAttributeByKey(attribute.key))
|
|
23
|
+
) {
|
|
24
|
+
form.setPreviousObject();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (form.isChanged()) {
|
|
28
|
+
return loadModularUI(form.connectKey, form.selfhref, {
|
|
29
|
+
method: HTTP_METHODS.POST,
|
|
30
|
+
data: form.formdata,
|
|
31
|
+
updateHandler: (newModel: ModularUIModel): ModularUIModel => {
|
|
32
|
+
if (newModel instanceof FormModel) {
|
|
33
|
+
const clonedModel: FormModel = form.clone();
|
|
34
|
+
clonedModel.updateCurrentFormObject(newModel);
|
|
35
|
+
return clonedModel;
|
|
36
|
+
}
|
|
37
|
+
return newModel;
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return null;
|
|
43
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormAutoupdate.js","names":["_ModularUIActions","require","_Constants","_FormModel","_interopRequireDefault","autoupdateFormObject","form","attribute","allObjects","length","currentFormObject","hasAttributeByKey","key","setPreviousObject","isChanged","loadModularUI","connectKey","selfhref","method","HTTP_METHODS","POST","data","formdata","updateHandler","newModel","FormModel","clonedModel","clone","updateCurrentFormObject","exports"],"sources":["../../../src/redux/actions/FormAutoupdate.js"],"sourcesContent":["// @flow\nimport { loadModularUI } from \"../_modularui/ModularUIActions\";\nimport { HTTP_METHODS } from \"../../constants/Constants\";\n\nimport FormModel from \"../../models/form/FormModel\";\n\nimport type { AttributeType, ModularUIModel } from \"../../models/types\";\nimport type { ThunkAction } from \"../types\";\n\n/**\n */\nexport const autoupdateFormObject = (\n form: FormModel,\n attribute: AttributeType,\n): ?ThunkAction => {\n // As long as we have form objects,\n // and the current attribute is not found in the current form object, go back.\n // When a form has a result, the current form object is null\n while (\n form.allObjects.length > 0 &&\n (!form.currentFormObject ||\n !form.currentFormObject.hasAttributeByKey(attribute.key))\n ) {\n form.setPreviousObject();\n }\n\n if (form.isChanged()) {\n return loadModularUI(form.connectKey, form.selfhref, {\n method: HTTP_METHODS.POST,\n data: form.formdata,\n updateHandler: (newModel: ModularUIModel): ModularUIModel => {\n if (newModel instanceof FormModel) {\n const clonedModel: FormModel = form.clone();\n clonedModel.updateCurrentFormObject(newModel);\n return clonedModel;\n }\n return newModel;\n },\n });\n }\n\n return null;\n};\n"],"mappings":";;;;;;;AACA,IAAAA,iBAAA,GAAAC,OAAA;AACA,IAAAC,UAAA,GAAAD,OAAA;AAEA,IAAAE,UAAA,GAAAC,sBAAA,CAAAH,OAAA;AAKA;AACA;AACO,MAAMI,oBAAoB,GAAGA,CAClCC,IAAe,EACfC,SAAwB,KACP;EACjB;EACA;EACA;EACA,OACED,IAAI,CAACE,UAAU,CAACC,MAAM,GAAG,CAAC,KACzB,CAACH,IAAI,CAACI,iBAAiB,IACtB,CAACJ,IAAI,CAACI,iBAAiB,CAACC,iBAAiB,CAACJ,SAAS,CAACK,GAAG,CAAC,CAAC,EAC3D;IACAN,IAAI,CAACO,iBAAiB,CAAC,CAAC;EAC1B;EAEA,IAAIP,IAAI,CAACQ,SAAS,CAAC,CAAC,EAAE;IACpB,OAAO,IAAAC,+BAAa,EAACT,IAAI,CAACU,UAAU,EAAEV,IAAI,CAACW,QAAQ,EAAE;MACnDC,MAAM,EAAEC,uBAAY,CAACC,IAAI;MACzBC,IAAI,EAAEf,IAAI,CAACgB,QAAQ;MACnBC,aAAa,EAAGC,QAAwB,IAAqB;QAC3D,IAAIA,QAAQ,YAAYC,kBAAS,EAAE;UACjC,MAAMC,WAAsB,GAAGpB,IAAI,CAACqB,KAAK,CAAC,CAAC;UAC3CD,WAAW,CAACE,uBAAuB,CAACJ,QAAQ,CAAC;UAC7C,OAAOE,WAAW;QACpB;QACA,OAAOF,QAAQ;MACjB;IACF,CAAC,CAAC;EACJ;EAEA,OAAO,IAAI;AACb,CAAC;AAACK,OAAA,CAAAxB,oBAAA,GAAAA,oBAAA","ignoreList":[]}
|
|
@@ -10,8 +10,9 @@ var _FormAttributeSetRepeatable = require("../actions/FormAttributeSetRepeatable
|
|
|
10
10
|
const mapDispatchToProps = (dispatch, ownProps) => ({
|
|
11
11
|
onAttributeChange: function (attribute, value) {
|
|
12
12
|
let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
|
|
13
|
-
autosubmit: ownProps.autosubmit
|
|
14
|
-
autosave: ownProps.autosave
|
|
13
|
+
autosubmit: ownProps.autosubmit ?? false,
|
|
14
|
+
autosave: ownProps.autosave ?? false,
|
|
15
|
+
autoupdate: ownProps.autoupdate ?? false
|
|
15
16
|
};
|
|
16
17
|
return dispatch((0, _FormAttributeSet.updateFormAttribute)(ownProps.form, ownProps.object, attribute, value, options));
|
|
17
18
|
},
|
|
@@ -24,6 +24,7 @@ type OwnProps = {
|
|
|
24
24
|
formLayout?: "vertical" | "horizontal" | "compact",
|
|
25
25
|
autosubmit?: boolean,
|
|
26
26
|
autosave?: boolean,
|
|
27
|
+
autoupdate?: boolean,
|
|
27
28
|
};
|
|
28
29
|
|
|
29
30
|
type DispatchProps = {
|
|
@@ -50,8 +51,9 @@ const mapDispatchToProps = (
|
|
|
50
51
|
attribute: AttributeType,
|
|
51
52
|
value: string,
|
|
52
53
|
options: UpdateFormOptions = {
|
|
53
|
-
autosubmit: ownProps.autosubmit
|
|
54
|
-
autosave: ownProps.autosave
|
|
54
|
+
autosubmit: ownProps.autosubmit ?? false,
|
|
55
|
+
autosave: ownProps.autosave ?? false,
|
|
56
|
+
autoupdate: ownProps.autoupdate ?? false,
|
|
55
57
|
},
|
|
56
58
|
) =>
|
|
57
59
|
dispatch(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormAttributeSet.js","names":["_reactRedux","require","_FormAttributeSet","_FormAttributeSetRepeatable","mapDispatchToProps","dispatch","ownProps","onAttributeChange","attribute","value","options","arguments","length","undefined","autosubmit","autosave","updateFormAttribute","form","object","onAddAttributeSetClick","addRepeatableAttributeSet","onCancelAttributeSetClick","formObject","cancelRepeatableAttributeSet","onRemoveAttributeSetClick","removeRepeatableAttributeSet","connectFormAttributeSet","exports","connect"],"sources":["../../../src/redux/connectors/FormAttributeSet.js"],"sourcesContent":["// @flow\nimport { connect } from \"react-redux\";\n\nimport { updateFormAttribute } from \"../actions/FormAttributeSet\";\nimport {\n addRepeatableAttributeSet,\n cancelRepeatableAttributeSet,\n removeRepeatableAttributeSet,\n} from \"../actions/FormAttributeSetRepeatable\";\n\nimport type { ThunkAction, UpdateFormOptions } from \"../types\";\nimport type { UpdateFormAction } from \"../_modularui/types\";\nimport type { AttributeType } from \"../../models/types\";\nimport type FormModel from \"../../models/form/FormModel\";\nimport type FormObjectModel from \"../../models/form/FormObjectModel\";\nimport type { DispatchAPI } from \"redux\";\nimport type { ComponentType } from \"react\";\n\ntype Dispatch = DispatchAPI<UpdateFormAction> & DispatchAPI<ThunkAction>;\n\ntype OwnProps = {\n form: FormModel,\n object: FormObjectModel,\n formLayout?: \"vertical\" | \"horizontal\" | \"compact\",\n autosubmit?: boolean,\n autosave?: boolean,\n};\n\ntype DispatchProps = {\n onAttributeChange: (\n attribute: AttributeType,\n value: string,\n options: UpdateFormOptions,\n ) => ThunkAction,\n onAddAttributeSetClick: () => UpdateFormAction,\n onCancelAttributeSetClick: (formObject: FormObjectModel) => UpdateFormAction,\n onRemoveAttributeSetClick: (formObject: FormObjectModel) => UpdateFormAction,\n};\n\ntype Props = {\n ...OwnProps,\n ...DispatchProps,\n};\n\nconst mapDispatchToProps = (\n dispatch: Dispatch,\n ownProps: OwnProps,\n): DispatchProps => ({\n onAttributeChange: (\n attribute: AttributeType,\n value: string,\n options: UpdateFormOptions = {\n autosubmit: ownProps.autosubmit
|
|
1
|
+
{"version":3,"file":"FormAttributeSet.js","names":["_reactRedux","require","_FormAttributeSet","_FormAttributeSetRepeatable","mapDispatchToProps","dispatch","ownProps","onAttributeChange","attribute","value","options","arguments","length","undefined","autosubmit","autosave","autoupdate","updateFormAttribute","form","object","onAddAttributeSetClick","addRepeatableAttributeSet","onCancelAttributeSetClick","formObject","cancelRepeatableAttributeSet","onRemoveAttributeSetClick","removeRepeatableAttributeSet","connectFormAttributeSet","exports","connect"],"sources":["../../../src/redux/connectors/FormAttributeSet.js"],"sourcesContent":["// @flow\nimport { connect } from \"react-redux\";\n\nimport { updateFormAttribute } from \"../actions/FormAttributeSet\";\nimport {\n addRepeatableAttributeSet,\n cancelRepeatableAttributeSet,\n removeRepeatableAttributeSet,\n} from \"../actions/FormAttributeSetRepeatable\";\n\nimport type { ThunkAction, UpdateFormOptions } from \"../types\";\nimport type { UpdateFormAction } from \"../_modularui/types\";\nimport type { AttributeType } from \"../../models/types\";\nimport type FormModel from \"../../models/form/FormModel\";\nimport type FormObjectModel from \"../../models/form/FormObjectModel\";\nimport type { DispatchAPI } from \"redux\";\nimport type { ComponentType } from \"react\";\n\ntype Dispatch = DispatchAPI<UpdateFormAction> & DispatchAPI<ThunkAction>;\n\ntype OwnProps = {\n form: FormModel,\n object: FormObjectModel,\n formLayout?: \"vertical\" | \"horizontal\" | \"compact\",\n autosubmit?: boolean,\n autosave?: boolean,\n autoupdate?: boolean,\n};\n\ntype DispatchProps = {\n onAttributeChange: (\n attribute: AttributeType,\n value: string,\n options: UpdateFormOptions,\n ) => ThunkAction,\n onAddAttributeSetClick: () => UpdateFormAction,\n onCancelAttributeSetClick: (formObject: FormObjectModel) => UpdateFormAction,\n onRemoveAttributeSetClick: (formObject: FormObjectModel) => UpdateFormAction,\n};\n\ntype Props = {\n ...OwnProps,\n ...DispatchProps,\n};\n\nconst mapDispatchToProps = (\n dispatch: Dispatch,\n ownProps: OwnProps,\n): DispatchProps => ({\n onAttributeChange: (\n attribute: AttributeType,\n value: string,\n options: UpdateFormOptions = {\n autosubmit: ownProps.autosubmit ?? false,\n autosave: ownProps.autosave ?? false,\n autoupdate: ownProps.autoupdate ?? false,\n },\n ) =>\n dispatch(\n updateFormAttribute(\n ownProps.form,\n ownProps.object,\n attribute,\n value,\n options,\n ),\n ),\n onAddAttributeSetClick: () =>\n dispatch(addRepeatableAttributeSet(ownProps.form)),\n onCancelAttributeSetClick: (formObject: FormObjectModel) =>\n dispatch(cancelRepeatableAttributeSet(ownProps.form, formObject)),\n onRemoveAttributeSetClick: (formObject: FormObjectModel) =>\n dispatch(removeRepeatableAttributeSet(ownProps.form, formObject)),\n});\n\n/**\n */\nexport const connectFormAttributeSet: ComponentType<any> = connect<\n Props,\n OwnProps,\n _,\n DispatchProps,\n _,\n _,\n>(null, mapDispatchToProps);\n"],"mappings":";;;;;;AACA,IAAAA,WAAA,GAAAC,OAAA;AAEA,IAAAC,iBAAA,GAAAD,OAAA;AACA,IAAAE,2BAAA,GAAAF,OAAA;AAyCA,MAAMG,kBAAkB,GAAGA,CACzBC,QAAkB,EAClBC,QAAkB,MACC;EACnBC,iBAAiB,EAAE,SAAAA,CACjBC,SAAwB,EACxBC,KAAa;IAAA,IACbC,OAA0B,GAAAC,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAAE,SAAA,GAAAF,SAAA,MAAG;MAC3BG,UAAU,EAAER,QAAQ,CAACQ,UAAU,IAAI,KAAK;MACxCC,QAAQ,EAAET,QAAQ,CAACS,QAAQ,IAAI,KAAK;MACpCC,UAAU,EAAEV,QAAQ,CAACU,UAAU,IAAI;IACrC,CAAC;IAAA,OAEDX,QAAQ,CACN,IAAAY,qCAAmB,EACjBX,QAAQ,CAACY,IAAI,EACbZ,QAAQ,CAACa,MAAM,EACfX,SAAS,EACTC,KAAK,EACLC,OACF,CACF,CAAC;EAAA;EACHU,sBAAsB,EAAEA,CAAA,KACtBf,QAAQ,CAAC,IAAAgB,qDAAyB,EAACf,QAAQ,CAACY,IAAI,CAAC,CAAC;EACpDI,yBAAyB,EAAGC,UAA2B,IACrDlB,QAAQ,CAAC,IAAAmB,wDAA4B,EAAClB,QAAQ,CAACY,IAAI,EAAEK,UAAU,CAAC,CAAC;EACnEE,yBAAyB,EAAGF,UAA2B,IACrDlB,QAAQ,CAAC,IAAAqB,wDAA4B,EAACpB,QAAQ,CAACY,IAAI,EAAEK,UAAU,CAAC;AACpE,CAAC,CAAC;;AAEF;AACA;AACO,MAAMI,uBAA2C,GAAAC,OAAA,CAAAD,uBAAA,GAAG,IAAAE,mBAAO,EAOhE,IAAI,EAAEzB,kBAAkB,CAAC","ignoreList":[]}
|
package/lib/redux/types.js.flow
CHANGED
|
@@ -46,6 +46,7 @@ export type PreferenceValue =
|
|
|
46
46
|
export type UpdateFormOptions = {
|
|
47
47
|
autosubmit: boolean,
|
|
48
48
|
autosave: boolean,
|
|
49
|
+
autoupdate: boolean,
|
|
49
50
|
forceUpdate?: boolean,
|
|
50
51
|
/** Default true: Activate/deactivate the form object validate by an update */
|
|
51
52
|
validate?: boolean,
|
package/lib/redux/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","names":[],"sources":["../../src/redux/types.js"],"sourcesContent":["// @flow\nimport type { Store, DispatchAPI } from \"redux\";\n\nimport type ErrorResponse from \"../models/error/ErrorResponse\";\n\nimport type FormModel from \"../models/form/FormModel\";\nimport typeof {\n NOTIFICATION_TYPES,\n AUTOSAVE_STATUS,\n} from \"../constants/Constants\";\n\nimport type { MessageObject } from \"../i18n/types\";\nimport type {\n I18nState,\n UpdateLocaleAction,\n SetLocalesAction,\n} from \"./_i18n/types\";\nimport type {\n ModularUIState,\n ModularUIAction,\n UpdateStatusAction,\n SetModelAction,\n UpdateModelAction,\n UpdateFormAction,\n RemoveModelByKeyAction,\n ResetModularUIAction,\n InitModelAction,\n} from \"./_modularui/types\";\nimport type {\n RouterState,\n LocationChangeAction,\n PushAction,\n ReplaceAction,\n GoAction,\n GoBackAction,\n GoForwardAction,\n} from \"./_router/types\";\n\nexport type PreferenceValue =\n | null\n | string\n | boolean\n | { [key: string]: any }\n | Array<PreferenceValue>;\n\nexport type UpdateFormOptions = {\n autosubmit: boolean,\n autosave: boolean,\n forceUpdate?: boolean,\n /** Default true: Activate/deactivate the form object validate by an update */\n validate?: boolean,\n};\n\nexport type NoAction = {\n type: \"NO_ACTION\",\n};\n\nexport type SaveErrorAction = {\n type: \"SAVE_ERROR\",\n payload: ErrorResponse,\n};\n\nexport type ShowModalAction = {\n type: \"SHOW_MODAL\",\n payload: string,\n};\n\nexport type CloseModalAction = {\n type: \"CLOSE_MODAL\",\n payload: string,\n};\n\nexport type DismissNotificationAction = {\n type: \"DISMISS_NOTIFICATION\",\n};\nexport type ShowNotificationAction = {\n type: \"SHOW_NOTIFICATION\",\n payload: {\n type: $Keys<NOTIFICATION_TYPES>,\n message: MessageObject,\n error: ?ErrorResponse,\n },\n};\n\nexport type SetPreferenceAction = {\n type: \"SET_PREFERENCE\",\n payload: { [name: string]: PreferenceValue },\n};\nexport type SetPreferencesAction = {\n type: \"SET_PREFERENCES\",\n payload: { [name: string]: PreferenceValue },\n};\n\nexport type StartProgressAction = {\n type: \"START_PROGRESS\",\n};\nexport type FinishProgressAction = {\n type: \"FINISH_PROGRESS\",\n};\nexport type ResetProgressAction = {\n type: \"RESET_PROGRESS\",\n};\nexport type UpdateProgressAction = {\n type: \"UPDATE_PROGRESS\",\n payload: { percentComplete: number },\n};\n\nexport type SendAuthenticationErrorAction = {\n type: \"AUTHENTICATION_ERROR\",\n payload: string,\n};\n\nexport type ResetAuthErrorsAction = {\n type: \"AUTHENTICATION_RESET_ERRORS\",\n};\n\nexport type LoginSuccessAction = {\n type: \"AUTHENTICATION_SUCCESS\",\n};\n\nexport type ChangePasswordAction = {\n type: \"CHANGE_PASSWORD\",\n};\n\nexport type LogoutSuccessAction = {\n type: \"AUTHENTICATION_LOGOUT\",\n};\n\nexport type UpdateAutosaveAction = {\n type: \"UPDATE_AUTOSAVE_STATUS\",\n payload: {\n status: $Keys<AUTOSAVE_STATUS>,\n model: FormModel,\n },\n};\n\nexport type ReduxAction =\n | UpdateStatusAction\n | SetModelAction\n | InitModelAction\n | UpdateModelAction\n | UpdateFormAction\n | RemoveModelByKeyAction\n | ResetModularUIAction\n | SaveErrorAction\n | UpdateLocaleAction\n | SetLocalesAction\n | ShowModalAction\n | CloseModalAction\n | DismissNotificationAction\n | ShowNotificationAction\n | SetPreferenceAction\n | SetPreferencesAction\n | StartProgressAction\n | FinishProgressAction\n | ResetProgressAction\n | UpdateProgressAction\n | ResetAuthErrorsAction\n | SendAuthenticationErrorAction\n | LoginSuccessAction\n | ChangePasswordAction\n | LogoutSuccessAction\n | UpdateAutosaveAction\n | LocationChangeAction\n | PushAction\n | ReplaceAction\n | GoAction\n | GoBackAction\n | GoForwardAction\n | ModularUIAction\n | NoAction;\n\n// Redux state\nexport type AuthState = {\n +mustChangePassword: boolean,\n +error: ?string,\n};\n\nexport type ErrorState = null | ErrorResponse;\n\nexport type ModalState = {\n +key: string,\n +visible: boolean,\n +size?: string,\n};\n\nexport type ModalsState = {\n +modals: Array<ModalState>,\n};\n\nexport type NotificationState = {\n +render: boolean,\n +messageType: string | null,\n +message: MessageObject | null,\n +error: ?ErrorResponse | null,\n};\n\nexport type PreferencesState = {\n +[name: string]: PreferenceValue,\n};\n\nexport type ProgressIndicatorState = {\n +count: number,\n +timestamp: number,\n +percentComplete: number,\n};\n\nexport type ReduxState = {\n +router: RouterState,\n +modularui: ModularUIState,\n +i18n: I18nState,\n +auth: AuthState,\n +error: ErrorState,\n +modals: ModalsState,\n +notification: NotificationState,\n +progressindicator: ProgressIndicatorState,\n +preferences: PreferencesState,\n ...\n};\n\nexport type GetState = () => ReduxState;\nexport type ThunkAction = (dispatch: Dispatch, getState: GetState) => any;\nexport type PromiseAction = Promise<PossibleAction>;\nexport type Dispatch = DispatchAPI<PossibleAction>;\nexport type ReduxStore = Store<ReduxState, ReduxAction, Dispatch>;\n\nexport type PossibleAction = ReduxAction | ThunkAction | PromiseAction;\n\nexport type CustomReducers = { [reducerKey: string]: any };\n"],"mappings":"","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"types.js","names":[],"sources":["../../src/redux/types.js"],"sourcesContent":["// @flow\nimport type { Store, DispatchAPI } from \"redux\";\n\nimport type ErrorResponse from \"../models/error/ErrorResponse\";\n\nimport type FormModel from \"../models/form/FormModel\";\nimport typeof {\n NOTIFICATION_TYPES,\n AUTOSAVE_STATUS,\n} from \"../constants/Constants\";\n\nimport type { MessageObject } from \"../i18n/types\";\nimport type {\n I18nState,\n UpdateLocaleAction,\n SetLocalesAction,\n} from \"./_i18n/types\";\nimport type {\n ModularUIState,\n ModularUIAction,\n UpdateStatusAction,\n SetModelAction,\n UpdateModelAction,\n UpdateFormAction,\n RemoveModelByKeyAction,\n ResetModularUIAction,\n InitModelAction,\n} from \"./_modularui/types\";\nimport type {\n RouterState,\n LocationChangeAction,\n PushAction,\n ReplaceAction,\n GoAction,\n GoBackAction,\n GoForwardAction,\n} from \"./_router/types\";\n\nexport type PreferenceValue =\n | null\n | string\n | boolean\n | { [key: string]: any }\n | Array<PreferenceValue>;\n\nexport type UpdateFormOptions = {\n autosubmit: boolean,\n autosave: boolean,\n autoupdate: boolean,\n forceUpdate?: boolean,\n /** Default true: Activate/deactivate the form object validate by an update */\n validate?: boolean,\n};\n\nexport type NoAction = {\n type: \"NO_ACTION\",\n};\n\nexport type SaveErrorAction = {\n type: \"SAVE_ERROR\",\n payload: ErrorResponse,\n};\n\nexport type ShowModalAction = {\n type: \"SHOW_MODAL\",\n payload: string,\n};\n\nexport type CloseModalAction = {\n type: \"CLOSE_MODAL\",\n payload: string,\n};\n\nexport type DismissNotificationAction = {\n type: \"DISMISS_NOTIFICATION\",\n};\nexport type ShowNotificationAction = {\n type: \"SHOW_NOTIFICATION\",\n payload: {\n type: $Keys<NOTIFICATION_TYPES>,\n message: MessageObject,\n error: ?ErrorResponse,\n },\n};\n\nexport type SetPreferenceAction = {\n type: \"SET_PREFERENCE\",\n payload: { [name: string]: PreferenceValue },\n};\nexport type SetPreferencesAction = {\n type: \"SET_PREFERENCES\",\n payload: { [name: string]: PreferenceValue },\n};\n\nexport type StartProgressAction = {\n type: \"START_PROGRESS\",\n};\nexport type FinishProgressAction = {\n type: \"FINISH_PROGRESS\",\n};\nexport type ResetProgressAction = {\n type: \"RESET_PROGRESS\",\n};\nexport type UpdateProgressAction = {\n type: \"UPDATE_PROGRESS\",\n payload: { percentComplete: number },\n};\n\nexport type SendAuthenticationErrorAction = {\n type: \"AUTHENTICATION_ERROR\",\n payload: string,\n};\n\nexport type ResetAuthErrorsAction = {\n type: \"AUTHENTICATION_RESET_ERRORS\",\n};\n\nexport type LoginSuccessAction = {\n type: \"AUTHENTICATION_SUCCESS\",\n};\n\nexport type ChangePasswordAction = {\n type: \"CHANGE_PASSWORD\",\n};\n\nexport type LogoutSuccessAction = {\n type: \"AUTHENTICATION_LOGOUT\",\n};\n\nexport type UpdateAutosaveAction = {\n type: \"UPDATE_AUTOSAVE_STATUS\",\n payload: {\n status: $Keys<AUTOSAVE_STATUS>,\n model: FormModel,\n },\n};\n\nexport type ReduxAction =\n | UpdateStatusAction\n | SetModelAction\n | InitModelAction\n | UpdateModelAction\n | UpdateFormAction\n | RemoveModelByKeyAction\n | ResetModularUIAction\n | SaveErrorAction\n | UpdateLocaleAction\n | SetLocalesAction\n | ShowModalAction\n | CloseModalAction\n | DismissNotificationAction\n | ShowNotificationAction\n | SetPreferenceAction\n | SetPreferencesAction\n | StartProgressAction\n | FinishProgressAction\n | ResetProgressAction\n | UpdateProgressAction\n | ResetAuthErrorsAction\n | SendAuthenticationErrorAction\n | LoginSuccessAction\n | ChangePasswordAction\n | LogoutSuccessAction\n | UpdateAutosaveAction\n | LocationChangeAction\n | PushAction\n | ReplaceAction\n | GoAction\n | GoBackAction\n | GoForwardAction\n | ModularUIAction\n | NoAction;\n\n// Redux state\nexport type AuthState = {\n +mustChangePassword: boolean,\n +error: ?string,\n};\n\nexport type ErrorState = null | ErrorResponse;\n\nexport type ModalState = {\n +key: string,\n +visible: boolean,\n +size?: string,\n};\n\nexport type ModalsState = {\n +modals: Array<ModalState>,\n};\n\nexport type NotificationState = {\n +render: boolean,\n +messageType: string | null,\n +message: MessageObject | null,\n +error: ?ErrorResponse | null,\n};\n\nexport type PreferencesState = {\n +[name: string]: PreferenceValue,\n};\n\nexport type ProgressIndicatorState = {\n +count: number,\n +timestamp: number,\n +percentComplete: number,\n};\n\nexport type ReduxState = {\n +router: RouterState,\n +modularui: ModularUIState,\n +i18n: I18nState,\n +auth: AuthState,\n +error: ErrorState,\n +modals: ModalsState,\n +notification: NotificationState,\n +progressindicator: ProgressIndicatorState,\n +preferences: PreferencesState,\n ...\n};\n\nexport type GetState = () => ReduxState;\nexport type ThunkAction = (dispatch: Dispatch, getState: GetState) => any;\nexport type PromiseAction = Promise<PossibleAction>;\nexport type Dispatch = DispatchAPI<PossibleAction>;\nexport type ReduxStore = Store<ReduxState, ReduxAction, Dispatch>;\n\nexport type PossibleAction = ReduxAction | ThunkAction | PromiseAction;\n\nexport type CustomReducers = { [reducerKey: string]: any };\n"],"mappings":"","ignoreList":[]}
|
|
@@ -31,11 +31,12 @@ export type RequestBaseOptions = {
|
|
|
31
31
|
|
|
32
32
|
export type RequestOptions = { ...RequestURLOptions, ...RequestBaseOptions };
|
|
33
33
|
|
|
34
|
+
export type UpdateHandler = (newModel: ModularUIModel) => ModularUIModel;
|
|
34
35
|
export type RequestModularUIOptions = {
|
|
35
36
|
...RequestBaseOptions,
|
|
36
37
|
targetModel?: TargetModel,
|
|
37
38
|
forceTargetModel?: boolean,
|
|
38
|
-
|
|
39
|
+
updateHandler?: UpdateHandler | void,
|
|
39
40
|
childmodels?: boolean,
|
|
40
41
|
isValidationRequest?: boolean,
|
|
41
42
|
removeOnUnmount?: boolean,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","names":[],"sources":["../../../src/utils/fetch/types.js"],"sourcesContent":["// @flow\nimport typeof { HTTP_METHODS } from \"../../constants/Constants\";\nimport type { ModularUIModel } from \"../../models/types\";\nimport type { TargetModel } from \"../../modularui/types\";\n\nexport type RequestURLOptions = {\n url: string,\n};\n\nexport type RequestBaseOptions = {\n method?: $Keys<HTTP_METHODS>,\n params?: string,\n data?: any,\n timeout?: number,\n responseType?: string,\n headers?: {\n [headerName: string]: string,\n Accept?: string,\n \"Accept-Language\"?: string,\n \"Content-Type\"?: string,\n \"x-filename\"?: string,\n \"x-filesize\"?: string,\n },\n events?: { [eventName: string]: () => void },\n onProgress?: ProgressEventHandler,\n includeContext?: boolean,\n locale?: string,\n cache?: boolean,\n isReload?: boolean,\n};\n\nexport type RequestOptions = { ...RequestURLOptions, ...RequestBaseOptions };\n\nexport type RequestModularUIOptions = {\n ...RequestBaseOptions,\n targetModel?: TargetModel,\n forceTargetModel?: boolean,\n
|
|
1
|
+
{"version":3,"file":"types.js","names":[],"sources":["../../../src/utils/fetch/types.js"],"sourcesContent":["// @flow\nimport typeof { HTTP_METHODS } from \"../../constants/Constants\";\nimport type { ModularUIModel } from \"../../models/types\";\nimport type { TargetModel } from \"../../modularui/types\";\n\nexport type RequestURLOptions = {\n url: string,\n};\n\nexport type RequestBaseOptions = {\n method?: $Keys<HTTP_METHODS>,\n params?: string,\n data?: any,\n timeout?: number,\n responseType?: string,\n headers?: {\n [headerName: string]: string,\n Accept?: string,\n \"Accept-Language\"?: string,\n \"Content-Type\"?: string,\n \"x-filename\"?: string,\n \"x-filesize\"?: string,\n },\n events?: { [eventName: string]: () => void },\n onProgress?: ProgressEventHandler,\n includeContext?: boolean,\n locale?: string,\n cache?: boolean,\n isReload?: boolean,\n};\n\nexport type RequestOptions = { ...RequestURLOptions, ...RequestBaseOptions };\n\nexport type UpdateHandler = (newModel: ModularUIModel) => ModularUIModel;\nexport type RequestModularUIOptions = {\n ...RequestBaseOptions,\n targetModel?: TargetModel,\n forceTargetModel?: boolean,\n updateHandler?: UpdateHandler | void,\n childmodels?: boolean,\n isValidationRequest?: boolean,\n removeOnUnmount?: boolean,\n};\n"],"mappings":"","ignoreList":[]}
|
package/package.json
CHANGED
package/src/hooks/useForm.js
CHANGED
|
@@ -5,6 +5,10 @@ import Href from "../models/href/Href";
|
|
|
5
5
|
|
|
6
6
|
import { getSetting, HTTP_METHODS } from "../constants";
|
|
7
7
|
|
|
8
|
+
import type {
|
|
9
|
+
RemoveModelByKeyAction,
|
|
10
|
+
UpdateFormAction,
|
|
11
|
+
} from "../redux/_modularui";
|
|
8
12
|
import { loadModularUI, removeModelByKey } from "../redux/_modularui";
|
|
9
13
|
import { useModularUI } from "./useModularUI";
|
|
10
14
|
|
|
@@ -20,12 +24,8 @@ import {
|
|
|
20
24
|
|
|
21
25
|
import FormModel from "../models/form/FormModel";
|
|
22
26
|
|
|
23
|
-
import type { FormObjectModel,
|
|
27
|
+
import type { AttributeType, FormObjectModel, ModularUIModel } from "../models";
|
|
24
28
|
import type { UpdateFormOptions } from "../redux/types";
|
|
25
|
-
import type {
|
|
26
|
-
RemoveModelByKeyAction,
|
|
27
|
-
UpdateFormAction,
|
|
28
|
-
} from "../redux/_modularui";
|
|
29
29
|
|
|
30
30
|
type FormNavigationHook = {
|
|
31
31
|
previous: (form: FormModel) => UpdateFormAction,
|
|
@@ -84,7 +84,14 @@ export const useFormNavigation = (): FormNavigationHook => {
|
|
|
84
84
|
loadModularUI(form.connectKey, form.selfhref, {
|
|
85
85
|
method: HTTP_METHODS.POST,
|
|
86
86
|
data: form.formdata,
|
|
87
|
-
|
|
87
|
+
updateHandler: (newModel: ModularUIModel): ModularUIModel => {
|
|
88
|
+
if (newModel instanceof FormModel) {
|
|
89
|
+
const clonedModel: FormModel = form.clone();
|
|
90
|
+
clonedModel.update(newModel);
|
|
91
|
+
return clonedModel;
|
|
92
|
+
}
|
|
93
|
+
return newModel;
|
|
94
|
+
},
|
|
88
95
|
targetModel: FormModel,
|
|
89
96
|
}),
|
|
90
97
|
);
|
|
@@ -105,7 +112,15 @@ export const useFormNavigation = (): FormNavigationHook => {
|
|
|
105
112
|
};
|
|
106
113
|
|
|
107
114
|
/**
|
|
108
|
-
*
|
|
115
|
+
* Hook that returns a function to update attributes of a form object.
|
|
116
|
+
* <br >
|
|
117
|
+
* The returned function accepts the following options:
|
|
118
|
+
*
|
|
119
|
+
* - autosubmit: Automatically submit the form after a change
|
|
120
|
+
* - autosav: Automatically save the form (in the background) after a change
|
|
121
|
+
* - autoupdate: Automatically update the current form object after a change
|
|
122
|
+
* - forceUpdate: Force the update even if conditions are not met.
|
|
123
|
+
* - validate: Activate/deactivate the form object validation by an update.
|
|
109
124
|
*/
|
|
110
125
|
export const useAttributeUpdate = (
|
|
111
126
|
form: FormModel,
|
|
@@ -744,7 +744,8 @@ export default class AttributeModel
|
|
|
744
744
|
/**
|
|
745
745
|
* Registers a missing error that was received from the server
|
|
746
746
|
*/
|
|
747
|
-
|
|
747
|
+
// eslint-disable-next-line no-unused-vars
|
|
748
|
+
addMissingError(receivedAttribute?: AttributeType): void {
|
|
748
749
|
this._errorCollection.addServerError("Constraint.Missing");
|
|
749
750
|
}
|
|
750
751
|
|
|
@@ -303,11 +303,19 @@ export default class ChoiceAttributeModel extends AttributeModel {
|
|
|
303
303
|
|
|
304
304
|
/**
|
|
305
305
|
*/
|
|
306
|
-
mergeAttribute(
|
|
306
|
+
mergeAttribute(
|
|
307
|
+
oldAttribute: AttributeType,
|
|
308
|
+
addNotExistingOptions: boolean = false,
|
|
309
|
+
removeNotExistingOptions: boolean = false,
|
|
310
|
+
) {
|
|
307
311
|
// when attribute is readonly, don't merge the options no modifications necessary
|
|
308
312
|
if (!this.readonly && oldAttribute instanceof ChoiceAttributeModel) {
|
|
309
313
|
this.concept = oldAttribute.concept;
|
|
310
|
-
this.options.mergeOptions(
|
|
314
|
+
this.options.mergeOptions(
|
|
315
|
+
oldAttribute.options,
|
|
316
|
+
addNotExistingOptions ?? this.type === "lookup",
|
|
317
|
+
removeNotExistingOptions,
|
|
318
|
+
);
|
|
311
319
|
this.options.deselectAll();
|
|
312
320
|
|
|
313
321
|
if (oldAttribute.isValid && oldAttribute.inputvalue !== null) {
|
|
@@ -354,6 +362,19 @@ export default class ChoiceAttributeModel extends AttributeModel {
|
|
|
354
362
|
return this;
|
|
355
363
|
}
|
|
356
364
|
|
|
365
|
+
/**
|
|
366
|
+
* Registers a missing error that was received from the server
|
|
367
|
+
*/
|
|
368
|
+
addMissingError(receivedAttribute?: AttributeType): void {
|
|
369
|
+
if (this.isChangedSince(0)) {
|
|
370
|
+
this._errorCollection.addServerError("Constraint.Missing");
|
|
371
|
+
}
|
|
372
|
+
// update choice options
|
|
373
|
+
if (receivedAttribute instanceof ChoiceAttributeModel) {
|
|
374
|
+
this.mergeAttribute(receivedAttribute, true, true);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
357
378
|
/**
|
|
358
379
|
*/
|
|
359
380
|
set hasContentConfiguration(hasContentConfiguration: boolean) {
|
|
@@ -309,15 +309,9 @@ class ChoiceAttributeOptionCollection extends ResourceCollection<ChoiceAttribute
|
|
|
309
309
|
mergeOptions(
|
|
310
310
|
withOptions: ChoiceAttributeOptionCollection,
|
|
311
311
|
addNotExistingOptions: boolean = false,
|
|
312
|
+
removeNotExistingOptions: boolean = false,
|
|
312
313
|
) {
|
|
313
|
-
|
|
314
|
-
this.collection = [
|
|
315
|
-
...this.collection,
|
|
316
|
-
...withOptions.filter(
|
|
317
|
-
(option) => !this.collection.some((opt) => opt.code === option.code),
|
|
318
|
-
),
|
|
319
|
-
];
|
|
320
|
-
}
|
|
314
|
+
const newCollection = [];
|
|
321
315
|
|
|
322
316
|
this.collection.forEach((option) => {
|
|
323
317
|
const foundOption = withOptions.find(
|
|
@@ -325,8 +319,22 @@ class ChoiceAttributeOptionCollection extends ResourceCollection<ChoiceAttribute
|
|
|
325
319
|
);
|
|
326
320
|
if (foundOption) {
|
|
327
321
|
option.mergeOption(foundOption);
|
|
322
|
+
newCollection.push(option);
|
|
323
|
+
} else if (!removeNotExistingOptions) {
|
|
324
|
+
newCollection.push(option);
|
|
328
325
|
}
|
|
329
326
|
});
|
|
327
|
+
|
|
328
|
+
if (addNotExistingOptions) {
|
|
329
|
+
this.collection = [
|
|
330
|
+
...newCollection,
|
|
331
|
+
...withOptions.filter(
|
|
332
|
+
(option) => !this.collection.some((opt) => opt.code === option.code),
|
|
333
|
+
),
|
|
334
|
+
];
|
|
335
|
+
} else {
|
|
336
|
+
this.collection = newCollection;
|
|
337
|
+
}
|
|
330
338
|
}
|
|
331
339
|
|
|
332
340
|
/**
|
|
@@ -15,6 +15,7 @@ import type {
|
|
|
15
15
|
import type { ModularUIResponse } from "../../modularui";
|
|
16
16
|
import type Href from "../href/Href";
|
|
17
17
|
import type LinkModel from "../links/LinkModel";
|
|
18
|
+
import type LinkCollection from "../links/LinkCollection";
|
|
18
19
|
import type ErrorResponse from "../error/ErrorResponse";
|
|
19
20
|
|
|
20
21
|
/**
|
|
@@ -109,6 +110,13 @@ export default class ConceptDetailModel extends ResourceModel {
|
|
|
109
110
|
return href;
|
|
110
111
|
}
|
|
111
112
|
|
|
113
|
+
/**
|
|
114
|
+
* Available diagrams for the concept, most of the time just one
|
|
115
|
+
*/
|
|
116
|
+
get diagramLinks(): LinkCollection {
|
|
117
|
+
return this.links.getLinksByGroup("diagram");
|
|
118
|
+
}
|
|
119
|
+
|
|
112
120
|
/**
|
|
113
121
|
* Get conceptType of concept
|
|
114
122
|
*/
|
|
@@ -1013,6 +1013,27 @@ class FormModel extends ResourceModel {
|
|
|
1013
1013
|
return this;
|
|
1014
1014
|
}
|
|
1015
1015
|
|
|
1016
|
+
/**
|
|
1017
|
+
* Updates the current form object with new information about the object,
|
|
1018
|
+
* like for example a new dynamicschema. Used for autoupdate functionality that makes it possible
|
|
1019
|
+
* to update the options of a next missing attribute in a form-tree iq question
|
|
1020
|
+
*/
|
|
1021
|
+
updateCurrentFormObject(receivedForm: ModularUIModel) {
|
|
1022
|
+
if (receivedForm instanceof FormModel) {
|
|
1023
|
+
const receivedFormData = receivedForm.data ?? {};
|
|
1024
|
+
const hasMissing = has(receivedFormData, "missing");
|
|
1025
|
+
const hasErrors = has(receivedFormData, "errors");
|
|
1026
|
+
|
|
1027
|
+
if (hasErrors) {
|
|
1028
|
+
this.handleErrors(receivedForm);
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
if (hasMissing) {
|
|
1032
|
+
this.handleMissing(receivedForm);
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1016
1037
|
/**
|
|
1017
1038
|
*/
|
|
1018
1039
|
updateValidations(data: any): FormModel {
|
|
@@ -1125,11 +1146,10 @@ class FormModel extends ResourceModel {
|
|
|
1125
1146
|
}
|
|
1126
1147
|
|
|
1127
1148
|
this.currentFormObject.attributeCollection.map((attribute) => {
|
|
1128
|
-
|
|
1129
|
-
receivedForm.currentFormObject
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
attribute.addMissingError();
|
|
1149
|
+
const receivedAttribute =
|
|
1150
|
+
receivedForm.currentFormObject?.getAttributeByKey(attribute.key);
|
|
1151
|
+
if (receivedAttribute) {
|
|
1152
|
+
attribute.addMissingError(receivedAttribute);
|
|
1133
1153
|
} else {
|
|
1134
1154
|
attribute.removeMissingError();
|
|
1135
1155
|
}
|
|
@@ -218,7 +218,15 @@ export default class FormObjectModel extends BaseModel {
|
|
|
218
218
|
}
|
|
219
219
|
|
|
220
220
|
/**
|
|
221
|
-
* Indicates if object is dynamic.
|
|
221
|
+
* Indicates if object is dynamic.
|
|
222
|
+
*
|
|
223
|
+
* A subtle difference exists between objects for wizard style instrument dialogs and other objects.
|
|
224
|
+
* In the 'missing object' response, wizard style objects will include only the first attribute(s) to be answered,
|
|
225
|
+
* while other objects will include the complete set of attributes of that object.
|
|
226
|
+
*
|
|
227
|
+
* This difference is condensed in the term of 'dynamic objects': these objects start (in the 'missing object' response)
|
|
228
|
+
* with a very select set of attributes to be answered, and each successive 'missing elements' response will include next attributes to be answered.
|
|
229
|
+
* When an object is dynamic, the form contributions will mention a "dynamicObject": true property.
|
|
222
230
|
*/
|
|
223
231
|
get isDynamic(): boolean {
|
|
224
232
|
return this.getContribution("dynamicObject", false);
|
|
@@ -17,7 +17,10 @@ import type {
|
|
|
17
17
|
ResetModularUIAction,
|
|
18
18
|
UpdateStatusAction,
|
|
19
19
|
} from "./types";
|
|
20
|
-
import type {
|
|
20
|
+
import type {
|
|
21
|
+
RequestModularUIOptions,
|
|
22
|
+
UpdateHandler,
|
|
23
|
+
} from "../../utils/fetch/types";
|
|
21
24
|
|
|
22
25
|
/**
|
|
23
26
|
*/
|
|
@@ -88,22 +91,11 @@ export const updateStatus = (
|
|
|
88
91
|
const loadModelSuccessAction = (
|
|
89
92
|
key: string,
|
|
90
93
|
model: ModularUIModel,
|
|
91
|
-
|
|
94
|
+
updateHandler: UpdateHandler | void,
|
|
92
95
|
): UpdateModelAction | SetModelAction => {
|
|
93
|
-
if (
|
|
94
|
-
|
|
95
|
-
if (typeof modelToUpdate["update"] === "function") {
|
|
96
|
-
const clonedModel = modelToUpdate.clone();
|
|
97
|
-
clonedModel.update(model);
|
|
98
|
-
|
|
99
|
-
return updateModel(clonedModel);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
throw new Error(
|
|
103
|
-
`loadModel action: updateModel is set as option for ${key}, but the model is missing an update methode`,
|
|
104
|
-
);
|
|
96
|
+
if (updateHandler) {
|
|
97
|
+
return updateModel(updateHandler(model));
|
|
105
98
|
}
|
|
106
|
-
|
|
107
99
|
return setModel(key, model);
|
|
108
100
|
};
|
|
109
101
|
|
|
@@ -127,7 +119,7 @@ export const loadModel = (
|
|
|
127
119
|
/**
|
|
128
120
|
*/
|
|
129
121
|
successAction: (model) =>
|
|
130
|
-
loadModelSuccessAction(key, model, options?.
|
|
122
|
+
loadModelSuccessAction(key, model, options?.updateHandler),
|
|
131
123
|
/**
|
|
132
124
|
*/
|
|
133
125
|
errorAction: (error) => {
|
|
@@ -6,6 +6,7 @@ import { getSetting } from "../../constants/Settings";
|
|
|
6
6
|
import { validateFormObject } from "./FormValidations";
|
|
7
7
|
import { autosaveFormObject } from "./FormAutosave";
|
|
8
8
|
import { autosubmitFormObject } from "./FormAutosubmit";
|
|
9
|
+
import { autoupdateFormObject } from "./FormAutoupdate";
|
|
9
10
|
|
|
10
11
|
import type { Dispatch, ThunkAction, UpdateFormOptions } from "../types";
|
|
11
12
|
import type { AttributeType } from "../../models/types";
|
|
@@ -23,7 +24,8 @@ export const updateFormAttribute =
|
|
|
23
24
|
inputvalue: string,
|
|
24
25
|
options: UpdateFormOptions = {
|
|
25
26
|
autosubmit: false,
|
|
26
|
-
autosave: false,
|
|
27
|
+
autosave: false, // autosave commits the form in the background
|
|
28
|
+
autoupdate: false, // autoupdate does not commit and updates the form with for example a new dynamicschema (work-around for form-tree iq)
|
|
27
29
|
forceUpdate: false,
|
|
28
30
|
validate: true,
|
|
29
31
|
},
|
|
@@ -56,18 +58,41 @@ export const updateFormAttribute =
|
|
|
56
58
|
}
|
|
57
59
|
}
|
|
58
60
|
|
|
59
|
-
if (options.
|
|
60
|
-
|
|
61
|
+
if (options.autoupdate && newForm.isValid) {
|
|
62
|
+
const autoupdateAction = autoupdateFormObject(newForm, attribute);
|
|
63
|
+
if (autoupdateAction) {
|
|
64
|
+
return dispatch(autoupdateAction);
|
|
65
|
+
}
|
|
61
66
|
}
|
|
62
67
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
getSetting("USE_INSTANT_SERVER_VALIDATION")
|
|
67
|
-
) {
|
|
68
|
-
// server form validations happens async, don't wait for the form to return
|
|
69
|
-
dispatch(validateFormObject(newForm));
|
|
70
|
-
}
|
|
68
|
+
handleAutoSave(dispatch, newForm, options);
|
|
69
|
+
|
|
70
|
+
handleValidate(dispatch, newForm, options);
|
|
71
71
|
|
|
72
72
|
return dispatch(updateForm(newForm));
|
|
73
73
|
};
|
|
74
|
+
|
|
75
|
+
const handleAutoSave = (
|
|
76
|
+
dispatch: Dispatch,
|
|
77
|
+
newForm: FormModel,
|
|
78
|
+
options: UpdateFormOptions,
|
|
79
|
+
) => {
|
|
80
|
+
if (options.autosave && newForm.isValid && newForm.isChanged()) {
|
|
81
|
+
dispatch(autosaveFormObject(newForm));
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const handleValidate = (
|
|
86
|
+
dispatch: Dispatch,
|
|
87
|
+
newForm: FormModel,
|
|
88
|
+
options: UpdateFormOptions,
|
|
89
|
+
) => {
|
|
90
|
+
if (
|
|
91
|
+
options.validate &&
|
|
92
|
+
newForm.currentFormObject?.hasDynamicValidations &&
|
|
93
|
+
getSetting("USE_INSTANT_SERVER_VALIDATION")
|
|
94
|
+
) {
|
|
95
|
+
// server form validations happens async, don't wait for the form to return
|
|
96
|
+
dispatch(validateFormObject(newForm));
|
|
97
|
+
}
|
|
98
|
+
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// @flow
|
|
2
2
|
import { loadModularUI } from "../_modularui/ModularUIActions";
|
|
3
3
|
import { HTTP_METHODS } from "../../constants/Constants";
|
|
4
|
+
import FormModel from "../../models/form/FormModel";
|
|
4
5
|
|
|
5
|
-
import type { AttributeType } from "../../models/types";
|
|
6
|
-
import type FormModel from "../../models/form/FormModel";
|
|
6
|
+
import type { ModularUIModel, AttributeType } from "../../models/types";
|
|
7
7
|
import type { ThunkAction } from "../types";
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -28,7 +28,14 @@ export const autosubmitFormObject = (
|
|
|
28
28
|
return loadModularUI(form.connectKey, form.selfhref, {
|
|
29
29
|
method: HTTP_METHODS.POST,
|
|
30
30
|
data: form.formdata,
|
|
31
|
-
|
|
31
|
+
updateHandler: (newModel: ModularUIModel): ModularUIModel => {
|
|
32
|
+
if (newModel instanceof FormModel) {
|
|
33
|
+
const clonedModel: FormModel = form.clone();
|
|
34
|
+
clonedModel.update(newModel);
|
|
35
|
+
return clonedModel;
|
|
36
|
+
}
|
|
37
|
+
return newModel;
|
|
38
|
+
},
|
|
32
39
|
});
|
|
33
40
|
}
|
|
34
41
|
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import { loadModularUI } from "../_modularui/ModularUIActions";
|
|
3
|
+
import { HTTP_METHODS } from "../../constants/Constants";
|
|
4
|
+
|
|
5
|
+
import FormModel from "../../models/form/FormModel";
|
|
6
|
+
|
|
7
|
+
import type { AttributeType, ModularUIModel } from "../../models/types";
|
|
8
|
+
import type { ThunkAction } from "../types";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
*/
|
|
12
|
+
export const autoupdateFormObject = (
|
|
13
|
+
form: FormModel,
|
|
14
|
+
attribute: AttributeType,
|
|
15
|
+
): ?ThunkAction => {
|
|
16
|
+
// As long as we have form objects,
|
|
17
|
+
// and the current attribute is not found in the current form object, go back.
|
|
18
|
+
// When a form has a result, the current form object is null
|
|
19
|
+
while (
|
|
20
|
+
form.allObjects.length > 0 &&
|
|
21
|
+
(!form.currentFormObject ||
|
|
22
|
+
!form.currentFormObject.hasAttributeByKey(attribute.key))
|
|
23
|
+
) {
|
|
24
|
+
form.setPreviousObject();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (form.isChanged()) {
|
|
28
|
+
return loadModularUI(form.connectKey, form.selfhref, {
|
|
29
|
+
method: HTTP_METHODS.POST,
|
|
30
|
+
data: form.formdata,
|
|
31
|
+
updateHandler: (newModel: ModularUIModel): ModularUIModel => {
|
|
32
|
+
if (newModel instanceof FormModel) {
|
|
33
|
+
const clonedModel: FormModel = form.clone();
|
|
34
|
+
clonedModel.updateCurrentFormObject(newModel);
|
|
35
|
+
return clonedModel;
|
|
36
|
+
}
|
|
37
|
+
return newModel;
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return null;
|
|
43
|
+
};
|
|
@@ -24,6 +24,7 @@ type OwnProps = {
|
|
|
24
24
|
formLayout?: "vertical" | "horizontal" | "compact",
|
|
25
25
|
autosubmit?: boolean,
|
|
26
26
|
autosave?: boolean,
|
|
27
|
+
autoupdate?: boolean,
|
|
27
28
|
};
|
|
28
29
|
|
|
29
30
|
type DispatchProps = {
|
|
@@ -50,8 +51,9 @@ const mapDispatchToProps = (
|
|
|
50
51
|
attribute: AttributeType,
|
|
51
52
|
value: string,
|
|
52
53
|
options: UpdateFormOptions = {
|
|
53
|
-
autosubmit: ownProps.autosubmit
|
|
54
|
-
autosave: ownProps.autosave
|
|
54
|
+
autosubmit: ownProps.autosubmit ?? false,
|
|
55
|
+
autosave: ownProps.autosave ?? false,
|
|
56
|
+
autoupdate: ownProps.autoupdate ?? false,
|
|
55
57
|
},
|
|
56
58
|
) =>
|
|
57
59
|
dispatch(
|
package/src/redux/types.js
CHANGED
|
@@ -46,6 +46,7 @@ export type PreferenceValue =
|
|
|
46
46
|
export type UpdateFormOptions = {
|
|
47
47
|
autosubmit: boolean,
|
|
48
48
|
autosave: boolean,
|
|
49
|
+
autoupdate: boolean,
|
|
49
50
|
forceUpdate?: boolean,
|
|
50
51
|
/** Default true: Activate/deactivate the form object validate by an update */
|
|
51
52
|
validate?: boolean,
|