| /*! |
| * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. |
| * |
| * Licensed under the Apache License, Version 2.0 (the 'License'); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an 'AS IS' BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
| * or implied. See the License for the specific language governing |
| * permissions and limitations under the License. |
| */ |
| import { |
| actionTypes, |
| rules, |
| dataRules, |
| SyncStates |
| } from './MergeEditorConstants.js'; |
| import cloneDeep from 'lodash/cloneDeep.js'; |
| import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js'; |
| import Configuration from 'sdc-app/config/Configuration.js'; |
| import ItemsHelper from '../../common/helpers/ItemsHelper.js'; |
| import { modalContentMapper } from 'sdc-app/common/modal/ModalContentMapper.js'; |
| import { actionTypes as modalActionTypes } from 'nfvo-components/modal/GlobalModalConstants.js'; |
| import i18n from 'nfvo-utils/i18n/i18n.js'; |
| import { optionsInputValues as epOptionsValues } from 'sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsConstants.js'; |
| import { optionsInputValues as laOptionsValues } from 'sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementConstants.js'; |
| import { optionsInputValues as processOptionValues } from 'sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesConstants.js'; |
| import { selectValues as limitSelectValues } from 'sdc-app/onboarding/licenseModel/limits/LimitEditorConstants.js'; |
| import FeatureGroupsActionHelper from 'sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsActionHelper.js'; |
| import LicenseAgreementActionHelper from 'sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementActionHelper.js'; |
| import moment from 'moment'; |
| import { DATE_FORMAT } from 'sdc-app/onboarding/OnboardingConstants.js'; |
| import ScreensHelper from 'sdc-app/common/helpers/ScreensHelper.js'; |
| |
| function softwareProductCategoriesUrl() { |
| const restCatalogPrefix = Configuration.get('restCatalogPrefix'); |
| return `${restCatalogPrefix}/v1/categories/resources/`; |
| } |
| |
| function versionUrl(itemId, versionId) { |
| const restPrefix = Configuration.get('restPrefix'); |
| return `${restPrefix}/v1.0/items/${itemId}/versions/${versionId}`; |
| } |
| |
| function baseUrl(itemId, version, conflictId) { |
| const versionId = version.id; |
| const restPrefix = Configuration.get('restPrefix'); |
| let baseUrl = `${restPrefix}/v1.0/items/${itemId}/versions/${versionId}/conflicts`; |
| return conflictId ? `${baseUrl}/${conflictId}` : baseUrl; |
| } |
| |
| function fetchConflicts({ itemId, version }) { |
| return RestAPIUtil.fetch(`${baseUrl(itemId, version)}`); |
| } |
| |
| function fetchConflictById({ itemId, version, cid }) { |
| return RestAPIUtil.fetch(`${baseUrl(itemId, version, cid)}`); |
| } |
| |
| function resolveConflict({ itemId, version, conflictId, resolution }) { |
| return RestAPIUtil.put(`${baseUrl(itemId, version, conflictId)}`, { |
| resolution |
| }); |
| } |
| |
| function fetchCategories() { |
| return RestAPIUtil.fetch(softwareProductCategoriesUrl()); |
| } |
| |
| function fetchVersion({ vendorId, licensingVersion }) { |
| return RestAPIUtil.fetch(versionUrl(vendorId, licensingVersion)); |
| } |
| |
| function createCategoryStr(data, { categories }) { |
| let { category, subCategory } = data; |
| let foundCat = categories.find(element => element.uniqueId === category); |
| if (!foundCat) { |
| return ''; |
| } |
| |
| let catName = foundCat.name; |
| let foundSub = foundCat.subcategories.find( |
| element => element.uniqueId === subCategory |
| ); |
| if (!foundSub) { |
| return `${catName}`; |
| } |
| |
| let subcatName = foundSub.name; |
| return `${catName} - ${subcatName}`; |
| } |
| |
| function getEnumValues({ enums, list }) { |
| if (!list) { |
| return ''; |
| } |
| return list.map(item => enums.find(el => el.enum === item).title); |
| } |
| |
| const MergeEditorActionHelper = { |
| analyzeSyncResult(dispatch, { itemId, version }) { |
| return ItemsHelper.checkItemStatus(dispatch, { |
| itemId, |
| versionId: version.id |
| }).then(response => { |
| let inMerge = |
| response && |
| response.state && |
| response.state.synchronizationState === SyncStates.MERGE; |
| if (inMerge) { |
| MergeEditorActionHelper.fetchConflicts(dispatch, { |
| itemId, |
| version |
| }).then(() => |
| dispatch({ |
| type: modalActionTypes.GLOBAL_MODAL_SHOW, |
| data: { |
| modalComponentName: modalContentMapper.MERGE_EDITOR, |
| modalClassName: 'merge-editor-modal', |
| title: `${i18n('Merge Required')} - ${ |
| version.description |
| }`, |
| onDeclined: () => { |
| dispatch({ |
| type: modalActionTypes.GLOBAL_MODAL_CLOSE |
| }); |
| }, |
| modalComponentProps: { |
| size: 'lg', |
| type: 'default' |
| } |
| } |
| }) |
| ); |
| } |
| return Promise.resolve({ |
| updatedVersion: response, |
| inMerge, |
| isDirty: response.state.dirty |
| }); |
| }); |
| }, |
| |
| fetchConflicts(dispatch, { itemId, version }) { |
| return fetchConflicts({ itemId, version }).then(data => { |
| dispatch({ |
| type: actionTypes.LOAD_CONFLICTS, |
| data |
| }); |
| return data; |
| }); |
| }, |
| |
| fetchConflict(dispatch, { itemId, version, cid }) { |
| fetchConflictById({ itemId, version, cid }).then(data => { |
| let newData = {}; |
| newData = MergeEditorActionHelper.processConflict(dispatch, { |
| conflict: data, |
| itemId, |
| cid, |
| version |
| }); |
| dispatch({ |
| type: actionTypes.LOAD_CONFLICT, |
| data: newData |
| }); |
| }); |
| }, |
| |
| resolveConflict( |
| dispatch, |
| { itemId, version, conflictId, resolution, currentScreen } |
| ) { |
| resolveConflict({ itemId, version, conflictId, resolution }).then( |
| () => { |
| MergeEditorActionHelper.fetchConflicts(dispatch, { |
| itemId, |
| version |
| }).then(conflicts => { |
| if ( |
| conflicts.conflictInfoList && |
| conflicts.conflictInfoList.length === 0 |
| ) { |
| dispatch({ |
| type: modalActionTypes.GLOBAL_MODAL_CLOSE |
| }); |
| ScreensHelper.loadLandingScreen(dispatch, { |
| previousScreenName: currentScreen.screen, |
| props: currentScreen.props |
| }); |
| ItemsHelper.checkItemStatus(dispatch, { |
| itemId, |
| versionId: version.id |
| }); |
| } |
| }); |
| } |
| ); |
| }, |
| |
| createConflictObject( |
| data, |
| { cid, conflict, dispatch, itemId, version, isYours } |
| ) { |
| let newData = {}; |
| |
| for (let key in data) { |
| if (data.hasOwnProperty(key)) { |
| let value = data[key]; |
| let fieldRule = |
| (dataRules[conflict.type] && |
| dataRules[conflict.type][key]) || |
| dataRules.general[key]; |
| |
| if (fieldRule) { |
| switch (fieldRule.rule) { |
| case rules.SKIP: |
| break; |
| |
| case rules.BOOLEAN: |
| let { trueValue, falseValue } = fieldRule; |
| newData[key] = |
| value === trueValue |
| ? true |
| : value === falseValue ? false : undefined; |
| break; |
| |
| case rules.PARSE: |
| let { moveFields, subFields } = fieldRule; |
| if (moveFields) { |
| let fields = subFields || Object.keys(value); |
| fields.forEach(field => { |
| newData[ |
| field |
| ] = MergeEditorActionHelper.createConflictObject( |
| value[field], |
| { |
| cid, |
| conflict, |
| dispatch, |
| itemId, |
| version, |
| isYours |
| } |
| ); |
| }); |
| } else { |
| newData[ |
| key |
| ] = MergeEditorActionHelper.createConflictObject( |
| value, |
| { |
| cid, |
| conflict, |
| dispatch, |
| itemId, |
| version, |
| isYours |
| } |
| ); |
| } |
| break; |
| |
| case rules.FUNCTION: |
| let { args, functionName } = fieldRule; |
| newData[key] = MergeEditorActionHelper[ |
| functionName |
| ](data, { |
| cid, |
| conflict, |
| dispatch, |
| version, |
| fieldName: key, |
| isYours, |
| itemId, |
| args |
| }); |
| break; |
| |
| default: |
| newData[key] = value; |
| break; |
| } |
| } else { |
| newData[key] = value; |
| } |
| } |
| } |
| |
| return newData; |
| }, |
| |
| getNamesFromIDs( |
| data, |
| { version, cid, dispatch, itemId, fieldName, isYours, args } |
| ) { |
| let idList = data[fieldName] || []; |
| let { fetchFunction, fetchField } = args; |
| |
| let promises = idList.map( |
| id => |
| new Promise(resolve => |
| MergeEditorActionHelper[fetchFunction](dispatch, { |
| licenseModelId: itemId, |
| [fetchField]: id, |
| version |
| }).then(item => resolve(item.name)) |
| ) |
| ); |
| |
| Promise.all(promises).then(fetchedItems => { |
| let yoursOrTheirs = isYours ? 'yoursField' : 'theirsField'; |
| dispatch({ |
| type: actionTypes.DATA_PROCESSED, |
| data: { |
| cid, |
| [yoursOrTheirs]: { name: fieldName, value: fetchedItems } |
| } |
| }); |
| }); |
| |
| return idList; |
| }, |
| |
| getFeatureGroups( |
| data, |
| { version, cid, dispatch, itemId, fieldName, isYours } |
| ) { |
| let featureGroups = data[fieldName] || []; |
| if (!(featureGroups instanceof Array)) { |
| featureGroups = [featureGroups]; |
| } |
| |
| let promises = featureGroups.map( |
| featureGroupId => |
| new Promise(resolve => |
| FeatureGroupsActionHelper.fetchFeatureGroup(dispatch, { |
| licenseModelId: itemId, |
| featureGroupId, |
| version |
| }) |
| .then(featureGroup => resolve(featureGroup.name)) |
| .catch(reason => |
| console.log( |
| `getFeatureGroups Promise rejected ('${reason}')` |
| ) |
| ) |
| ) |
| ); |
| |
| Promise.all(promises).then(fetchedGroups => { |
| let yoursOrTheirs = isYours ? 'yoursField' : 'theirsField'; |
| dispatch({ |
| type: actionTypes.DATA_PROCESSED, |
| data: { |
| cid, |
| [yoursOrTheirs]: { name: fieldName, value: fetchedGroups } |
| } |
| }); |
| }); |
| |
| return featureGroups; |
| }, |
| |
| getLicenseAgreements( |
| data, |
| { version, cid, dispatch, itemId, fieldName, isYours } |
| ) { |
| let licenseAgreements = data[fieldName] || []; |
| if (!(licenseAgreements instanceof Array)) { |
| licenseAgreements = [licenseAgreements]; |
| } |
| |
| let promises = licenseAgreements.map( |
| licenseAgreementId => |
| new Promise(resolve => |
| LicenseAgreementActionHelper.fetchLicenseAgreement( |
| dispatch, |
| { |
| licenseModelId: itemId, |
| licenseAgreementId, |
| version |
| } |
| ) |
| .then(licenseAgreement => |
| resolve(licenseAgreement.name) |
| ) |
| .catch(reason => |
| console.log( |
| `getLicenseAgreements Promise rejected ('${reason}')` |
| ) |
| ) |
| ) |
| ); |
| |
| Promise.all(promises).then(fetchedAgreements => { |
| let yoursOrTheirs = isYours ? 'yoursField' : 'theirsField'; |
| dispatch({ |
| type: actionTypes.DATA_PROCESSED, |
| data: { |
| cid, |
| [yoursOrTheirs]: { |
| name: fieldName, |
| value: fetchedAgreements |
| } |
| } |
| }); |
| }); |
| |
| return licenseAgreements; |
| }, |
| |
| processConflict(dispatch, { conflict, cid, version, itemId }) { |
| let { id, type, yours, theirs } = conflict; |
| |
| let newYours = MergeEditorActionHelper.createConflictObject( |
| cloneDeep(yours), |
| { cid, conflict, dispatch, itemId, version, isYours: true } |
| ); |
| let newTheirs = MergeEditorActionHelper.createConflictObject( |
| cloneDeep(theirs), |
| { cid, conflict, dispatch, itemId, version, isYours: false } |
| ); |
| |
| return { |
| id, |
| type, |
| yours: newYours, |
| theirs: newTheirs |
| }; |
| }, |
| |
| reduceList(data, { fieldName, args }) { |
| let { subField } = args; |
| return data[fieldName].map(el => el[subField]); |
| }, |
| |
| getEnumList({ fieldName }) { |
| const enumLists = { |
| licenseTerm: laOptionsValues.LICENSE_MODEL_TYPE, |
| operationalScope: epOptionsValues.OPERATIONAL_SCOPE, |
| processType: processOptionValues.PROCESS_TYPE, |
| limitType: [ |
| { title: 'Service Provider', enum: 'ServiceProvider' }, |
| { title: 'Vendor', enum: 'Vendor' } |
| ], |
| limitUnit: limitSelectValues.UNIT |
| }; |
| |
| return enumLists[fieldName]; |
| }, |
| |
| getEnumValue(data, { fieldName, args = {} }) { |
| let value = data[fieldName]; |
| let enumValues = MergeEditorActionHelper.getEnumList({ |
| fieldName: args.listName || fieldName |
| }); |
| let enumValue = enumValues.find(el => el.enum === value); |
| |
| return (enumValue && enumValue.title) || value; |
| }, |
| |
| processChoice(data, { fieldName, args = {} }) { |
| let value = data[fieldName]; |
| let enumValues = MergeEditorActionHelper.getEnumList({ |
| fieldName: args.listName || fieldName |
| }); |
| let newValue = |
| value.other || |
| (enumValues && |
| enumValues.find(el => el.enum === value.choice).title) || |
| value.choice; |
| |
| return newValue; |
| }, |
| |
| processChoices(data, { fieldName, args = {} }) { |
| let value = data[fieldName]; |
| let enumValues = MergeEditorActionHelper.getEnumList({ |
| fieldName: args.listName || fieldName |
| }); |
| let newValue = |
| value.other || |
| getEnumValues({ enums: enumValues, list: value.choices }) || |
| value.choices; |
| |
| return newValue; |
| }, |
| |
| convertArrayToObject(data, { fieldName }) { |
| let value = data[fieldName]; |
| let newValue = {}; |
| value.forEach((el, index) => { |
| newValue[index] = el; |
| }); |
| return newValue; |
| }, |
| |
| fetchCategory(data, { cid, isYours, fieldName, dispatch }) { |
| fetchCategories().then(categories => { |
| let value = createCategoryStr(data, { categories }); |
| let yoursOrTheirs = isYours ? 'yoursField' : 'theirsField'; |
| |
| dispatch({ |
| type: actionTypes.DATA_PROCESSED, |
| data: { |
| cid, |
| [yoursOrTheirs]: { name: fieldName, value } |
| } |
| }); |
| }); |
| }, |
| |
| fetchLMVersion(data, { cid, dispatch, isYours }) { |
| let { licensingVersion, vendorId } = data; |
| let yoursOrTheirs = isYours ? 'yoursField' : 'theirsField'; |
| |
| if (licensingVersion) { |
| fetchVersion({ licensingVersion, vendorId }).then(response => { |
| dispatch({ |
| type: actionTypes.DATA_PROCESSED, |
| data: { |
| cid, |
| [yoursOrTheirs]: { |
| name: 'licensingVersion', |
| value: response.name |
| } |
| } |
| }); |
| }); |
| } |
| }, |
| |
| parseDate(data, { fieldName }) { |
| let date = data[fieldName]; |
| return date && moment(date, DATE_FORMAT).format(DATE_FORMAT); |
| } |
| }; |
| |
| export default MergeEditorActionHelper; |