Obtain upload lock before uploading
[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, onUploadProgress = undefined) {
116     const options = {
117         noLoading: true
118     };
119     if (onUploadProgress) {
120         options.onUploadProgress = onUploadProgress;
121     }
122     return RestAPIUtil.post(
123         `${baseUrl()}${vspId}/versions/${
124             version.id
125         }/orchestration-template-candidate`,
126         formData,
127         options
128     );
129 }
130
131 function uploadVNFFile(csarId, softwareProductId, version) {
132     let verId = typeof version === 'object' ? version.id : version;
133     return RestAPIUtil.post(
134         `${baseUrl()}${softwareProductId}/versions/${verId}/vnfrepository/vnfpackage/${csarId}/import`
135     );
136 }
137 function putSoftwareProduct({ softwareProduct, version }) {
138     return RestAPIUtil.put(
139         `${baseUrl()}${softwareProduct.id}/versions/${version.id}`,
140         {
141             name: softwareProduct.name,
142             description: softwareProduct.description,
143             category: softwareProduct.category,
144             subCategory: softwareProduct.subCategory,
145             vendorId: softwareProduct.vendorId,
146             vendorName: softwareProduct.vendorName,
147             licensingVersion: softwareProduct.licensingVersion
148                 ? softwareProduct.licensingVersion
149                 : undefined,
150             icon: softwareProduct.icon,
151             licenseType: softwareProduct.licenseType,
152             selectedModelList: softwareProduct.selectedModelList,
153             licensingData: getLicensingData(softwareProduct.licensingData)
154         }
155     );
156 }
157
158 function putSoftwareProductQuestionnaire(vspId, qdata, version) {
159     return RestAPIUtil.put(
160         `${baseUrl()}${vspId}/versions/${version.id}/questionnaire`,
161         qdata
162     );
163 }
164
165 function putSoftwareProductAction(id, action, version) {
166     return RestAPIUtil.put(`${baseUrl()}${id}/versions/${version.id}/actions`, {
167         action: action
168     });
169 }
170
171 function fetchSoftwareProductList() {
172     return RestAPIUtil.fetch(
173         `${baseUrl()}?versionFilter=${versionStatus.DRAFT}`
174     );
175 }
176
177 function fetchArchivedSoftwareProductList() {
178     return RestAPIUtil.fetch(`${baseUrl()}?Status=${itemStatus.ARCHIVED}`);
179 }
180
181 function fetchFinalizedSoftwareProductList() {
182     return RestAPIUtil.fetch(
183         `${baseUrl()}?versionFilter=${versionStatus.CERTIFIED}`
184     );
185 }
186
187 function fetchSoftwareProduct(vspId, version) {
188     return RestAPIUtil.fetch(`${baseUrl()}${vspId}/versions/${version.id}`);
189 }
190
191 function fetchSoftwareProductQuestionnaire(vspId, version) {
192     return RestAPIUtil.fetch(
193         `${baseUrl()}${vspId}/versions/${version.id}/questionnaire`
194     );
195 }
196
197 function updateSoftwareProductHeatCandidate(
198     softwareProductId,
199     heatCandidate,
200     version
201 ) {
202     return RestAPIUtil.put(
203         `${baseUrl()}${softwareProductId}/versions/${
204             version.id
205         }/orchestration-template-candidate/manifest`,
206         heatCandidate
207     );
208 }
209 function validateHeatCandidate(softwareProductId, version) {
210     return RestAPIUtil.put(
211         `${baseUrl()}${softwareProductId}/versions/${
212             version.id
213         }/orchestration-template-candidate/process`
214     );
215 }
216
217 function fetchOrchestrationTemplateCandidate(softwareProductId, version) {
218     return RestAPIUtil.fetch(
219         `${baseUrl()}${softwareProductId}/versions/${
220             version.id
221         }/orchestration-template-candidate`,
222         { dataType: 'binary' }
223     );
224 }
225
226 function abortValidationProcess(softwareProductId, version) {
227     return RestAPIUtil.destroy(
228         `${baseUrl()}${softwareProductId}/versions/${
229             version.id
230         }/orchestration-template-candidate`
231     );
232 }
233
234 function objToString(obj) {
235     let str = '';
236     if (obj instanceof Array) {
237         obj.forEach(item => {
238             str += objToString(item) + '\n';
239         });
240     } else {
241         for (let p in obj) {
242             if (obj.hasOwnProperty(p)) {
243                 str += obj[p] + '\n';
244             }
245         }
246     }
247     return str.replace(/\n$/, '');
248 }
249
250 function parseUploadErrorMsg(error) {
251     let message = '';
252     for (let key in error) {
253         if (error.hasOwnProperty(key)) {
254             message += objToString(error[key]) + '\n';
255         }
256     }
257     return message.replace(/\n$/, '');
258 }
259
260 function showWarningValidationInfo(dispatch, errors) {
261     dispatch({
262         type: modalActionTypes.GLOBAL_MODAL_WARNING,
263         data: {
264             title: 'Validation messages',
265             msg: parseUploadErrorMsg(errors),
266             cancelButtonText: 'OK'
267         }
268     });
269 }
270
271 function fetchSoftwareProductCategories(dispatch) {
272     let handleResponse = response =>
273         dispatch({
274             type: actionTypes.SOFTWARE_PRODUCT_CATEGORIES_LOADED,
275             softwareProductCategories: response
276         });
277     return RestAPIUtil.fetch(softwareProductCategoriesUrl())
278         .then(handleResponse)
279         .catch(() => handleResponse(null));
280 }
281
282 function fetchModelList(dispatch) {
283     let handleResponse = response =>
284         dispatch({
285             type: actionTypes.SOFTWARE_PRODUCT_MODELS_LOADED,
286             modelList: response
287         });
288     RestAPIUtil.fetch(getModelUrl())
289         .then(handleResponse)
290         .catch(() => handleResponse(null));
291 }
292
293 function loadLicensingData(dispatch, { licenseModelId, licensingVersion }) {
294     return ItemsHelper.fetchVersion({
295         itemId: licenseModelId,
296         versionId: licensingVersion
297     }).then(() => {
298         return Promise.all([
299             LicenseAgreementActionHelper.fetchLicenseAgreementList(dispatch, {
300                 licenseModelId,
301                 version: { id: licensingVersion }
302             }),
303             FeatureGroupsActionHelper.fetchFeatureGroupsList(dispatch, {
304                 licenseModelId,
305                 version: { id: licensingVersion }
306             })
307         ]);
308     });
309 }
310
311 function getExpandedItemsId(items, itemIdToToggle) {
312     for (let i = 0; i < items.length; i++) {
313         if (items[i].id === itemIdToToggle) {
314             if (items[i].expanded) {
315                 return {};
316             } else {
317                 return { [itemIdToToggle]: true };
318             }
319         } else if (items[i].items && items[i].items.length > 0) {
320             let mapOfExpandedIds = getExpandedItemsId(
321                 items[i].items,
322                 itemIdToToggle
323             );
324             if (mapOfExpandedIds !== false) {
325                 mapOfExpandedIds[items[i].id] = true;
326                 return mapOfExpandedIds;
327             }
328         }
329     }
330     return false;
331 }
332
333 function migrateSoftwareProduct(vspId, version) {
334     return RestAPIUtil.put(`${baseUrl()}${vspId}/versions/${version.id}/heal`);
335 }
336
337 const SoftwareProductActionHelper = {
338     fetchFinalizedSoftwareProductList(dispatch) {
339         return fetchFinalizedSoftwareProductList().then(response =>
340             dispatch({
341                 type: actionTypes.FINALIZED_SOFTWARE_PRODUCT_LIST_LOADED,
342                 response
343             })
344         );
345     },
346
347     fetchArchivedSoftwareProductList(dispatch) {
348         return fetchArchivedSoftwareProductList().then(response =>
349             dispatch({
350                 type: actionTypes.ARCHIVED_SOFTWARE_PRODUCT_LIST_LOADED,
351                 response
352             })
353         );
354     },
355
356     fetchUploadStatus(vspId, versionId) {
357         const options = {
358             validateStatus: function(status) {
359                 return status < 400 || status === 404;
360             },
361             noLoading: true
362         };
363         return RestAPIUtil.get(
364             `${baseUrl()}${vspId}/versions/${versionId}/orchestration-template-candidate/upload`,
365             options
366         );
367     },
368
369     createUploadStatus(vspId, versionId) {
370         const options = {
371             noLoading: true
372         };
373         return RestAPIUtil.post(
374             `${baseUrl()}${vspId}/versions/${versionId}/orchestration-template-candidate/upload`,
375             options
376         );
377     },
378
379     loadSoftwareProductAssociatedData(dispatch) {
380         fetchSoftwareProductCategories(dispatch);
381         fetchModelList(dispatch);
382         LicenseModelActionHelper.fetchFinalizedLicenseModels(dispatch);
383     },
384
385     loadSoftwareProductDetailsData(
386         dispatch,
387         { licenseModelId, licensingVersion }
388     ) {
389         SoftwareProductActionHelper.loadSoftwareProductAssociatedData(dispatch);
390         if (licensingVersion) {
391             return loadLicensingData(dispatch, {
392                 licenseModelId,
393                 licensingVersion
394             });
395         }
396         return Promise.resolve();
397     },
398
399     fetchSoftwareProductList(dispatch) {
400         return fetchSoftwareProductList().then(response =>
401             dispatch({
402                 type: actionTypes.SOFTWARE_PRODUCT_LIST_LOADED,
403                 response
404             })
405         );
406     },
407
408     loadSoftwareProductHeatCandidate(dispatch, { softwareProductId, version }) {
409         return RestAPIUtil.fetch(
410             `${baseUrl()}${softwareProductId}/versions/${
411                 version.id
412             }/orchestration-template-candidate/manifest`
413         ).then(response =>
414             dispatch({
415                 type: HeatSetupActions.MANIFEST_LOADED,
416                 response
417             })
418         );
419     },
420
421     loadLicensingVersionsList(dispatch, { licenseModelId }) {
422         return ItemsHelper.fetchVersions({ itemId: licenseModelId }).then(
423             response => {
424                 dispatch({
425                     type: actionTypes.LOAD_LICENSING_VERSIONS_LIST,
426                     licensingVersionsList: response.results
427                 });
428             }
429         );
430     },
431     updateSoftwareProductHeatCandidate(
432         dispatch,
433         { softwareProductId, heatCandidate, version }
434     ) {
435         return updateSoftwareProductHeatCandidate(
436             softwareProductId,
437             heatCandidate,
438             version
439         );
440     },
441
442     processAndValidateHeatCandidate(dispatch, { softwareProductId, version }) {
443         displayTimingValidationInfo(dispatch);
444         return validateHeatCandidate(softwareProductId, version).then(
445             response => {
446                 if (response.status === 'Success') {
447                     SoftwareProductComponentsActionHelper.fetchSoftwareProductComponents(
448                         dispatch,
449                         { softwareProductId, version }
450                     );
451                     SoftwareProductActionHelper.fetchSoftwareProduct(dispatch, {
452                         softwareProductId,
453                         version
454                     });
455                 } else {
456                     SoftwareProductActionHelper.fetchSoftwareProduct(dispatch, {
457                         softwareProductId,
458                         version
459                     });
460                 }
461                 closeTimingValidationInfo(dispatch);
462             }
463         );
464     },
465
466     uploadFile(
467         dispatch,
468         {
469             softwareProductId,
470             formData,
471             failedNotificationTitle,
472             version,
473             onUploadProgress = undefined
474         }
475     ) {
476         dispatch({
477             type: HeatSetupActions.FILL_HEAT_SETUP_CACHE,
478             payload: {}
479         });
480         return Promise.resolve()
481             .then(() =>
482                 uploadFile(
483                     softwareProductId,
484                     formData,
485                     version,
486                     onUploadProgress
487                 )
488             )
489             .then(response => {
490                 if (response.status === 'Success') {
491                     dispatch({
492                         type: commonActionTypes.DATA_CHANGED,
493                         deltaData: {
494                             onboardingOrigin: response.onboardingOrigin
495                         },
496                         formName: forms.VENDOR_SOFTWARE_PRODUCT_DETAILS
497                     });
498                     switch (response.onboardingOrigin) {
499                         case onboardingOriginTypes.ZIP:
500                             ScreensHelper.loadScreen(dispatch, {
501                                 screen:
502                                     enums.SCREEN
503                                         .SOFTWARE_PRODUCT_ATTACHMENTS_SETUP,
504                                 screenType: screenTypes.SOFTWARE_PRODUCT,
505                                 props: { softwareProductId, version }
506                             });
507                             dispatch({
508                                 type: actionTypes.CANDIDATE_IN_PROCESS,
509                                 inProcess: true
510                             });
511                             break;
512                         case onboardingOriginTypes.CSAR:
513                             ScreensHelper.loadScreen(dispatch, {
514                                 screen:
515                                     enums.SCREEN
516                                         .SOFTWARE_PRODUCT_ATTACHMENTS_VALIDATION,
517                                 screenType: screenTypes.SOFTWARE_PRODUCT,
518                                 props: { softwareProductId, version }
519                             });
520                             break;
521                     }
522                     closeTimingValidationInfo(dispatch);
523                     if (
524                         response.errors !== null &&
525                         Object.keys(response.errors).length !== 0
526                     ) {
527                         showWarningValidationInfo(dispatch, response.errors);
528                     }
529                 } else {
530                     throw new Error(parseUploadErrorMsg(response.errors));
531                 }
532             })
533             .catch(error => {
534                 dispatch(
535                     {
536                         type: modalActionTypes.GLOBAL_MODAL_ERROR,
537                         data: {
538                             title: failedNotificationTitle,
539                             msg:
540                                 error.message ||
541                                 (error.responseJSON &&
542                                     error.responseJSON.message) ||
543                                 parseUploadErrorMsg(error.responseJSON.errors)
544                         }
545                     },
546                     closeTimingValidationInfo(dispatch)
547                 );
548             });
549     },
550
551     uploadVNFFile(
552         dispatch,
553         { csarId, failedNotificationTitle, softwareProductId, version }
554     ) {
555         dispatch({
556             type: HeatSetupActions.FILL_HEAT_SETUP_CACHE,
557             payload: {}
558         });
559
560         Promise.resolve()
561             .then(() => uploadVNFFile(csarId, softwareProductId, version))
562             .then(response => {
563                 if (response.status === 'Success') {
564                     dispatch({
565                         type: commonActionTypes.DATA_CHANGED,
566                         deltaData: {
567                             onboardingOrigin: response.onboardingOrigin
568                         },
569                         formName: forms.VENDOR_SOFTWARE_PRODUCT_DETAILS
570                     });
571                     switch (response.onboardingOrigin) {
572                         case onboardingOriginTypes.ZIP:
573                             OnboardingActionHelper.navigateToSoftwareProductAttachmentsSetupTab(
574                                 dispatch,
575                                 { softwareProductId, version }
576                             );
577                             break;
578                         case onboardingOriginTypes.CSAR:
579                             OnboardingActionHelper.navigateToSoftwareProductAttachmentsValidationTab(
580                                 dispatch,
581                                 { softwareProductId, version }
582                             );
583                             break;
584                     }
585                 } else {
586                     throw new Error(parseUploadErrorMsg(response.errors));
587                 }
588             })
589             .catch(error => {
590                 dispatch({
591                     type: modalActionTypes.GLOBAL_MODAL_ERROR,
592                     data: {
593                         title: failedNotificationTitle,
594                         msg: error.message
595                     }
596                 });
597             });
598     },
599     downloadHeatFile(
600         dispatch,
601         { softwareProductId, heatCandidate, isReadOnlyMode, version }
602     ) {
603         let p = isReadOnlyMode
604             ? Promise.resolve()
605             : SoftwareProductActionHelper.updateSoftwareProductHeatCandidate(
606                   dispatch,
607                   {
608                       softwareProductId,
609                       heatCandidate,
610                       version
611                   }
612               );
613         p.then(() => {
614             fetchOrchestrationTemplateCandidate(
615                 softwareProductId,
616                 version
617             ).then(response => {
618                 showFileSaveDialog({
619                     blob: response.blob,
620                     headers: response.headers,
621                     defaultFilename: 'HEAT_file.zip',
622                     addTimestamp: true
623                 });
624             });
625         }, null /* do not download if data was not saved correctly*/);
626     },
627
628     hideUploadConfirm(dispatch) {
629         dispatch({
630             type: actionTypes.softwareProductEditor.UPLOAD_CONFIRMATION
631         });
632     },
633     updateSoftwareProduct(dispatch, { softwareProduct, version, qdata }) {
634         return Promise.all([
635             SoftwareProductActionHelper.updateSoftwareProductData(dispatch, {
636                 softwareProduct,
637                 version
638             }).then(() =>
639                 dispatch({
640                     type: actionTypes.SOFTWARE_PRODUCT_LIST_EDIT,
641                     payload: { softwareProduct }
642                 })
643             ),
644             SoftwareProductActionHelper.updateSoftwareProductQuestionnaire(
645                 dispatch,
646                 {
647                     softwareProductId: softwareProduct.id,
648                     qdata,
649                     version
650                 }
651             )
652         ]);
653     },
654
655     updateSoftwareProductData(dispatch, { softwareProduct, version }) {
656         return putSoftwareProduct({ softwareProduct, version });
657     },
658
659     updateSoftwareProductQuestionnaire(
660         dispatch,
661         { softwareProductId, qdata, version }
662     ) {
663         return putSoftwareProductQuestionnaire(
664             softwareProductId,
665             qdata,
666             version
667         );
668     },
669
670     softwareProductEditorDataChanged(dispatch, { deltaData }) {
671         dispatch({
672             type: actionTypes.softwareProductEditor.DATA_CHANGED,
673             deltaData
674         });
675     },
676
677     softwareProductQuestionnaireUpdate(dispatch, { data }) {
678         dispatch({
679             type: actionTypes.SOFTWARE_PRODUCT_QUESTIONNAIRE_UPDATE,
680             payload: { qdata: data }
681         });
682     },
683
684     softwareProductEditorVendorChanged(dispatch, { deltaData, formName }) {
685         if (deltaData.licensingVersion) {
686             return loadLicensingData(dispatch, {
687                 licenseModelId: deltaData.vendorId,
688                 licensingVersion: deltaData.licensingVersion
689             }).then(() => {
690                 ValidationHelper.dataChanged(dispatch, { deltaData, formName });
691                 return Promise.resolve();
692             });
693         } else if (deltaData.vendorId) {
694             ValidationHelper.dataChanged(dispatch, { deltaData, formName });
695             return SoftwareProductActionHelper.loadLicensingVersionsList(
696                 dispatch,
697                 {
698                     licenseModelId: deltaData.vendorId
699                 }
700             ).then(() =>
701                 OnboardingActionHelper.forceBreadCrumbsUpdate(dispatch)
702             );
703         } else {
704             ValidationHelper.dataChanged(dispatch, { deltaData, formName });
705
706             dispatch({
707                 type: licenseAgreementActionTypes.LICENSE_AGREEMENT_LIST_LOADED,
708                 response: { results: [] }
709             });
710
711             dispatch({
712                 type: featureGroupsActionConstants.FEATURE_GROUPS_LIST_LOADED,
713                 response: { results: [] }
714             });
715         }
716     },
717
718     setIsValidityData(dispatch, { isValidityData }) {
719         dispatch({
720             type: actionTypes.softwareProductEditor.IS_VALIDITY_DATA_CHANGED,
721             isValidityData
722         });
723     },
724
725     fetchSoftwareProduct(dispatch, { softwareProductId, version }) {
726         return Promise.all([
727             fetchSoftwareProduct(softwareProductId, version).then(response => {
728                 dispatch({
729                     type: actionTypes.SOFTWARE_PRODUCT_LOADED,
730                     response
731                 });
732                 return response;
733             }),
734             fetchSoftwareProductQuestionnaire(softwareProductId, version).then(
735                 response => {
736                     ValidationHelper.qDataLoaded(dispatch, {
737                         response: {
738                             qdata: response.data
739                                 ? JSON.parse(response.data)
740                                 : {},
741                             qschema: JSON.parse(response.schema)
742                         },
743                         qName: PRODUCT_QUESTIONNAIRE
744                     });
745                 }
746             )
747         ]);
748     },
749
750     manageSubmitAction(dispatch, { softwareProductId, version, isDirty }) {
751         if (isDirty) {
752             const onCommit = comment => {
753                 return this.performVCAction(dispatch, {
754                     softwareProductId,
755                     action: VersionControllerActionsEnum.COMMIT,
756                     version,
757                     comment
758                 }).then(() => {
759                     return this.performSubmitAction(dispatch, {
760                         softwareProductId,
761                         version
762                     });
763                 });
764             };
765             dispatch({
766                 type: modalActionTypes.GLOBAL_MODAL_SHOW,
767                 data: {
768                     modalComponentName: modalContentMapper.COMMIT_COMMENT,
769                     modalComponentProps: {
770                         onCommit,
771                         type: CommitModalType.COMMIT_SUBMIT
772                     },
773                     title: i18n('Commit & Submit')
774                 }
775             });
776             return Promise.resolve(version);
777         }
778         return this.performSubmitAction(dispatch, {
779             softwareProductId,
780             version
781         });
782     },
783
784     performSubmitAction(dispatch, { softwareProductId, version }) {
785         return putSoftwareProductAction(
786             softwareProductId,
787             VersionControllerActionsEnum.SUBMIT,
788             version
789         ).then(
790             () => {
791                 return putSoftwareProductAction(
792                     softwareProductId,
793                     VersionControllerActionsEnum.CREATE_PACKAGE,
794                     version
795                 ).then(() => {
796                     return ItemsHelper.checkItemStatus(dispatch, {
797                         itemId: softwareProductId,
798                         versionId: version.id
799                     }).then(updatedVersion => {
800                         dispatch({
801                             type: modalActionTypes.GLOBAL_MODAL_SUCCESS,
802                             data: {
803                                 title: i18n('Submit Succeeded'),
804                                 msg: i18n(
805                                     'This software product successfully submitted'
806                                 ),
807                                 cancelButtonText: i18n('OK'),
808                                 timeout: 2000
809                             }
810                         });
811                         versionPageActionHelper.fetchVersions(dispatch, {
812                             itemType: itemTypes.SOFTWARE_PRODUCT,
813                             itemId: softwareProductId
814                         });
815                         return Promise.resolve(updatedVersion);
816                     });
817                 });
818             },
819             error => {
820                 dispatch({
821                     type: modalActionTypes.GLOBAL_MODAL_ERROR,
822                     data: {
823                         modalComponentName:
824                             modalContentMapper.SUMBIT_ERROR_RESPONSE,
825                         title: i18n('Submit Failed'),
826                         modalComponentProps: {
827                             validationResponse: error.responseJSON
828                         },
829                         cancelButtonText: i18n('OK')
830                     }
831                 });
832                 return Promise.reject(error.responseJSON);
833             }
834         );
835     },
836
837     performVCAction(dispatch, { softwareProductId, action, version, comment }) {
838         return MergeEditorActionHelper.analyzeSyncResult(dispatch, {
839             itemId: softwareProductId,
840             version
841         }).then(({ inMerge, isDirty, updatedVersion }) => {
842             if (
843                 (updatedVersion.status === versionStatus.CERTIFIED ||
844                     updatedVersion.archivedStatus === itemStatus.ARCHIVED) &&
845                 (action === VersionControllerActionsEnum.COMMIT ||
846                     action === VersionControllerActionsEnum.SYNC)
847             ) {
848                 versionPageActionHelper.fetchVersions(dispatch, {
849                     itemType: itemTypes.SOFTWARE_PRODUCT,
850                     itemId: softwareProductId
851                 });
852                 const msg =
853                     updatedVersion.archivedStatus === itemStatus.ARCHIVED
854                         ? i18n('Item was Archived')
855                         : i18n('Item version already Certified');
856                 dispatch({
857                     type: modalActionTypes.GLOBAL_MODAL_WARNING,
858                     data: {
859                         title: i18n('Commit error'),
860                         msg,
861                         cancelButtonText: i18n('Cancel')
862                     }
863                 });
864                 return Promise.resolve(updatedVersion);
865             }
866             if (!inMerge) {
867                 if (action === VersionControllerActionsEnum.SUBMIT) {
868                     return this.manageSubmitAction(dispatch, {
869                         softwareProductId,
870                         version,
871                         isDirty
872                     });
873                 } else {
874                     let isCallActionValid =
875                         action !== VersionControllerActionsEnum.COMMIT ||
876                         isDirty;
877                     if (isCallActionValid) {
878                         return ItemsHelper.performVCAction({
879                             itemId: softwareProductId,
880                             action,
881                             version,
882                             comment
883                         }).then(() => {
884                             versionPageActionHelper.fetchVersions(dispatch, {
885                                 itemType: itemTypes.LICENSE_MODEL,
886                                 itemId: softwareProductId
887                             });
888                             if (action === VersionControllerActionsEnum.SYNC) {
889                                 return MergeEditorActionHelper.analyzeSyncResult(
890                                     dispatch,
891                                     { itemId: softwareProductId, version }
892                                 ).then(({ updatedVersion }) => {
893                                     return Promise.resolve(updatedVersion);
894                                 });
895                             } else {
896                                 return ItemsHelper.checkItemStatus(dispatch, {
897                                     itemId: softwareProductId,
898                                     versionId: version.id
899                                 });
900                             }
901                         });
902                     } else {
903                         dispatch({
904                             type: modalActionTypes.GLOBAL_MODAL_ERROR,
905                             data: {
906                                 title: i18n('Commit Failed'),
907                                 msg: i18n('There is nothing to commit')
908                             }
909                         });
910                     }
911                 }
912             }
913         });
914     },
915
916     toggleNavigationItems(dispatch, { items, itemIdToExpand }) {
917         let mapOfExpandedIds = getExpandedItemsId(items, itemIdToExpand);
918         dispatch({
919             type: actionTypes.TOGGLE_NAVIGATION_ITEM,
920             mapOfExpandedIds
921         });
922     },
923
924     /** for the next verision */
925     addComponent(dispatch, { softwareProductId, version }) {
926         SoftwareProductComponentsActionHelper.clearComponentCreationData(
927             dispatch
928         );
929         dispatch({
930             type: componentActionTypes.COMPONENT_CREATE_OPEN
931         });
932         dispatch({
933             type: modalActionTypes.GLOBAL_MODAL_SHOW,
934             data: {
935                 modalComponentName: modalContentMapper.COMPONENT_CREATION,
936                 modalComponentProps: { softwareProductId, version },
937                 title: 'Create Virtual Function Component'
938             }
939         });
940     },
941
942     migrateSoftwareProduct(dispatch, { softwareProduct }) {
943         let { id: softwareProductId, version } = softwareProduct;
944         const newVer = version.id;
945         migrateSoftwareProduct(softwareProductId, version).then(() =>
946             ScreensHelper.loadScreen(dispatch, {
947                 screen: enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE,
948                 screenType: screenTypes.SOFTWARE_PRODUCT,
949                 props: {
950                     softwareProductId,
951                     version: { id: newVer, label: newVer }
952                 }
953             })
954         );
955     },
956
957     abortCandidateValidation(dispatch, { softwareProductId, version }) {
958         return abortValidationProcess(softwareProductId, version);
959     }
960 };
961
962 export default SoftwareProductActionHelper;