Including build.sh to run gulp-webpack
[aai/sparky-fe.git] / src / generic-components / filterBar / FilterBarUtils.js
1 /*
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
4  * ================================================================================
5  * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
6  * Copyright © 2017 Amdocs
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *       http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  *
21  * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22  */
23 import isEmpty from 'lodash/isEmpty';
24 import moment from 'moment-timezone';
25 import {
26   POST,
27   POST_HEADER
28 } from 'app/networking/NetworkConstants.js';
29 import {
30   UNIFIED_FILTERS_URL,
31   DISCOVER_FILTERS_ERROR_MSG,
32   DATE_TIME_ZONE,
33   FILTER_ATTRIBUTE_TO,
34   FILTER_ATTRIBUTE_FROM,
35   FILTER_ATTRIBUTE_CODE,
36   FILTER_ATTRIBUTE_VALUES,
37   FILTER_ATTRIBUTE_CONTROLS,
38   FILTER_ATTRIBUTE_DEFAULT_VALUE,
39   FILTER_TYPE_ENUM,
40   filterBarActionTypes
41 } from 'generic-components/filterBar/FilterBarConstants.js';
42 import {
43   MESSAGE_LEVEL_WARNING
44 } from 'utils/GlobalConstants.js';
45 import {
46   getSetGlobalMessageEvent
47 } from 'app/globalInlineMessageBar/GlobalInlineMessageBarActions.js';
48
49 export function buildFilterValueMap(filterValueString) {
50   let filterValueObj = {};
51   let filters = filterValueString.split(',');
52
53   for (let filterIndex in filters) {
54     let filterStringParts = filters[filterIndex].split('=');
55
56     filterValueObj[filterStringParts[0]] = filterStringParts[1];
57   }
58
59   return filterValueObj;
60 }
61
62 export function buildFilterValueMapFromObj(filterValues) {
63   let filterValueObj = {};
64
65   for (let filterIndex in filterValues) {
66     filterValueObj[filterValues[filterIndex].filterId] = filterValues[filterIndex].filterValue;
67   }
68
69   return filterValueObj;
70 }
71
72 export function getFilterListQueryString(filterValueList) {
73   let filterQueryList = [];
74
75   for (let filter in filterValueList) {
76     if (filterValueList[filter]) {
77       filterQueryList.push(
78         {
79           'filterId': filter,
80           'filterValue': filterValueList[filter]
81         }
82       );
83     }
84   }
85
86   return filterQueryList;
87 }
88
89 function getFilterSearchURL() {
90   return UNIFIED_FILTERS_URL.replace('@@IP-ADDRESS@@', document.location.hostname);
91 }
92
93 function getFiltersQueryObject(viewName) {
94   return {
95     'viewName': viewName
96   };
97 }
98
99 function getFiltersEvent(actionType, filterList) {
100   return {
101     type: actionType,
102     data: filterList
103   };
104 }
105
106 export function getUnifiedFilters(viewName, actionType) {
107   return dispatch => {
108     return fetch(getFilterSearchURL(), {
109       credentials: 'same-origin',
110       method: POST,
111       headers: POST_HEADER,
112       body: JSON.stringify(getFiltersQueryObject(viewName))
113     }).then(
114       (response) => response.json()
115     ).then(
116       (responseJson) => {
117         dispatch(
118           getFiltersEvent(actionType, responseJson.filters)
119         );
120       }
121     ).catch(
122       () => {
123         dispatch(getSetGlobalMessageEvent(DISCOVER_FILTERS_ERROR_MSG, MESSAGE_LEVEL_WARNING));
124       }
125     );
126   };
127 }
128
129 function extractConvertedDateValues(dateValues) {
130   let convertedValues = {};
131   if (dateValues.from) {
132     let startMoment = moment(dateValues.from);
133     convertedValues.startDate = startMoment.toDate();
134     convertedValues.time_zone = startMoment.format(DATE_TIME_ZONE);
135   }
136
137   if (dateValues.to) {
138     let endMoment = moment(dateValues.to);
139     convertedValues.endDate = endMoment.toDate();
140     convertedValues.time_zone = endMoment.format(DATE_TIME_ZONE);
141   }
142
143   convertedValues.code = dateValues.code;
144
145   return convertedValues;
146 }
147
148 function convertFilterValues(filterValues) {
149   let convertedFilterValues = {};
150
151   for (let filterId in filterValues) {
152     if (filterValues.hasOwnProperty(filterId) &&
153       !isEmpty(filterValues[filterId]) && !isEmpty(filterValues[filterId].controls)) {
154       let controls = filterValues[filterId].controls;
155       let firstControlKey = Object.keys(controls)[0];
156       if (controls[firstControlKey][FILTER_ATTRIBUTE_VALUES][FILTER_ATTRIBUTE_FROM] ||
157         controls[firstControlKey][FILTER_ATTRIBUTE_VALUES][FILTER_ATTRIBUTE_TO]) {
158         // TODO should check against filter type (ex: dropdown or date)
159         // rather than assuming value attributes (ex: 'to' or 'from')
160         convertedFilterValues[filterId] =
161           extractConvertedDateValues(controls[firstControlKey][FILTER_ATTRIBUTE_VALUES]);
162       } else {
163         let codeValue = controls[firstControlKey][FILTER_ATTRIBUTE_VALUES][FILTER_ATTRIBUTE_CODE];
164         convertedFilterValues[filterId] = codeValue;
165       }
166     }
167   }
168
169   return convertedFilterValues;
170 }
171
172 function combineMissingFilters(filterValues, allFilters) {
173   let allFilterIds = Object.keys(allFilters);
174
175   for (let id in allFilterIds) {
176     if (!filterValues.hasOwnProperty(allFilterIds[id])) {
177       filterValues[allFilterIds[id]] = '';
178     }
179   }
180
181   return filterValues;
182 }
183
184 function getFilterSelectionEvent(selectedValuesMap, convertedValues) {
185   return {
186     type: filterBarActionTypes.NEW_SELECTIONS,
187     data: {
188       selectedValuesMap: convertedValues,
189       unifiedValues: selectedValuesMap
190     }
191   };
192 }
193
194 export function processFilterSelection(filterValues, allFilters) {
195   let convertedFilterValues = convertFilterValues(filterValues);
196   let combinedFilterValues = combineMissingFilters(convertedFilterValues, allFilters);
197
198   // dispatch NEW_SELECTION event type with converted values as the data
199   return getFilterSelectionEvent(filterValues, combinedFilterValues);
200 }
201
202 export function setNonConvertedFilterValues(nonConvertedValues) {
203   return {
204     type: filterBarActionTypes.SET_NON_CONVERTED_VALUES,
205     data: nonConvertedValues
206   };
207 }
208
209 function convertedFilterValuesEvent(nonConvertedValues, convertedValues) {
210   return {
211     type: filterBarActionTypes.SET_CONVERTED_VALUES,
212     data: {
213       nonConvertedValues: nonConvertedValues,
214       convertedValues: convertedValues
215     }
216   };
217 }
218
219 function mapValuesToOption(filterOptions, nonConvertedValue) {
220   let mappedValues = {};
221
222   // loop over options to find match for value
223   for (let i in filterOptions) {
224     if (filterOptions[i].code === nonConvertedValue) {
225       // found the matching
226       mappedValues = filterOptions[i];
227       break;
228     }
229   }
230
231   return mappedValues;
232 }
233
234 function mapValuesToDateOption(nonConvertedValue) {
235   let mappedValues = {};
236
237   if (nonConvertedValue.startDate) {
238     mappedValues.from = new Date(nonConvertedValue.startDate);
239   } else {
240     mappedValues.from = null;
241   }
242
243   if (nonConvertedValue.endDate) {
244     mappedValues.to = new Date(nonConvertedValue.endDate);
245   } else {
246     mappedValues.to = null;
247   }
248
249   mappedValues.code = nonConvertedValue.code;
250
251   return mappedValues;
252 }
253
254 function mapValuesToFilter(nonConvertedValues, allFilters, currentlySetFilterValues) {
255   let convertedValues = {};
256
257   for (let nonConvertedId in nonConvertedValues) {
258     if (nonConvertedValues[nonConvertedId] !== '') {
259       let matchingFilterObj = allFilters[nonConvertedId];
260       let filterControlId = Object.keys(matchingFilterObj.controls)[0];
261       let mappedValue = {};
262
263       if (matchingFilterObj[FILTER_ATTRIBUTE_CONTROLS][filterControlId].type === FILTER_TYPE_ENUM.DATE) {
264         mappedValue = mapValuesToDateOption(nonConvertedValues[nonConvertedId]);
265       } else {
266         mappedValue = mapValuesToOption(matchingFilterObj[FILTER_ATTRIBUTE_CONTROLS][filterControlId].options,
267           nonConvertedValues[nonConvertedId]);
268       }
269
270       let values = {};
271       values[FILTER_ATTRIBUTE_VALUES] = mappedValue;
272       let filterControlers = {};
273       filterControlers[filterControlId] = values;
274       let filter = {};
275       filter[FILTER_ATTRIBUTE_CONTROLS] = filterControlers;
276       convertedValues[nonConvertedId] = filter;
277     } else if (!isEmpty(currentlySetFilterValues[nonConvertedId])) {
278       // currently a value is set for this filter, need to ensure we map this filter
279       // to an empty value so that it is cleared/reset
280       let matchingFilterObj = allFilters[nonConvertedId];
281       let filterControlId = Object.keys(matchingFilterObj.controls)[0];
282       let mappedValue = {};
283       let values = {};
284       values[FILTER_ATTRIBUTE_VALUES] = mappedValue;
285       let filterControlers = {};
286       filterControlers[filterControlId] = values;
287       let filter = {};
288       filter[FILTER_ATTRIBUTE_CONTROLS] = filterControlers;
289       convertedValues[nonConvertedId] = filter;
290     }
291   }
292
293   return convertedValues;
294 }
295
296 export function convertNonConvertedValues(nonConvertedValues, allFilters, currentlySetFilterValues) {
297   let convertedValues = mapValuesToFilter(nonConvertedValues, allFilters, currentlySetFilterValues);
298   return convertedFilterValuesEvent(nonConvertedValues, convertedValues);
299 }
300
301 export function clearFilters() {
302   return {
303     type: filterBarActionTypes.CLEAR_FILTERS
304   };
305 }
306
307 function getSetUnifiedFilterValuesEvent(unifiedValues) {
308   return {
309     type: filterBarActionTypes.SET_UNIFIED_VALUES,
310     data: unifiedValues
311   };
312 }
313
314 function getFilterDefault(filters, filterId) {
315   let filterControlId = Object.keys(filters[filterId][FILTER_ATTRIBUTE_CONTROLS])[0];
316   let defaultValue = filters[filterId][FILTER_ATTRIBUTE_CONTROLS][filterControlId][FILTER_ATTRIBUTE_DEFAULT_VALUE];
317   if (!defaultValue) {
318     defaultValue = {};
319   }
320   return defaultValue;
321 }
322
323 export function setFilterSelectionsToDefaults(filters, filterValues) {
324   let defaultFilterMap = {};
325
326   for (let filterId in filters) {
327     let filterDefaultValue = getFilterDefault(filters, filterId);
328     if (!isEmpty(filterDefaultValue) || (filterValues && filterValues[filterId])) {
329       let filterControlId = Object.keys(filters[filterId][FILTER_ATTRIBUTE_CONTROLS])[0];
330       let controller = {};
331       controller.values = filterDefaultValue;
332       let controllers = {};
333       controllers[filterControlId] = controller;
334       let controls = {};
335       controls.controls = controllers;
336       defaultFilterMap[filterId] = controls;
337     }
338   }
339
340   if (isEmpty(defaultFilterMap)) {
341     // there are no default values, so need to ensure all filters get cleared,
342     // but just incase this 'clearing'
343     let combinedValues = combineMissingFilters(defaultFilterMap, filters);
344     return setNonConvertedFilterValues(combinedValues);
345   } else {
346     // jsut set the Unified Filter Value which will be sent down to the filter (filter
347     // will set itself to the default value and then send notification back up of the selection
348     return getSetUnifiedFilterValuesEvent(defaultFilterMap);
349   }
350 }