Obtain and control VSP package upload status
[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     loadSoftwareProductAssociatedData(dispatch) {
370         fetchSoftwareProductCategories(dispatch);
371         fetchModelList(dispatch);
372         LicenseModelActionHelper.fetchFinalizedLicenseModels(dispatch);
373     },
374
375     loadSoftwareProductDetailsData(
376         dispatch,
377         { licenseModelId, licensingVersion }
378     ) {
379         SoftwareProductActionHelper.loadSoftwareProductAssociatedData(dispatch);
380         if (licensingVersion) {
381             return loadLicensingData(dispatch, {
382                 licenseModelId,
383                 licensingVersion
384             });
385         }
386         return Promise.resolve();
387     },
388
389     fetchSoftwareProductList(dispatch) {
390         return fetchSoftwareProductList().then(response =>
391             dispatch({
392                 type: actionTypes.SOFTWARE_PRODUCT_LIST_LOADED,
393                 response
394             })
395         );
396     },
397
398     loadSoftwareProductHeatCandidate(dispatch, { softwareProductId, version }) {
399         return RestAPIUtil.fetch(
400             `${baseUrl()}${softwareProductId}/versions/${
401                 version.id
402             }/orchestration-template-candidate/manifest`
403         ).then(response =>
404             dispatch({
405                 type: HeatSetupActions.MANIFEST_LOADED,
406                 response
407             })
408         );
409     },
410
411     loadLicensingVersionsList(dispatch, { licenseModelId }) {
412         return ItemsHelper.fetchVersions({ itemId: licenseModelId }).then(
413             response => {
414                 dispatch({
415                     type: actionTypes.LOAD_LICENSING_VERSIONS_LIST,
416                     licensingVersionsList: response.results
417                 });
418             }
419         );
420     },
421     updateSoftwareProductHeatCandidate(
422         dispatch,
423         { softwareProductId, heatCandidate, version }
424     ) {
425         return updateSoftwareProductHeatCandidate(
426             softwareProductId,
427             heatCandidate,
428             version
429         );
430     },
431
432     processAndValidateHeatCandidate(dispatch, { softwareProductId, version }) {
433         displayTimingValidationInfo(dispatch);
434         return validateHeatCandidate(softwareProductId, version).then(
435             response => {
436                 if (response.status === 'Success') {
437                     SoftwareProductComponentsActionHelper.fetchSoftwareProductComponents(
438                         dispatch,
439                         { softwareProductId, version }
440                     );
441                     SoftwareProductActionHelper.fetchSoftwareProduct(dispatch, {
442                         softwareProductId,
443                         version
444                     });
445                 } else {
446                     SoftwareProductActionHelper.fetchSoftwareProduct(dispatch, {
447                         softwareProductId,
448                         version
449                     });
450                 }
451                 closeTimingValidationInfo(dispatch);
452             }
453         );
454     },
455
456     uploadFile(
457         dispatch,
458         {
459             softwareProductId,
460             formData,
461             failedNotificationTitle,
462             version,
463             onUploadProgress = undefined
464         }
465     ) {
466         dispatch({
467             type: HeatSetupActions.FILL_HEAT_SETUP_CACHE,
468             payload: {}
469         });
470         return Promise.resolve()
471             .then(() =>
472                 uploadFile(
473                     softwareProductId,
474                     formData,
475                     version,
476                     onUploadProgress
477                 )
478             )
479             .then(response => {
480                 if (response.status === 'Success') {
481                     dispatch({
482                         type: commonActionTypes.DATA_CHANGED,
483                         deltaData: {
484                             onboardingOrigin: response.onboardingOrigin
485                         },
486                         formName: forms.VENDOR_SOFTWARE_PRODUCT_DETAILS
487                     });
488                     switch (response.onboardingOrigin) {
489                         case onboardingOriginTypes.ZIP:
490                             ScreensHelper.loadScreen(dispatch, {
491                                 screen:
492                                     enums.SCREEN
493                                         .SOFTWARE_PRODUCT_ATTACHMENTS_SETUP,
494                                 screenType: screenTypes.SOFTWARE_PRODUCT,
495                                 props: { softwareProductId, version }
496                             });
497                             dispatch({
498                                 type: actionTypes.CANDIDATE_IN_PROCESS,
499                                 inProcess: true
500                             });
501                             break;
502                         case onboardingOriginTypes.CSAR:
503                             ScreensHelper.loadScreen(dispatch, {
504                                 screen:
505                                     enums.SCREEN
506                                         .SOFTWARE_PRODUCT_ATTACHMENTS_VALIDATION,
507                                 screenType: screenTypes.SOFTWARE_PRODUCT,
508                                 props: { softwareProductId, version }
509                             });
510                             break;
511                     }
512                     closeTimingValidationInfo(dispatch);
513                     if (
514                         response.errors !== null &&
515                         Object.keys(response.errors).length !== 0
516                     ) {
517                         showWarningValidationInfo(dispatch, response.errors);
518                     }
519                 } else {
520                     throw new Error(parseUploadErrorMsg(response.errors));
521                 }
522             })
523             .catch(error => {
524                 dispatch(
525                     {
526                         type: modalActionTypes.GLOBAL_MODAL_ERROR,
527                         data: {
528                             title: failedNotificationTitle,
529                             msg:
530                                 error.message ||
531                                 (error.responseJSON &&
532                                     error.responseJSON.message) ||
533                                 parseUploadErrorMsg(error.responseJSON.errors)
534                         }
535                     },
536                     closeTimingValidationInfo(dispatch)
537                 );
538             });
539     },
540
541     uploadVNFFile(
542         dispatch,
543         { csarId, failedNotificationTitle, softwareProductId, version }
544     ) {
545         dispatch({
546             type: HeatSetupActions.FILL_HEAT_SETUP_CACHE,
547             payload: {}
548         });
549
550         Promise.resolve()
551             .then(() => uploadVNFFile(csarId, softwareProductId, version))
552             .then(response => {
553                 if (response.status === 'Success') {
554                     dispatch({
555                         type: commonActionTypes.DATA_CHANGED,
556                         deltaData: {
557                             onboardingOrigin: response.onboardingOrigin
558                         },
559                         formName: forms.VENDOR_SOFTWARE_PRODUCT_DETAILS
560                     });
561                     switch (response.onboardingOrigin) {
562                         case onboardingOriginTypes.ZIP:
563                             OnboardingActionHelper.navigateToSoftwareProductAttachmentsSetupTab(
564                                 dispatch,
565                                 { softwareProductId, version }
566                             );
567                             break;
568                         case onboardingOriginTypes.CSAR:
569                             OnboardingActionHelper.navigateToSoftwareProductAttachmentsValidationTab(
570                                 dispatch,
571                                 { softwareProductId, version }
572                             );
573                             break;
574                     }
575                 } else {
576                     throw new Error(parseUploadErrorMsg(response.errors));
577                 }
578             })
579             .catch(error => {
580                 dispatch({
581                     type: modalActionTypes.GLOBAL_MODAL_ERROR,
582                     data: {
583                         title: failedNotificationTitle,
584                         msg: error.message
585                     }
586                 });
587             });
588     },
589     downloadHeatFile(
590         dispatch,
591         { softwareProductId, heatCandidate, isReadOnlyMode, version }
592     ) {
593         let p = isReadOnlyMode
594             ? Promise.resolve()
595             : SoftwareProductActionHelper.updateSoftwareProductHeatCandidate(
596                   dispatch,
597                   {
598                       softwareProductId,
599                       heatCandidate,
600                       version
601                   }
602               );
603         p.then(() => {
604             fetchOrchestrationTemplateCandidate(
605                 softwareProductId,
606                 version
607             ).then(response => {
608                 showFileSaveDialog({
609                     blob: response.blob,
610                     headers: response.headers,
611                     defaultFilename: 'HEAT_file.zip',
612                     addTimestamp: true
613                 });
614             });
615         }, null /* do not download if data was not saved correctly*/);
616     },
617
618     hideUploadConfirm(dispatch) {
619         dispatch({
620             type: actionTypes.softwareProductEditor.UPLOAD_CONFIRMATION
621         });
622     },
623     updateSoftwareProduct(dispatch, { softwareProduct, version, qdata }) {
624         return Promise.all([
625             SoftwareProductActionHelper.updateSoftwareProductData(dispatch, {
626                 softwareProduct,
627                 version
628             }).then(() =>
629                 dispatch({
630                     type: actionTypes.SOFTWARE_PRODUCT_LIST_EDIT,
631                     payload: { softwareProduct }
632                 })
633             ),
634             SoftwareProductActionHelper.updateSoftwareProductQuestionnaire(
635                 dispatch,
636                 {
637                     softwareProductId: softwareProduct.id,
638                     qdata,
639                     version
640                 }
641             )
642         ]);
643     },
644
645     updateSoftwareProductData(dispatch, { softwareProduct, version }) {
646         return putSoftwareProduct({ softwareProduct, version });
647     },
648
649     updateSoftwareProductQuestionnaire(
650         dispatch,
651         { softwareProductId, qdata, version }
652     ) {
653         return putSoftwareProductQuestionnaire(
654             softwareProductId,
655             qdata,
656             version
657         );
658     },
659
660     softwareProductEditorDataChanged(dispatch, { deltaData }) {
661         dispatch({
662             type: actionTypes.softwareProductEditor.DATA_CHANGED,
663             deltaData
664         });
665     },
666
667     softwareProductQuestionnaireUpdate(dispatch, { data }) {
668         dispatch({
669             type: actionTypes.SOFTWARE_PRODUCT_QUESTIONNAIRE_UPDATE,
670             payload: { qdata: data }
671         });
672     },
673
674     softwareProductEditorVendorChanged(dispatch, { deltaData, formName }) {
675         if (deltaData.licensingVersion) {
676             return loadLicensingData(dispatch, {
677                 licenseModelId: deltaData.vendorId,
678                 licensingVersion: deltaData.licensingVersion
679             }).then(() => {
680                 ValidationHelper.dataChanged(dispatch, { deltaData, formName });
681                 return Promise.resolve();
682             });
683         } else if (deltaData.vendorId) {
684             ValidationHelper.dataChanged(dispatch, { deltaData, formName });
685             return SoftwareProductActionHelper.loadLicensingVersionsList(
686                 dispatch,
687                 {
688                     licenseModelId: deltaData.vendorId
689                 }
690             ).then(() =>
691                 OnboardingActionHelper.forceBreadCrumbsUpdate(dispatch)
692             );
693         } else {
694             ValidationHelper.dataChanged(dispatch, { deltaData, formName });
695
696             dispatch({
697                 type: licenseAgreementActionTypes.LICENSE_AGREEMENT_LIST_LOADED,
698                 response: { results: [] }
699             });
700
701             dispatch({
702                 type: featureGroupsActionConstants.FEATURE_GROUPS_LIST_LOADED,
703                 response: { results: [] }
704             });
705         }
706     },
707
708     setIsValidityData(dispatch, { isValidityData }) {
709         dispatch({
710             type: actionTypes.softwareProductEditor.IS_VALIDITY_DATA_CHANGED,
711             isValidityData
712         });
713     },
714
715     fetchSoftwareProduct(dispatch, { softwareProductId, version }) {
716         return Promise.all([
717             fetchSoftwareProduct(softwareProductId, version).then(response => {
718                 dispatch({
719                     type: actionTypes.SOFTWARE_PRODUCT_LOADED,
720                     response
721                 });
722                 return response;
723             }),
724             fetchSoftwareProductQuestionnaire(softwareProductId, version).then(
725                 response => {
726                     ValidationHelper.qDataLoaded(dispatch, {
727                         response: {
728                             qdata: response.data
729                                 ? JSON.parse(response.data)
730                                 : {},
731                             qschema: JSON.parse(response.schema)
732                         },
733                         qName: PRODUCT_QUESTIONNAIRE
734                     });
735                 }
736             )
737         ]);
738     },
739
740     manageSubmitAction(dispatch, { softwareProductId, version, isDirty }) {
741         if (isDirty) {
742             const onCommit = comment => {
743                 return this.performVCAction(dispatch, {
744                     softwareProductId,
745                     action: VersionControllerActionsEnum.COMMIT,
746                     version,
747                     comment
748                 }).then(() => {
749                     return this.performSubmitAction(dispatch, {
750                         softwareProductId,
751                         version
752                     });
753                 });
754             };
755             dispatch({
756                 type: modalActionTypes.GLOBAL_MODAL_SHOW,
757                 data: {
758                     modalComponentName: modalContentMapper.COMMIT_COMMENT,
759                     modalComponentProps: {
760                         onCommit,
761                         type: CommitModalType.COMMIT_SUBMIT
762                     },
763                     title: i18n('Commit & Submit')
764                 }
765             });
766             return Promise.resolve(version);
767         }
768         return this.performSubmitAction(dispatch, {
769             softwareProductId,
770             version
771         });
772     },
773
774     performSubmitAction(dispatch, { softwareProductId, version }) {
775         return putSoftwareProductAction(
776             softwareProductId,
777             VersionControllerActionsEnum.SUBMIT,
778             version
779         ).then(
780             () => {
781                 return putSoftwareProductAction(
782                     softwareProductId,
783                     VersionControllerActionsEnum.CREATE_PACKAGE,
784                     version
785                 ).then(() => {
786                     return ItemsHelper.checkItemStatus(dispatch, {
787                         itemId: softwareProductId,
788                         versionId: version.id
789                     }).then(updatedVersion => {
790                         dispatch({
791                             type: modalActionTypes.GLOBAL_MODAL_SUCCESS,
792                             data: {
793                                 title: i18n('Submit Succeeded'),
794                                 msg: i18n(
795                                     'This software product successfully submitted'
796                                 ),
797                                 cancelButtonText: i18n('OK'),
798                                 timeout: 2000
799                             }
800                         });
801                         versionPageActionHelper.fetchVersions(dispatch, {
802                             itemType: itemTypes.SOFTWARE_PRODUCT,
803                             itemId: softwareProductId
804                         });
805                         return Promise.resolve(updatedVersion);
806                     });
807                 });
808             },
809             error => {
810                 dispatch({
811                     type: modalActionTypes.GLOBAL_MODAL_ERROR,
812                     data: {
813                         modalComponentName:
814                             modalContentMapper.SUMBIT_ERROR_RESPONSE,
815                         title: i18n('Submit Failed'),
816                         modalComponentProps: {
817                             validationResponse: error.responseJSON
818                         },
819                         cancelButtonText: i18n('OK')
820                     }
821                 });
822                 return Promise.reject(error.responseJSON);
823             }
824         );
825     },
826
827     performVCAction(dispatch, { softwareProductId, action, version, comment }) {
828         return MergeEditorActionHelper.analyzeSyncResult(dispatch, {
829             itemId: softwareProductId,
830             version
831         }).then(({ inMerge, isDirty, updatedVersion }) => {
832             if (
833                 (updatedVersion.status === versionStatus.CERTIFIED ||
834                     updatedVersion.archivedStatus === itemStatus.ARCHIVED) &&
835                 (action === VersionControllerActionsEnum.COMMIT ||
836                     action === VersionControllerActionsEnum.SYNC)
837             ) {
838                 versionPageActionHelper.fetchVersions(dispatch, {
839                     itemType: itemTypes.SOFTWARE_PRODUCT,
840                     itemId: softwareProductId
841                 });
842                 const msg =
843                     updatedVersion.archivedStatus === itemStatus.ARCHIVED
844                         ? i18n('Item was Archived')
845                         : i18n('Item version already Certified');
846                 dispatch({
847                     type: modalActionTypes.GLOBAL_MODAL_WARNING,
848                     data: {
849                         title: i18n('Commit error'),
850                         msg,
851                         cancelButtonText: i18n('Cancel')
852                     }
853                 });
854                 return Promise.resolve(updatedVersion);
855             }
856             if (!inMerge) {
857                 if (action === VersionControllerActionsEnum.SUBMIT) {
858                     return this.manageSubmitAction(dispatch, {
859                         softwareProductId,
860                         version,
861                         isDirty
862                     });
863                 } else {
864                     let isCallActionValid =
865                         action !== VersionControllerActionsEnum.COMMIT ||
866                         isDirty;
867                     if (isCallActionValid) {
868                         return ItemsHelper.performVCAction({
869                             itemId: softwareProductId,
870                             action,
871                             version,
872                             comment
873                         }).then(() => {
874                             versionPageActionHelper.fetchVersions(dispatch, {
875                                 itemType: itemTypes.LICENSE_MODEL,
876                                 itemId: softwareProductId
877                             });
878                             if (action === VersionControllerActionsEnum.SYNC) {
879                                 return MergeEditorActionHelper.analyzeSyncResult(
880                                     dispatch,
881                                     { itemId: softwareProductId, version }
882                                 ).then(({ updatedVersion }) => {
883                                     return Promise.resolve(updatedVersion);
884                                 });
885                             } else {
886                                 return ItemsHelper.checkItemStatus(dispatch, {
887                                     itemId: softwareProductId,
888                                     versionId: version.id
889                                 });
890                             }
891                         });
892                     } else {
893                         dispatch({
894                             type: modalActionTypes.GLOBAL_MODAL_ERROR,
895                             data: {
896                                 title: i18n('Commit Failed'),
897                                 msg: i18n('There is nothing to commit')
898                             }
899                         });
900                     }
901                 }
902             }
903         });
904     },
905
906     toggleNavigationItems(dispatch, { items, itemIdToExpand }) {
907         let mapOfExpandedIds = getExpandedItemsId(items, itemIdToExpand);
908         dispatch({
909             type: actionTypes.TOGGLE_NAVIGATION_ITEM,
910             mapOfExpandedIds
911         });
912     },
913
914     /** for the next verision */
915     addComponent(dispatch, { softwareProductId, version }) {
916         SoftwareProductComponentsActionHelper.clearComponentCreationData(
917             dispatch
918         );
919         dispatch({
920             type: componentActionTypes.COMPONENT_CREATE_OPEN
921         });
922         dispatch({
923             type: modalActionTypes.GLOBAL_MODAL_SHOW,
924             data: {
925                 modalComponentName: modalContentMapper.COMPONENT_CREATION,
926                 modalComponentProps: { softwareProductId, version },
927                 title: 'Create Virtual Function Component'
928             }
929         });
930     },
931
932     migrateSoftwareProduct(dispatch, { softwareProduct }) {
933         let { id: softwareProductId, version } = softwareProduct;
934         const newVer = version.id;
935         migrateSoftwareProduct(softwareProductId, version).then(() =>
936             ScreensHelper.loadScreen(dispatch, {
937                 screen: enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE,
938                 screenType: screenTypes.SOFTWARE_PRODUCT,
939                 props: {
940                     softwareProductId,
941                     version: { id: newVer, label: newVer }
942                 }
943             })
944         );
945     },
946
947     abortCandidateValidation(dispatch, { softwareProductId, version }) {
948         return abortValidationProcess(softwareProductId, version);
949     }
950 };
951
952 export default SoftwareProductActionHelper;