5c82c70830dc273725b341e8a50e1fe9fbd9e4f2
[sdc.git] / openecomp-ui / src / sdc-app / onboarding / softwareProduct / SoftwareProductActionHelper.js
1 /*!
2  * Copyright © 2016-2018 European Support Limited
3  * Modifications copyright (c) 2021 Nokia
4  * Modifications Copyright (C) 2021 Nordix Foundation.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
15  * or implied. See the License for the specific language governing
16  * permissions and limitations under the License.
17  */
18 import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
19 import showFileSaveDialog from 'nfvo-utils/ShowFileSaveDialog.js';
20 import Configuration from 'sdc-app/config/Configuration.js';
21 import i18n from 'nfvo-utils/i18n/i18n.js';
22 import LicenseModelActionHelper from 'sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js';
23 import LicenseAgreementActionHelper from 'sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementActionHelper.js';
24 import FeatureGroupsActionHelper from 'sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsActionHelper.js';
25
26 import {
27     actionTypes,
28     onboardingOriginTypes,
29     PRODUCT_QUESTIONNAIRE,
30     forms
31 } from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js';
32 import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js';
33 import SoftwareProductComponentsActionHelper from './components/SoftwareProductComponentsActionHelper.js';
34 import { actionsEnum as VersionControllerActionsEnum } from 'nfvo-components/panel/versionController/VersionControllerConstants.js';
35 import { actionTypes as HeatSetupActions } from 'sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupConstants.js';
36 import { actionTypes as featureGroupsActionConstants } from 'sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsConstants.js';
37 import { actionTypes as licenseAgreementActionTypes } from 'sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementConstants.js';
38 import { actionTypes as componentActionTypes } from './components/SoftwareProductComponentsConstants.js';
39 import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
40 import { actionTypes as modalActionTypes } from 'nfvo-components/modal/GlobalModalConstants.js';
41 import { modalContentMapper } from 'sdc-app/common/modal/ModalContentMapper.js';
42 import { default as ItemsHelper } from 'sdc-app/common/helpers/ItemsHelper.js';
43 import ScreensHelper from 'sdc-app/common/helpers/ScreensHelper.js';
44 import { enums, screenTypes } from 'sdc-app/onboarding/OnboardingConstants.js';
45 import MergeEditorActionHelper from 'sdc-app/common/merge/MergeEditorActionHelper.js';
46 import { CommitModalType } from 'nfvo-components/panel/versionController/components/CommitCommentModal.jsx';
47 import { actionTypes as commonActionTypes } from 'sdc-app/common/reducers/PlainDataReducerConstants.js';
48 import versionPageActionHelper from 'sdc-app/onboarding/versionsPage/VersionsPageActionHelper.js';
49 import { itemTypes } from 'sdc-app/onboarding/versionsPage/VersionsPageConstants.js';
50 import getValue from 'nfvo-utils/getValue.js';
51 import {
52     itemStatus,
53     versionStatus
54 } from 'sdc-app/common/helpers/ItemsHelperConstants.js';
55
56 let shouldDisplayTimingValidationInfo = true;
57 let alertValidationTiming = Configuration.get(
58     'displayAlertValidationAfterMilisec'
59 );
60
61 function getLicensingData(licensingData = {}) {
62     const { licenseAgreement, featureGroups } = licensingData;
63     const newlicenseAgreement = getValue(licenseAgreement);
64     const newfeatureGroups = getValue(featureGroups);
65     return newlicenseAgreement
66         ? {
67               licenseAgreement: newlicenseAgreement,
68               featureGroups: newfeatureGroups
69           }
70         : undefined;
71 }
72
73 function getTimingInfoWarning() {
74     return {
75         type: modalActionTypes.GLOBAL_MODAL_WARNING,
76         data: {
77             title: 'Please be patient',
78             msg: 'Large files processing may take up to several minutes.',
79             cancelButtonText: 'OK'
80         }
81     };
82 }
83
84 function displayTimingValidationInfo(dispatch) {
85     shouldDisplayTimingValidationInfo = true;
86     setTimeout(() => {
87         if (shouldDisplayTimingValidationInfo) {
88             dispatch(getTimingInfoWarning());
89         }
90     }, alertValidationTiming);
91 }
92
93 function closeTimingValidationInfo(dispatch) {
94     shouldDisplayTimingValidationInfo = false;
95     dispatch({
96         type: modalActionTypes.GLOBAL_MODAL_CLOSE
97     });
98 }
99
100 function baseUrl() {
101     const restPrefix = Configuration.get('restPrefix');
102     return `${restPrefix}/v1.0/vendor-software-products/`;
103 }
104
105 function softwareProductCategoriesUrl() {
106     const restCatalogPrefix = Configuration.get('restCatalogPrefix');
107     return `${restCatalogPrefix}/v1/categories/resources/`;
108 }
109
110 function getModelUrl() {
111     const restCatalogPrefix = Configuration.get('restCatalogPrefix');
112     return `${restCatalogPrefix}/v1/catalog/model?modelType=normative`;
113 }
114
115 function uploadFile(vspId, formData, version) {
116     return RestAPIUtil.post(
117         `${baseUrl()}${vspId}/versions/${
118             version.id
119         }/orchestration-template-candidate`,
120         formData
121     );
122 }
123
124 function uploadVNFFile(csarId, softwareProductId, version) {
125     let verId = typeof version === 'object' ? version.id : version;
126     return RestAPIUtil.post(
127         `${baseUrl()}${softwareProductId}/versions/${verId}/vnfrepository/vnfpackage/${csarId}/import`
128     );
129 }
130 function putSoftwareProduct({ softwareProduct, version }) {
131     return RestAPIUtil.put(
132         `${baseUrl()}${softwareProduct.id}/versions/${version.id}`,
133         {
134             name: softwareProduct.name,
135             description: softwareProduct.description,
136             category: softwareProduct.category,
137             subCategory: softwareProduct.subCategory,
138             vendorId: softwareProduct.vendorId,
139             vendorName: softwareProduct.vendorName,
140             licensingVersion: softwareProduct.licensingVersion
141                 ? softwareProduct.licensingVersion
142                 : undefined,
143             icon: softwareProduct.icon,
144             licenseType: softwareProduct.licenseType,
145             selectedModelList: softwareProduct.selectedModelList,
146             licensingData: getLicensingData(softwareProduct.licensingData)
147         }
148     );
149 }
150
151 function putSoftwareProductQuestionnaire(vspId, qdata, version) {
152     return RestAPIUtil.put(
153         `${baseUrl()}${vspId}/versions/${version.id}/questionnaire`,
154         qdata
155     );
156 }
157
158 function putSoftwareProductAction(id, action, version) {
159     return RestAPIUtil.put(`${baseUrl()}${id}/versions/${version.id}/actions`, {
160         action: action
161     });
162 }
163
164 function fetchSoftwareProductList() {
165     return RestAPIUtil.fetch(
166         `${baseUrl()}?versionFilter=${versionStatus.DRAFT}`
167     );
168 }
169
170 function fetchArchivedSoftwareProductList() {
171     return RestAPIUtil.fetch(`${baseUrl()}?Status=${itemStatus.ARCHIVED}`);
172 }
173
174 function fetchFinalizedSoftwareProductList() {
175     return RestAPIUtil.fetch(
176         `${baseUrl()}?versionFilter=${versionStatus.CERTIFIED}`
177     );
178 }
179
180 function fetchSoftwareProduct(vspId, version) {
181     return RestAPIUtil.fetch(`${baseUrl()}${vspId}/versions/${version.id}`);
182 }
183
184 function fetchSoftwareProductQuestionnaire(vspId, version) {
185     return RestAPIUtil.fetch(
186         `${baseUrl()}${vspId}/versions/${version.id}/questionnaire`
187     );
188 }
189
190 function updateSoftwareProductHeatCandidate(
191     softwareProductId,
192     heatCandidate,
193     version
194 ) {
195     return RestAPIUtil.put(
196         `${baseUrl()}${softwareProductId}/versions/${
197             version.id
198         }/orchestration-template-candidate/manifest`,
199         heatCandidate
200     );
201 }
202 function validateHeatCandidate(softwareProductId, version) {
203     return RestAPIUtil.put(
204         `${baseUrl()}${softwareProductId}/versions/${
205             version.id
206         }/orchestration-template-candidate/process`
207     );
208 }
209
210 function fetchOrchestrationTemplateCandidate(softwareProductId, version) {
211     return RestAPIUtil.fetch(
212         `${baseUrl()}${softwareProductId}/versions/${
213             version.id
214         }/orchestration-template-candidate`,
215         { dataType: 'binary' }
216     );
217 }
218
219 function abortValidationProcess(softwareProductId, version) {
220     return RestAPIUtil.destroy(
221         `${baseUrl()}${softwareProductId}/versions/${
222             version.id
223         }/orchestration-template-candidate`
224     );
225 }
226
227 function objToString(obj) {
228     let str = '';
229     if (obj instanceof Array) {
230         obj.forEach(item => {
231             str += objToString(item) + '\n';
232         });
233     } else {
234         for (let p in obj) {
235             if (obj.hasOwnProperty(p)) {
236                 str += obj[p] + '\n';
237             }
238         }
239     }
240     return str.replace(/\n$/, '');
241 }
242
243 function parseUploadErrorMsg(error) {
244     let message = '';
245     for (let key in error) {
246         if (error.hasOwnProperty(key)) {
247             message += objToString(error[key]) + '\n';
248         }
249     }
250     return message.replace(/\n$/, '');
251 }
252
253 function showWarningValidationInfo(dispatch, errors) {
254     dispatch({
255         type: modalActionTypes.GLOBAL_MODAL_WARNING,
256         data: {
257             title: 'Validation messages',
258             msg: parseUploadErrorMsg(errors),
259             cancelButtonText: 'OK'
260         }
261     });
262 }
263
264 function fetchSoftwareProductCategories(dispatch) {
265     let handleResponse = response =>
266         dispatch({
267             type: actionTypes.SOFTWARE_PRODUCT_CATEGORIES_LOADED,
268             softwareProductCategories: response
269         });
270     return RestAPIUtil.fetch(softwareProductCategoriesUrl())
271         .then(handleResponse)
272         .catch(() => handleResponse(null));
273 }
274
275 function fetchModelList(dispatch) {
276     let handleResponse = response =>
277         dispatch({
278             type: actionTypes.SOFTWARE_PRODUCT_MODELS_LOADED,
279             modelList: response
280         });
281     RestAPIUtil.fetch(getModelUrl())
282         .then(handleResponse)
283         .catch(() => handleResponse(null));
284 }
285
286 function loadLicensingData(dispatch, { licenseModelId, licensingVersion }) {
287     return ItemsHelper.fetchVersion({
288         itemId: licenseModelId,
289         versionId: licensingVersion
290     }).then(() => {
291         return Promise.all([
292             LicenseAgreementActionHelper.fetchLicenseAgreementList(dispatch, {
293                 licenseModelId,
294                 version: { id: licensingVersion }
295             }),
296             FeatureGroupsActionHelper.fetchFeatureGroupsList(dispatch, {
297                 licenseModelId,
298                 version: { id: licensingVersion }
299             })
300         ]);
301     });
302 }
303
304 function getExpandedItemsId(items, itemIdToToggle) {
305     for (let i = 0; i < items.length; i++) {
306         if (items[i].id === itemIdToToggle) {
307             if (items[i].expanded) {
308                 return {};
309             } else {
310                 return { [itemIdToToggle]: true };
311             }
312         } else if (items[i].items && items[i].items.length > 0) {
313             let mapOfExpandedIds = getExpandedItemsId(
314                 items[i].items,
315                 itemIdToToggle
316             );
317             if (mapOfExpandedIds !== false) {
318                 mapOfExpandedIds[items[i].id] = true;
319                 return mapOfExpandedIds;
320             }
321         }
322     }
323     return false;
324 }
325
326 function migrateSoftwareProduct(vspId, version) {
327     return RestAPIUtil.put(`${baseUrl()}${vspId}/versions/${version.id}/heal`);
328 }
329
330 const SoftwareProductActionHelper = {
331     fetchFinalizedSoftwareProductList(dispatch) {
332         return fetchFinalizedSoftwareProductList().then(response =>
333             dispatch({
334                 type: actionTypes.FINALIZED_SOFTWARE_PRODUCT_LIST_LOADED,
335                 response
336             })
337         );
338     },
339
340     fetchArchivedSoftwareProductList(dispatch) {
341         return fetchArchivedSoftwareProductList().then(response =>
342             dispatch({
343                 type: actionTypes.ARCHIVED_SOFTWARE_PRODUCT_LIST_LOADED,
344                 response
345             })
346         );
347     },
348
349     loadSoftwareProductAssociatedData(dispatch) {
350         fetchSoftwareProductCategories(dispatch);
351         fetchModelList(dispatch);
352         LicenseModelActionHelper.fetchFinalizedLicenseModels(dispatch);
353     },
354
355     loadSoftwareProductDetailsData(
356         dispatch,
357         { licenseModelId, licensingVersion }
358     ) {
359         SoftwareProductActionHelper.loadSoftwareProductAssociatedData(dispatch);
360         if (licensingVersion) {
361             return loadLicensingData(dispatch, {
362                 licenseModelId,
363                 licensingVersion
364             });
365         }
366         return Promise.resolve();
367     },
368
369     fetchSoftwareProductList(dispatch) {
370         return fetchSoftwareProductList().then(response =>
371             dispatch({
372                 type: actionTypes.SOFTWARE_PRODUCT_LIST_LOADED,
373                 response
374             })
375         );
376     },
377
378     loadSoftwareProductHeatCandidate(dispatch, { softwareProductId, version }) {
379         return RestAPIUtil.fetch(
380             `${baseUrl()}${softwareProductId}/versions/${
381                 version.id
382             }/orchestration-template-candidate/manifest`
383         ).then(response =>
384             dispatch({
385                 type: HeatSetupActions.MANIFEST_LOADED,
386                 response
387             })
388         );
389     },
390
391     loadLicensingVersionsList(dispatch, { licenseModelId }) {
392         return ItemsHelper.fetchVersions({ itemId: licenseModelId }).then(
393             response => {
394                 dispatch({
395                     type: actionTypes.LOAD_LICENSING_VERSIONS_LIST,
396                     licensingVersionsList: response.results
397                 });
398             }
399         );
400     },
401     updateSoftwareProductHeatCandidate(
402         dispatch,
403         { softwareProductId, heatCandidate, version }
404     ) {
405         return updateSoftwareProductHeatCandidate(
406             softwareProductId,
407             heatCandidate,
408             version
409         );
410     },
411
412     processAndValidateHeatCandidate(dispatch, { softwareProductId, version }) {
413         displayTimingValidationInfo(dispatch);
414         return validateHeatCandidate(softwareProductId, version).then(
415             response => {
416                 if (response.status === 'Success') {
417                     SoftwareProductComponentsActionHelper.fetchSoftwareProductComponents(
418                         dispatch,
419                         { softwareProductId, version }
420                     );
421                     SoftwareProductActionHelper.fetchSoftwareProduct(dispatch, {
422                         softwareProductId,
423                         version
424                     });
425                 } else {
426                     SoftwareProductActionHelper.fetchSoftwareProduct(dispatch, {
427                         softwareProductId,
428                         version
429                     });
430                 }
431                 closeTimingValidationInfo(dispatch);
432             }
433         );
434     },
435
436     uploadFile(
437         dispatch,
438         { softwareProductId, formData, failedNotificationTitle, version }
439     ) {
440         dispatch({
441             type: HeatSetupActions.FILL_HEAT_SETUP_CACHE,
442             payload: {}
443         });
444         displayTimingValidationInfo(dispatch);
445         Promise.resolve()
446             .then(() => uploadFile(softwareProductId, formData, version))
447             .then(response => {
448                 if (response.status === 'Success') {
449                     dispatch({
450                         type: commonActionTypes.DATA_CHANGED,
451                         deltaData: {
452                             onboardingOrigin: response.onboardingOrigin
453                         },
454                         formName: forms.VENDOR_SOFTWARE_PRODUCT_DETAILS
455                     });
456                     switch (response.onboardingOrigin) {
457                         case onboardingOriginTypes.ZIP:
458                             ScreensHelper.loadScreen(dispatch, {
459                                 screen:
460                                     enums.SCREEN
461                                         .SOFTWARE_PRODUCT_ATTACHMENTS_SETUP,
462                                 screenType: screenTypes.SOFTWARE_PRODUCT,
463                                 props: { softwareProductId, version }
464                             });
465                             dispatch({
466                                 type: actionTypes.CANDIDATE_IN_PROCESS,
467                                 inProcess: true
468                             });
469                             break;
470                         case onboardingOriginTypes.CSAR:
471                             ScreensHelper.loadScreen(dispatch, {
472                                 screen:
473                                     enums.SCREEN
474                                         .SOFTWARE_PRODUCT_ATTACHMENTS_VALIDATION,
475                                 screenType: screenTypes.SOFTWARE_PRODUCT,
476                                 props: { softwareProductId, version }
477                             });
478                             break;
479                     }
480                     closeTimingValidationInfo(dispatch);
481                     if (
482                         response.errors !== null &&
483                         Object.keys(response.errors).length !== 0
484                     ) {
485                         showWarningValidationInfo(dispatch, response.errors);
486                     }
487                 } else {
488                     throw new Error(parseUploadErrorMsg(response.errors));
489                 }
490             })
491             .catch(error => {
492                 dispatch(
493                     {
494                         type: modalActionTypes.GLOBAL_MODAL_ERROR,
495                         data: {
496                             title: failedNotificationTitle,
497                             msg:
498                                 error.message ||
499                                 (error.responseJSON &&
500                                     error.responseJSON.message) ||
501                                 parseUploadErrorMsg(error.responseJSON.errors)
502                         }
503                     },
504                     closeTimingValidationInfo(dispatch)
505                 );
506             });
507     },
508
509     uploadVNFFile(
510         dispatch,
511         { csarId, failedNotificationTitle, softwareProductId, version }
512     ) {
513         dispatch({
514             type: HeatSetupActions.FILL_HEAT_SETUP_CACHE,
515             payload: {}
516         });
517
518         Promise.resolve()
519             .then(() => uploadVNFFile(csarId, softwareProductId, version))
520             .then(response => {
521                 if (response.status === 'Success') {
522                     dispatch({
523                         type: commonActionTypes.DATA_CHANGED,
524                         deltaData: {
525                             onboardingOrigin: response.onboardingOrigin
526                         },
527                         formName: forms.VENDOR_SOFTWARE_PRODUCT_DETAILS
528                     });
529                     switch (response.onboardingOrigin) {
530                         case onboardingOriginTypes.ZIP:
531                             OnboardingActionHelper.navigateToSoftwareProductAttachmentsSetupTab(
532                                 dispatch,
533                                 { softwareProductId, version }
534                             );
535                             break;
536                         case onboardingOriginTypes.CSAR:
537                             OnboardingActionHelper.navigateToSoftwareProductAttachmentsValidationTab(
538                                 dispatch,
539                                 { softwareProductId, version }
540                             );
541                             break;
542                     }
543                 } else {
544                     throw new Error(parseUploadErrorMsg(response.errors));
545                 }
546             })
547             .catch(error => {
548                 dispatch({
549                     type: modalActionTypes.GLOBAL_MODAL_ERROR,
550                     data: {
551                         title: failedNotificationTitle,
552                         msg: error.message
553                     }
554                 });
555             });
556     },
557     downloadHeatFile(
558         dispatch,
559         { softwareProductId, heatCandidate, isReadOnlyMode, version }
560     ) {
561         let p = isReadOnlyMode
562             ? Promise.resolve()
563             : SoftwareProductActionHelper.updateSoftwareProductHeatCandidate(
564                   dispatch,
565                   {
566                       softwareProductId,
567                       heatCandidate,
568                       version
569                   }
570               );
571         p.then(() => {
572             fetchOrchestrationTemplateCandidate(
573                 softwareProductId,
574                 version
575             ).then(response => {
576                 showFileSaveDialog({
577                     blob: response.blob,
578                     headers: response.headers,
579                     defaultFilename: 'HEAT_file.zip',
580                     addTimestamp: true
581                 });
582             });
583         }, null /* do not download if data was not saved correctly*/);
584     },
585
586     hideUploadConfirm(dispatch) {
587         dispatch({
588             type: actionTypes.softwareProductEditor.UPLOAD_CONFIRMATION
589         });
590     },
591     updateSoftwareProduct(dispatch, { softwareProduct, version, qdata }) {
592         return Promise.all([
593             SoftwareProductActionHelper.updateSoftwareProductData(dispatch, {
594                 softwareProduct,
595                 version
596             }).then(() =>
597                 dispatch({
598                     type: actionTypes.SOFTWARE_PRODUCT_LIST_EDIT,
599                     payload: { softwareProduct }
600                 })
601             ),
602             SoftwareProductActionHelper.updateSoftwareProductQuestionnaire(
603                 dispatch,
604                 {
605                     softwareProductId: softwareProduct.id,
606                     qdata,
607                     version
608                 }
609             )
610         ]);
611     },
612
613     updateSoftwareProductData(dispatch, { softwareProduct, version }) {
614         return putSoftwareProduct({ softwareProduct, version });
615     },
616
617     updateSoftwareProductQuestionnaire(
618         dispatch,
619         { softwareProductId, qdata, version }
620     ) {
621         return putSoftwareProductQuestionnaire(
622             softwareProductId,
623             qdata,
624             version
625         );
626     },
627
628     softwareProductEditorDataChanged(dispatch, { deltaData }) {
629         dispatch({
630             type: actionTypes.softwareProductEditor.DATA_CHANGED,
631             deltaData
632         });
633     },
634
635     softwareProductQuestionnaireUpdate(dispatch, { data }) {
636         dispatch({
637             type: actionTypes.SOFTWARE_PRODUCT_QUESTIONNAIRE_UPDATE,
638             payload: { qdata: data }
639         });
640     },
641
642     softwareProductEditorVendorChanged(dispatch, { deltaData, formName }) {
643         if (deltaData.licensingVersion) {
644             return loadLicensingData(dispatch, {
645                 licenseModelId: deltaData.vendorId,
646                 licensingVersion: deltaData.licensingVersion
647             }).then(() => {
648                 ValidationHelper.dataChanged(dispatch, { deltaData, formName });
649                 return Promise.resolve();
650             });
651         } else if (deltaData.vendorId) {
652             ValidationHelper.dataChanged(dispatch, { deltaData, formName });
653             return SoftwareProductActionHelper.loadLicensingVersionsList(
654                 dispatch,
655                 {
656                     licenseModelId: deltaData.vendorId
657                 }
658             ).then(() =>
659                 OnboardingActionHelper.forceBreadCrumbsUpdate(dispatch)
660             );
661         } else {
662             ValidationHelper.dataChanged(dispatch, { deltaData, formName });
663
664             dispatch({
665                 type: licenseAgreementActionTypes.LICENSE_AGREEMENT_LIST_LOADED,
666                 response: { results: [] }
667             });
668
669             dispatch({
670                 type: featureGroupsActionConstants.FEATURE_GROUPS_LIST_LOADED,
671                 response: { results: [] }
672             });
673         }
674     },
675
676     setIsValidityData(dispatch, { isValidityData }) {
677         dispatch({
678             type: actionTypes.softwareProductEditor.IS_VALIDITY_DATA_CHANGED,
679             isValidityData
680         });
681     },
682
683     fetchSoftwareProduct(dispatch, { softwareProductId, version }) {
684         return Promise.all([
685             fetchSoftwareProduct(softwareProductId, version).then(response => {
686                 dispatch({
687                     type: actionTypes.SOFTWARE_PRODUCT_LOADED,
688                     response
689                 });
690                 return response;
691             }),
692             fetchSoftwareProductQuestionnaire(softwareProductId, version).then(
693                 response => {
694                     ValidationHelper.qDataLoaded(dispatch, {
695                         response: {
696                             qdata: response.data
697                                 ? JSON.parse(response.data)
698                                 : {},
699                             qschema: JSON.parse(response.schema)
700                         },
701                         qName: PRODUCT_QUESTIONNAIRE
702                     });
703                 }
704             )
705         ]);
706     },
707
708     manageSubmitAction(dispatch, { softwareProductId, version, isDirty }) {
709         if (isDirty) {
710             const onCommit = comment => {
711                 return this.performVCAction(dispatch, {
712                     softwareProductId,
713                     action: VersionControllerActionsEnum.COMMIT,
714                     version,
715                     comment
716                 }).then(() => {
717                     return this.performSubmitAction(dispatch, {
718                         softwareProductId,
719                         version
720                     });
721                 });
722             };
723             dispatch({
724                 type: modalActionTypes.GLOBAL_MODAL_SHOW,
725                 data: {
726                     modalComponentName: modalContentMapper.COMMIT_COMMENT,
727                     modalComponentProps: {
728                         onCommit,
729                         type: CommitModalType.COMMIT_SUBMIT
730                     },
731                     title: i18n('Commit & Submit')
732                 }
733             });
734             return Promise.resolve(version);
735         }
736         return this.performSubmitAction(dispatch, {
737             softwareProductId,
738             version
739         });
740     },
741
742     performSubmitAction(dispatch, { softwareProductId, version }) {
743         return putSoftwareProductAction(
744             softwareProductId,
745             VersionControllerActionsEnum.SUBMIT,
746             version
747         ).then(
748             () => {
749                 return putSoftwareProductAction(
750                     softwareProductId,
751                     VersionControllerActionsEnum.CREATE_PACKAGE,
752                     version
753                 ).then(() => {
754                     return ItemsHelper.checkItemStatus(dispatch, {
755                         itemId: softwareProductId,
756                         versionId: version.id
757                     }).then(updatedVersion => {
758                         dispatch({
759                             type: modalActionTypes.GLOBAL_MODAL_SUCCESS,
760                             data: {
761                                 title: i18n('Submit Succeeded'),
762                                 msg: i18n(
763                                     'This software product successfully submitted'
764                                 ),
765                                 cancelButtonText: i18n('OK'),
766                                 timeout: 2000
767                             }
768                         });
769                         versionPageActionHelper.fetchVersions(dispatch, {
770                             itemType: itemTypes.SOFTWARE_PRODUCT,
771                             itemId: softwareProductId
772                         });
773                         return Promise.resolve(updatedVersion);
774                     });
775                 });
776             },
777             error => {
778                 dispatch({
779                     type: modalActionTypes.GLOBAL_MODAL_ERROR,
780                     data: {
781                         modalComponentName:
782                             modalContentMapper.SUMBIT_ERROR_RESPONSE,
783                         title: i18n('Submit Failed'),
784                         modalComponentProps: {
785                             validationResponse: error.responseJSON
786                         },
787                         cancelButtonText: i18n('OK')
788                     }
789                 });
790                 return Promise.reject(error.responseJSON);
791             }
792         );
793     },
794
795     performVCAction(dispatch, { softwareProductId, action, version, comment }) {
796         return MergeEditorActionHelper.analyzeSyncResult(dispatch, {
797             itemId: softwareProductId,
798             version
799         }).then(({ inMerge, isDirty, updatedVersion }) => {
800             if (
801                 (updatedVersion.status === versionStatus.CERTIFIED ||
802                     updatedVersion.archivedStatus === itemStatus.ARCHIVED) &&
803                 (action === VersionControllerActionsEnum.COMMIT ||
804                     action === VersionControllerActionsEnum.SYNC)
805             ) {
806                 versionPageActionHelper.fetchVersions(dispatch, {
807                     itemType: itemTypes.SOFTWARE_PRODUCT,
808                     itemId: softwareProductId
809                 });
810                 const msg =
811                     updatedVersion.archivedStatus === itemStatus.ARCHIVED
812                         ? i18n('Item was Archived')
813                         : i18n('Item version already Certified');
814                 dispatch({
815                     type: modalActionTypes.GLOBAL_MODAL_WARNING,
816                     data: {
817                         title: i18n('Commit error'),
818                         msg,
819                         cancelButtonText: i18n('Cancel')
820                     }
821                 });
822                 return Promise.resolve(updatedVersion);
823             }
824             if (!inMerge) {
825                 if (action === VersionControllerActionsEnum.SUBMIT) {
826                     return this.manageSubmitAction(dispatch, {
827                         softwareProductId,
828                         version,
829                         isDirty
830                     });
831                 } else {
832                     let isCallActionValid =
833                         action !== VersionControllerActionsEnum.COMMIT ||
834                         isDirty;
835                     if (isCallActionValid) {
836                         return ItemsHelper.performVCAction({
837                             itemId: softwareProductId,
838                             action,
839                             version,
840                             comment
841                         }).then(() => {
842                             versionPageActionHelper.fetchVersions(dispatch, {
843                                 itemType: itemTypes.LICENSE_MODEL,
844                                 itemId: softwareProductId
845                             });
846                             if (action === VersionControllerActionsEnum.SYNC) {
847                                 return MergeEditorActionHelper.analyzeSyncResult(
848                                     dispatch,
849                                     { itemId: softwareProductId, version }
850                                 ).then(({ updatedVersion }) => {
851                                     return Promise.resolve(updatedVersion);
852                                 });
853                             } else {
854                                 return ItemsHelper.checkItemStatus(dispatch, {
855                                     itemId: softwareProductId,
856                                     versionId: version.id
857                                 });
858                             }
859                         });
860                     } else {
861                         dispatch({
862                             type: modalActionTypes.GLOBAL_MODAL_ERROR,
863                             data: {
864                                 title: i18n('Commit Failed'),
865                                 msg: i18n('There is nothing to commit')
866                             }
867                         });
868                     }
869                 }
870             }
871         });
872     },
873
874     toggleNavigationItems(dispatch, { items, itemIdToExpand }) {
875         let mapOfExpandedIds = getExpandedItemsId(items, itemIdToExpand);
876         dispatch({
877             type: actionTypes.TOGGLE_NAVIGATION_ITEM,
878             mapOfExpandedIds
879         });
880     },
881
882     /** for the next verision */
883     addComponent(dispatch, { softwareProductId, version }) {
884         SoftwareProductComponentsActionHelper.clearComponentCreationData(
885             dispatch
886         );
887         dispatch({
888             type: componentActionTypes.COMPONENT_CREATE_OPEN
889         });
890         dispatch({
891             type: modalActionTypes.GLOBAL_MODAL_SHOW,
892             data: {
893                 modalComponentName: modalContentMapper.COMPONENT_CREATION,
894                 modalComponentProps: { softwareProductId, version },
895                 title: 'Create Virtual Function Component'
896             }
897         });
898     },
899
900     migrateSoftwareProduct(dispatch, { softwareProduct }) {
901         let { id: softwareProductId, version } = softwareProduct;
902         const newVer = version.id;
903         migrateSoftwareProduct(softwareProductId, version).then(() =>
904             ScreensHelper.loadScreen(dispatch, {
905                 screen: enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE,
906                 screenType: screenTypes.SOFTWARE_PRODUCT,
907                 props: {
908                     softwareProductId,
909                     version: { id: newVer, label: newVer }
910                 }
911             })
912         );
913     },
914
915     abortCandidateValidation(dispatch, { softwareProductId, version }) {
916         return abortValidationProcess(softwareProductId, version);
917     }
918 };
919
920 export default SoftwareProductActionHelper;