blob: 6ac6d753d44d19b6d23225c8173e51cce9a2b73b [file] [log] [blame]
AviZi280f8012017-06-09 02:39:56 +03001/*!
2 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
13 * or implied. See the License for the specific language governing
14 * permissions and limitations under the License.
15 */
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +020016import { actionTypes } from './JSONSchemaReducerConstants.js';
AviZi280f8012017-06-09 02:39:56 +030017import Validator from 'nfvo-utils/Validator.js';
18import JSONSchema from 'nfvo-utils/json/JSONSchema.js';
19import JSONPointer from 'nfvo-utils/json/JSONPointer.js';
20import forOwn from 'lodash/forOwn.js';
21import isArray from 'lodash/isArray.js';
22
AviZi280f8012017-06-09 02:39:56 +030023function flattenData(data, result, pointer = '') {
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +020024 let newPointer = pointer;
25 if (typeof data === 'object' && !isArray(data)) {
26 for (let i in data) {
27 newPointer = newPointer ? newPointer + '/' + i : i;
28 flattenData(data[i], result, newPointer);
29 newPointer = pointer;
30 }
31 } else {
32 result[newPointer] = data;
33 }
AviZi280f8012017-06-09 02:39:56 +030034}
35
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +020036function updateSchemaDataAndValidateReducer(
37 state = {},
38 action,
39 questionnaireName
40) {
41 let genericFieldInfoClone;
42 switch (action.type) {
43 case actionTypes.DATA_LOADED:
44 if (questionnaireName !== action.qName) {
45 return { ...state };
46 }
47 const schema = action.payload.qschema;
48 let schemaLoader = new JSONSchema();
49 schemaLoader.setSchema(schema);
50 schemaLoader.setSupportedValidationFunctions(
51 Object.keys(Validator.globalValidationFunctions)
52 );
53 let { genericFieldInfo } = schemaLoader.flattenSchema();
AviZi280f8012017-06-09 02:39:56 +030054
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +020055 let data = action.payload.qdata;
56 let dataMap = {};
57 flattenData(data, dataMap);
AviZi280f8012017-06-09 02:39:56 +030058
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +020059 return {
60 ...state,
61 qdata: action.payload.qdata, // the original hierarchical data. to be used for submit and save
62 qgenericFieldInfo: genericFieldInfo, // information about the fields that the view will require and reducer will need, such as validations, enum to use, etc.
63 dataMap // flattened schema data for ease of use
64 };
AviZi280f8012017-06-09 02:39:56 +030065
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +020066 case actionTypes.DATA_CHANGED:
67 let changedData = action.deltaData;
68 if (questionnaireName !== action.qName) {
69 return { ...state };
70 }
AviZi280f8012017-06-09 02:39:56 +030071
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +020072 genericFieldInfoClone = { ...state.qgenericFieldInfo };
73 let qDataClone = { ...state.qdata };
74 let dataMapClone = { ...state.dataMap };
AviZi280f8012017-06-09 02:39:56 +030075
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +020076 forOwn(changedData, (value, key) => {
77 if (state.qgenericFieldInfo[key]) {
78 let result = Validator.validate(
79 key,
80 value,
81 state.qgenericFieldInfo[key].validations,
82 state,
83 action.customValidations
84 );
85 genericFieldInfoClone[key] = {
86 ...genericFieldInfoClone[key],
87 isValid: result.isValid,
88 errorText: result.errorText
89 };
90 qDataClone = JSONPointer.setValue(
91 state.qdata,
92 '/' + key,
93 value
94 );
95 dataMapClone[key] = value;
96 }
97 });
AviZi280f8012017-06-09 02:39:56 +030098
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +020099 return {
100 ...state,
101 qdata: qDataClone,
102 dataMap: dataMapClone,
103 qgenericFieldInfo: genericFieldInfoClone
104 };
AviZi280f8012017-06-09 02:39:56 +0300105
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200106 case actionTypes.VALIDATE_DATA:
107 let specificFields = action.data;
108 if (questionnaireName !== action.qName) {
109 return { ...state };
110 }
111 genericFieldInfoClone = { ...state.qgenericFieldInfo };
112 forOwn(specificFields, (value, key) => {
113 let result = Validator.validate(
114 key,
115 value,
116 state.qgenericFieldInfo[key].validations,
117 state,
118 action.customValidations
119 );
120 genericFieldInfoClone[key] = {
121 ...genericFieldInfoClone[key],
122 isValid: result.isValid,
123 errorText: result.errorText
124 };
125 });
126 return {
127 ...state,
128 formReady: null,
129 qgenericFieldInfo: genericFieldInfoClone
130 };
AviZi280f8012017-06-09 02:39:56 +0300131
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200132 case actionTypes.VALIDATE_FORM:
133 if (questionnaireName !== action.qName) {
134 return { ...state };
135 }
136 genericFieldInfoClone = { ...state.qgenericFieldInfo };
137 let formReady = true;
138 forOwn(state.qgenericFieldInfo, (value, key) => {
139 let val = state.dataMap[key] ? state.dataMap[key] : '';
140 let result = Validator.validate(
141 key,
142 val,
143 state.qgenericFieldInfo[key].validations,
144 state,
145 action.customValidations
146 );
147 genericFieldInfoClone[key] = {
148 ...genericFieldInfoClone[key],
149 isValid: result.isValid,
150 errorText: result.errorText
151 };
152 if (!result.isValid) {
153 formReady = false;
154 }
155 });
156 return {
157 ...state,
158 formReady,
159 qgenericFieldInfo: genericFieldInfoClone
160 };
AviZi280f8012017-06-09 02:39:56 +0300161
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200162 default:
163 return state;
164 }
165}
AviZi280f8012017-06-09 02:39:56 +0300166
167export function createJSONSchemaReducer(questionnaireName) {
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200168 return (state = {}, action) => {
169 return updateSchemaDataAndValidateReducer(
170 state,
171 action,
172 questionnaireName
173 );
174 };
175}
AviZi280f8012017-06-09 02:39:56 +0300176
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200177export function createComposedJSONSchemaReducer(
178 questionnaireName,
179 additionalActionsReducer
180) {
181 return (state = {}, action) => {
182 if (
183 action.type === actionTypes.VALIDATE_DATA ||
184 action.type === actionTypes.VALIDATE_FORM ||
185 action.type === actionTypes.DATA_CHANGED ||
186 action.type === actionTypes.DATA_LOADED
187 ) {
188 return updateSchemaDataAndValidateReducer(
189 state,
190 action,
191 questionnaireName
192 );
193 } else {
194 return additionalActionsReducer(state, action);
195 }
196 };
197}