summaryrefslogtreecommitdiffstats
path: root/openecomp-ui/src/sdc-app/common/merge
diff options
context:
space:
mode:
Diffstat (limited to 'openecomp-ui/src/sdc-app/common/merge')
-rw-r--r--openecomp-ui/src/sdc-app/common/merge/MergeEditor.js45
-rw-r--r--openecomp-ui/src/sdc-app/common/merge/MergeEditorActionHelper.js881
-rw-r--r--openecomp-ui/src/sdc-app/common/merge/MergeEditorConstants.js375
-rw-r--r--openecomp-ui/src/sdc-app/common/merge/MergeEditorReducer.js96
-rw-r--r--openecomp-ui/src/sdc-app/common/merge/MergeEditorView.jsx568
5 files changed, 1118 insertions, 847 deletions
diff --git a/openecomp-ui/src/sdc-app/common/merge/MergeEditor.js b/openecomp-ui/src/sdc-app/common/merge/MergeEditor.js
index baf00cf0cf..81f7174623 100644
--- a/openecomp-ui/src/sdc-app/common/merge/MergeEditor.js
+++ b/openecomp-ui/src/sdc-app/common/merge/MergeEditor.js
@@ -13,25 +13,42 @@
* or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
-import {connect} from 'react-redux';
+import { connect } from 'react-redux';
import MergeEditorView from './MergeEditorView.jsx';
import MergeEditorActionHelper from './MergeEditorActionHelper.js';
-export const mapStateToProps = ({mergeEditor, currentScreen}) => {
- let {props} = currentScreen;
- let item = {
- id: props.softwareProductId || props.licenseModelId,
- version: props.version
- };
- return {...mergeEditor, item, currentScreen};
+export const mapStateToProps = ({ mergeEditor, currentScreen }) => {
+ let { props } = currentScreen;
+ let item = {
+ id: props.softwareProductId || props.licenseModelId,
+ version: props.version
+ };
+ return { ...mergeEditor, item, currentScreen };
};
-export const mapActionsToProps = (dispatch) => {
- return {
- fetchConflict: ({cid, itemId, version}) => MergeEditorActionHelper.fetchConflict(dispatch, {itemId, version, cid}),
- onResolveConflict: ({conflictId, resolution, itemId, version, currentScreen}) =>
- MergeEditorActionHelper.resolveConflict(dispatch, {itemId, version, conflictId, resolution, currentScreen})
- };
+export const mapActionsToProps = dispatch => {
+ return {
+ fetchConflict: ({ cid, itemId, version }) =>
+ MergeEditorActionHelper.fetchConflict(dispatch, {
+ itemId,
+ version,
+ cid
+ }),
+ onResolveConflict: ({
+ conflictId,
+ resolution,
+ itemId,
+ version,
+ currentScreen
+ }) =>
+ MergeEditorActionHelper.resolveConflict(dispatch, {
+ itemId,
+ version,
+ conflictId,
+ resolution,
+ currentScreen
+ })
+ };
};
export default connect(mapStateToProps, mapActionsToProps)(MergeEditorView);
diff --git a/openecomp-ui/src/sdc-app/common/merge/MergeEditorActionHelper.js b/openecomp-ui/src/sdc-app/common/merge/MergeEditorActionHelper.js
index 92ec60b999..c54b9feb93 100644
--- a/openecomp-ui/src/sdc-app/common/merge/MergeEditorActionHelper.js
+++ b/openecomp-ui/src/sdc-app/common/merge/MergeEditorActionHelper.js
@@ -13,431 +13,532 @@
* 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 {
+ 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 { 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 { 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 { 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/`;
+ 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}`;
+ 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;
+ 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 fetchConflicts({ itemId, version }) {
+ return RestAPIUtil.fetch(`${baseUrl(itemId, version)}`);
}
-function fetchConflictById({itemId, version, cid}) {
- return RestAPIUtil.fetch(`${baseUrl(itemId, version, cid)}`);
+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 resolveConflict({ itemId, version, conflictId, resolution }) {
+ return RestAPIUtil.put(`${baseUrl(itemId, version, conflictId)}`, {
+ resolution
+ });
}
function fetchCategories() {
- return RestAPIUtil.fetch(softwareProductCategoriesUrl());
+ return RestAPIUtil.fetch(softwareProductCategoriesUrl());
}
-function fetchVersion({vendorId, licensingVersion}) {
- return RestAPIUtil.fetch(versionUrl(vendorId, licensingVersion));
+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 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);
-
+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);
-
- }
-
+ 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;
diff --git a/openecomp-ui/src/sdc-app/common/merge/MergeEditorConstants.js b/openecomp-ui/src/sdc-app/common/merge/MergeEditorConstants.js
index f7f6d4195e..b82d08683f 100644
--- a/openecomp-ui/src/sdc-app/common/merge/MergeEditorConstants.js
+++ b/openecomp-ui/src/sdc-app/common/merge/MergeEditorConstants.js
@@ -17,208 +17,205 @@
import keyMirror from 'nfvo-utils/KeyMirror.js';
export const actionTypes = keyMirror({
- LOAD_CONFLICTS: null,
- ADD_ACTIONS: null,
- LOAD_CONFLICT: null,
- DATA_PROCESSED: null
+ LOAD_CONFLICTS: null,
+ ADD_ACTIONS: null,
+ LOAD_CONFLICT: null,
+ DATA_PROCESSED: null
});
export const rules = {
- SKIP: 'skip',
- PARSE: 'parse',
- FUNCTION: 'function',
- BOOLEAN: 'boolean'
+ SKIP: 'skip',
+ PARSE: 'parse',
+ FUNCTION: 'function',
+ BOOLEAN: 'boolean'
};
export const SyncStates = {
- MERGE : 'Merging',
- OUT_OF_SYNC: 'OutOfSync',
- UP_TO_DATE: 'UpToDate'
+ MERGE: 'Merging',
+ OUT_OF_SYNC: 'OutOfSync',
+ UP_TO_DATE: 'UpToDate'
};
export const ResolutionTypes = {
- YOURS: 'YOURS',
- THEIRS: 'THEIRS'
+ YOURS: 'YOURS',
+ THEIRS: 'THEIRS'
};
export const fileTypes = {
- LKG : 'LicenseKeyGroup',
- VLM : 'VendorLicenseModel',
- EP : 'EntitlementPool',
- FG : 'FeatureGroup',
- LA : 'LicenseAgreement',
- VSP : 'VendorSoftwareProduct',
- LIMIT : 'Limit',
- VSP_Q : 'VSPQuestionnaire',
- COMPONENT : 'Component',
- COMPONENT_Q : 'ComponentQuestionnaire',
- COMPONENT_DEP : 'ComponentDependencies',
- COMPUTE_Q : 'ComputeQuestionnaire',
- COMPUTE : 'Compute',
- COMPUTE_FLAVOR: 'ComputeFlavor',
- NIC : 'Nic',
- NIC_Q : 'NicQuestionnaire',
- IMAGE : 'Image',
- IMAGE_Q : 'ImageQuestionnaire',
- PROCESS : 'Process',
- DEPLOYMENT_FLAVOR : 'DeploymentFlavor',
- VENDOR : 'Vendor',
- NETWORK : 'Network',
- ORCHESTRATION_TEMPLATE_CANDIDATE : 'OrchestrationTemplateCandidate'
+ LKG: 'LicenseKeyGroup',
+ VLM: 'VendorLicenseModel',
+ EP: 'EntitlementPool',
+ FG: 'FeatureGroup',
+ LA: 'LicenseAgreement',
+ VSP: 'VendorSoftwareProduct',
+ LIMIT: 'Limit',
+ VSP_Q: 'VSPQuestionnaire',
+ COMPONENT: 'Component',
+ COMPONENT_Q: 'ComponentQuestionnaire',
+ COMPONENT_DEP: 'ComponentDependencies',
+ COMPUTE_Q: 'ComputeQuestionnaire',
+ COMPUTE: 'Compute',
+ COMPUTE_FLAVOR: 'ComputeFlavor',
+ NIC: 'Nic',
+ NIC_Q: 'NicQuestionnaire',
+ IMAGE: 'Image',
+ IMAGE_Q: 'ImageQuestionnaire',
+ PROCESS: 'Process',
+ DEPLOYMENT_FLAVOR: 'DeploymentFlavor',
+ VENDOR: 'Vendor',
+ NETWORK: 'Network',
+ ORCHESTRATION_TEMPLATE_CANDIDATE: 'OrchestrationTemplateCandidate'
};
export const dataRules = {
- general: {
- id: {
- rule: rules.SKIP
- },
- questionareData: {
- rule: rules.PARSE,
- moveFields: true
- },
- startDate: {
- rule: rules.FUNCTION,
- functionName: 'parseDate'
- },
- expiryDate: {
- rule: rules.FUNCTION,
- functionName: 'parseDate'
- },
- featureGroups: {
- rule: rules.FUNCTION,
- functionName: 'reduceList',
- args: {subField: 'name'}
- },
- licenseKeyGroups: {
- rule: rules.FUNCTION,
- functionName: 'reduceList',
- args: {subField: 'name'}
- },
- entitlementPools: {
- rule: rules.FUNCTION,
- functionName: 'reduceList',
- args: {subField: 'name'}
- },
- },
- [fileTypes.COMPONENT] : {
- },
- [fileTypes.COMPUTE_FLAVOR] : {
- associatedToDeploymentFlavor: {
- rule: rules.BOOLEAN,
- trueValue: 'true'
- }
- },
- [fileTypes.COMPUTE_Q] : {
- },
- [fileTypes.COMPONENT_Q] : {
- isComponentMandatory: {
- rule: rules.BOOLEAN,
- trueValue: 'YES',
- falseValue: 'NO'
- }
- },
- [fileTypes.EP] : {
- referencingFeatureGroups: {
- rule: rules.SKIP,
- functionName: 'getFeatureGroups'
- },
- operationalScope: {
- rule: rules.FUNCTION,
- functionName: 'processChoices'
- },
- },
- [fileTypes.FG] : {
- referencingLicenseAgreements: {
- rule: rules.SKIP,
- functionName: 'getLicenseAgreements'
- }
- },
- [fileTypes.LA] : {
- licenseTerm : {
- rule: rules.FUNCTION,
- functionName: 'processChoice'
- }
- },
- [fileTypes.LIMIT] : {
- type: {
- rule: rules.FUNCTION,
- functionName: 'getEnumValue',
- args: {listName: 'limitType'}
- },
- unit: {
- rule: rules.FUNCTION,
- functionName: 'getEnumValue',
- args: {listName: 'limitUnit'}
- }
- },
- [fileTypes.LKG] : {
- operationalScope: {
- rule: rules.FUNCTION,
- functionName: 'processChoices'
- },
- referencingFeatureGroups: {
- rule: rules.SKIP,
- functionName: 'getFeatureGroups'
- },
- },
- [fileTypes.NIC] : {
- networkId: {
- rule: rules.SKIP
- }
- },
- [fileTypes.NIC_Q] : {
- },
- [fileTypes.PROCESS] : {
- type: {
- rule: rules.FUNCTION,
- functionName: 'getEnumValue',
- args: {listName: 'processType'}
- }
- },
- [fileTypes.VLM] : {
- iconRef: {
- rule: rules.SKIP
- }
- },
- [fileTypes.VSP] : {
- vendorId: {
- rule: rules.SKIP
- },
- onboardingMethod: {
- rule: rules.SKIP
- },
- validationData: {
- rule: rules.SKIP
- },
- isOldVersion: {
- rule: rules.SKIP
- },
- licensingVersion: {
- rule: rules.FUNCTION,
- functionName: 'fetchLMVersion'
- },
- category: {
- rule: rules.FUNCTION,
- functionName: 'fetchCategory'
- },
- subCategory: {
- rule: rules.SKIP
- },
- },
- [fileTypes.VSP_Q] : {
- affinityData: {
- rule: rules.SKIP
- },
- storageReplicationAcrossRegion: {
- rule: rules.BOOLEAN,
- trueValue: 'true',
- falseValue: 'false'
- }
- },
- [fileTypes.ORCHESTRATION_TEMPLATE_CANDIDATE] : {
- modules: {
- rule: rules.FUNCTION,
- functionName: 'convertArrayToObject'
- },
- },
+ general: {
+ id: {
+ rule: rules.SKIP
+ },
+ questionareData: {
+ rule: rules.PARSE,
+ moveFields: true
+ },
+ startDate: {
+ rule: rules.FUNCTION,
+ functionName: 'parseDate'
+ },
+ expiryDate: {
+ rule: rules.FUNCTION,
+ functionName: 'parseDate'
+ },
+ featureGroups: {
+ rule: rules.FUNCTION,
+ functionName: 'reduceList',
+ args: { subField: 'name' }
+ },
+ licenseKeyGroups: {
+ rule: rules.FUNCTION,
+ functionName: 'reduceList',
+ args: { subField: 'name' }
+ },
+ entitlementPools: {
+ rule: rules.FUNCTION,
+ functionName: 'reduceList',
+ args: { subField: 'name' }
+ }
+ },
+ [fileTypes.COMPONENT]: {},
+ [fileTypes.COMPUTE_FLAVOR]: {
+ associatedToDeploymentFlavor: {
+ rule: rules.BOOLEAN,
+ trueValue: 'true'
+ }
+ },
+ [fileTypes.COMPUTE_Q]: {},
+ [fileTypes.COMPONENT_Q]: {
+ isComponentMandatory: {
+ rule: rules.BOOLEAN,
+ trueValue: 'YES',
+ falseValue: 'NO'
+ }
+ },
+ [fileTypes.EP]: {
+ referencingFeatureGroups: {
+ rule: rules.SKIP,
+ functionName: 'getFeatureGroups'
+ },
+ operationalScope: {
+ rule: rules.FUNCTION,
+ functionName: 'processChoices'
+ }
+ },
+ [fileTypes.FG]: {
+ referencingLicenseAgreements: {
+ rule: rules.SKIP,
+ functionName: 'getLicenseAgreements'
+ }
+ },
+ [fileTypes.LA]: {
+ licenseTerm: {
+ rule: rules.FUNCTION,
+ functionName: 'processChoice'
+ }
+ },
+ [fileTypes.LIMIT]: {
+ type: {
+ rule: rules.FUNCTION,
+ functionName: 'getEnumValue',
+ args: { listName: 'limitType' }
+ },
+ unit: {
+ rule: rules.FUNCTION,
+ functionName: 'getEnumValue',
+ args: { listName: 'limitUnit' }
+ }
+ },
+ [fileTypes.LKG]: {
+ operationalScope: {
+ rule: rules.FUNCTION,
+ functionName: 'processChoices'
+ },
+ referencingFeatureGroups: {
+ rule: rules.SKIP,
+ functionName: 'getFeatureGroups'
+ }
+ },
+ [fileTypes.NIC]: {
+ networkId: {
+ rule: rules.SKIP
+ }
+ },
+ [fileTypes.NIC_Q]: {},
+ [fileTypes.PROCESS]: {
+ type: {
+ rule: rules.FUNCTION,
+ functionName: 'getEnumValue',
+ args: { listName: 'processType' }
+ }
+ },
+ [fileTypes.VLM]: {
+ iconRef: {
+ rule: rules.SKIP
+ }
+ },
+ [fileTypes.VSP]: {
+ vendorId: {
+ rule: rules.SKIP
+ },
+ onboardingMethod: {
+ rule: rules.SKIP
+ },
+ validationData: {
+ rule: rules.SKIP
+ },
+ isOldVersion: {
+ rule: rules.SKIP
+ },
+ licensingVersion: {
+ rule: rules.FUNCTION,
+ functionName: 'fetchLMVersion'
+ },
+ category: {
+ rule: rules.FUNCTION,
+ functionName: 'fetchCategory'
+ },
+ subCategory: {
+ rule: rules.SKIP
+ }
+ },
+ [fileTypes.VSP_Q]: {
+ affinityData: {
+ rule: rules.SKIP
+ },
+ storageReplicationAcrossRegion: {
+ rule: rules.BOOLEAN,
+ trueValue: 'true',
+ falseValue: 'false'
+ }
+ },
+ [fileTypes.ORCHESTRATION_TEMPLATE_CANDIDATE]: {
+ modules: {
+ rule: rules.FUNCTION,
+ functionName: 'convertArrayToObject'
+ }
+ }
};
diff --git a/openecomp-ui/src/sdc-app/common/merge/MergeEditorReducer.js b/openecomp-ui/src/sdc-app/common/merge/MergeEditorReducer.js
index 6985fcfaca..1630849b64 100644
--- a/openecomp-ui/src/sdc-app/common/merge/MergeEditorReducer.js
+++ b/openecomp-ui/src/sdc-app/common/merge/MergeEditorReducer.js
@@ -13,54 +13,54 @@
* or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
-import {actionTypes} from './MergeEditorConstants.js';
+import { actionTypes } from './MergeEditorConstants.js';
export default (state = [], action) => {
- switch (action.type) {
- case actionTypes.LOAD_CONFLICT: {
- let cdata = {...action.data};
- // let data = state.conflicts ? {...state.conflicts.data} : {} ;
- // data[cdata.id] = cdata;
- let conflicts = state.conflicts ? {...state.conflicts} : {};
- conflicts[cdata.id] = cdata;
- return {
- ...state,
- conflicts
- };
- }
- case actionTypes.DATA_PROCESSED: {
- let conflicts = {...state.conflicts};
- let {data} = action;
- if (data && data.cid) {
- let yours = {...conflicts[data.cid].yours};
- let theirs = {...conflicts[data.cid].theirs};
- let {yoursField, theirsField} = data;
- if (yoursField) {
- yours[yoursField.name] = yoursField.value;
- conflicts[data.cid].yours = yours;
- }
- if (theirsField) {
- theirs[theirsField.name] = theirsField.value;
- conflicts[data.cid].theirs = theirs;
- }
- }
- return {
- ...state,
- conflicts: {
- ...conflicts
- }
- };
- }
- case actionTypes.LOAD_CONFLICTS:
- let conflictFiles = [];
- if (action.data) {
- conflictFiles = [...action.data.conflictInfoList];
- }
- return {
- inMerge: conflictFiles.length > 0,
- conflictFiles
- };
- default:
- return state;
- }
+ switch (action.type) {
+ case actionTypes.LOAD_CONFLICT: {
+ let cdata = { ...action.data };
+ // let data = state.conflicts ? {...state.conflicts.data} : {} ;
+ // data[cdata.id] = cdata;
+ let conflicts = state.conflicts ? { ...state.conflicts } : {};
+ conflicts[cdata.id] = cdata;
+ return {
+ ...state,
+ conflicts
+ };
+ }
+ case actionTypes.DATA_PROCESSED: {
+ let conflicts = { ...state.conflicts };
+ let { data } = action;
+ if (data && data.cid) {
+ let yours = { ...conflicts[data.cid].yours };
+ let theirs = { ...conflicts[data.cid].theirs };
+ let { yoursField, theirsField } = data;
+ if (yoursField) {
+ yours[yoursField.name] = yoursField.value;
+ conflicts[data.cid].yours = yours;
+ }
+ if (theirsField) {
+ theirs[theirsField.name] = theirsField.value;
+ conflicts[data.cid].theirs = theirs;
+ }
+ }
+ return {
+ ...state,
+ conflicts: {
+ ...conflicts
+ }
+ };
+ }
+ case actionTypes.LOAD_CONFLICTS:
+ let conflictFiles = [];
+ if (action.data) {
+ conflictFiles = [...action.data.conflictInfoList];
+ }
+ return {
+ inMerge: conflictFiles.length > 0,
+ conflictFiles
+ };
+ default:
+ return state;
+ }
};
diff --git a/openecomp-ui/src/sdc-app/common/merge/MergeEditorView.jsx b/openecomp-ui/src/sdc-app/common/merge/MergeEditorView.jsx
index 34d86419e7..a7e36a39fc 100644
--- a/openecomp-ui/src/sdc-app/common/merge/MergeEditorView.jsx
+++ b/openecomp-ui/src/sdc-app/common/merge/MergeEditorView.jsx
@@ -24,233 +24,389 @@ import GridItem from 'nfvo-components/grid/GridItem.jsx';
import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js';
import Radio from 'sdc-ui/lib/react/Radio.js';
import equal from 'deep-equal';
-import {ResolutionTypes} from './MergeEditorConstants.js';
+import { ResolutionTypes } from './MergeEditorConstants.js';
-class ConflictCategory extends React.Component {
- state = {
- resolution: ResolutionTypes.YOURS
- };
+class ConflictCategory extends React.Component {
+ state = {
+ resolution: ResolutionTypes.YOURS
+ };
- getTitle(conflictType, conflictName) {
- if (typeof conflictName === 'undefined' || conflictType === conflictName) {
- return i18n(conflictType);
- } else {
- return `${i18n(conflictType)}: ${conflictName}`;
- }
- }
+ getTitle(conflictType, conflictName) {
+ if (
+ typeof conflictName === 'undefined' ||
+ conflictType === conflictName
+ ) {
+ return i18n(conflictType);
+ } else {
+ return `${i18n(conflictType)}: ${conflictName}`;
+ }
+ }
- render() {
- let {collapseExpand, conflict: {id: conflictId, type, name}, isCollapsed, item: {id: itemId, version}, onResolveConflict} = this.props;
- let {resolution} = this.state;
- const iconClass = isCollapsed ? 'merge-chevron' : 'merge-chevron right';
+ render() {
+ let {
+ collapseExpand,
+ conflict: { id: conflictId, type, name },
+ isCollapsed,
+ item: { id: itemId, version },
+ onResolveConflict
+ } = this.props;
+ let { resolution } = this.state;
+ const iconClass = isCollapsed ? 'merge-chevron' : 'merge-chevron right';
- return (
- <div key={'conflictCategory_' + conflictId} >
- <GridSection className='conflict-section'>
- <GridItem >
- <div className='collapsible-section' onClick={collapseExpand}>
- <SVGIcon name={isCollapsed ? 'chevronDown' : 'chevronUp'} iconClassName={iconClass} />
- <div className='conflict-title'>{this.getTitle(type, name)}</div>
- </div>
- </GridItem>
- <GridItem className='yours'>
- <Radio name={'radio_' + conflictId} checked={resolution === ResolutionTypes.YOURS} value='yours'
- onChange={() => this.setState({resolution: ResolutionTypes.YOURS})} data-test-id={'radio_' + conflictId + '_yours'} />
- </GridItem>
- <GridItem className='theirs'>
- <Radio name={'radio_' + conflictId} checked={resolution === ResolutionTypes.THEIRS} value='theirs'
- onChange={() => this.setState({resolution: ResolutionTypes.THEIRS})} data-test-id={'radio_' + conflictId + '_theirs'} /></GridItem>
- <GridItem className='resolve'>
- <Button className='conflict-resolve-btn' btnType='outline' color='gray'
- onClick={() => onResolveConflict({conflictId, resolution, itemId, version})}>
- {i18n('Resolve')}
- </Button>
- </GridItem>
- </GridSection>
- <div>
- {isCollapsed && this.props.children}
- </div>
- </div>
- );
- }
-
-};
-
-class TextCompare extends React.Component {
- render() {
- // let rand = Math.random() * (3000 - 1) + 1;
- let {yours, theirs, field, type, isObjName, conflictsOnly} = this.props;
- let typeYours = typeof yours;
- let typeTheirs = typeof theirs;
+ return (
+ <div key={'conflictCategory_' + conflictId}>
+ <GridSection className="conflict-section">
+ <GridItem>
+ <div
+ className="collapsible-section"
+ onClick={collapseExpand}>
+ <SVGIcon
+ name={isCollapsed ? 'chevronDown' : 'chevronUp'}
+ iconClassName={iconClass}
+ />
+ <div className="conflict-title">
+ {this.getTitle(type, name)}
+ </div>
+ </div>
+ </GridItem>
+ <GridItem className="yours">
+ <Radio
+ name={'radio_' + conflictId}
+ checked={resolution === ResolutionTypes.YOURS}
+ value="yours"
+ onChange={() =>
+ this.setState({
+ resolution: ResolutionTypes.YOURS
+ })
+ }
+ data-test-id={'radio_' + conflictId + '_yours'}
+ />
+ </GridItem>
+ <GridItem className="theirs">
+ <Radio
+ name={'radio_' + conflictId}
+ checked={resolution === ResolutionTypes.THEIRS}
+ value="theirs"
+ onChange={() =>
+ this.setState({
+ resolution: ResolutionTypes.THEIRS
+ })
+ }
+ data-test-id={'radio_' + conflictId + '_theirs'}
+ />
+ </GridItem>
+ <GridItem className="resolve">
+ <Button
+ className="conflict-resolve-btn"
+ btnType="outline"
+ color="gray"
+ onClick={() =>
+ onResolveConflict({
+ conflictId,
+ resolution,
+ itemId,
+ version
+ })
+ }>
+ {i18n('Resolve')}
+ </Button>
+ </GridItem>
+ </GridSection>
+ <div>{isCollapsed && this.props.children}</div>
+ </div>
+ );
+ }
+}
- let parsedType = `${type}/${field}`.replace(/\/[0-9]+/g,'/index');
- let level = type.split('/').length;
+class TextCompare extends React.Component {
+ render() {
+ // let rand = Math.random() * (3000 - 1) + 1;
+ let {
+ yours,
+ theirs,
+ field,
+ type,
+ isObjName,
+ conflictsOnly
+ } = this.props;
+ let typeYours = typeof yours;
+ let typeTheirs = typeof theirs;
- if (typeYours === 'boolean' || typeTheirs === 'boolean') {
- yours = yours ? i18n('Yes') : i18n('No');
- theirs = theirs ? i18n('Yes') : i18n('No');
- }
+ let parsedType = `${type}/${field}`.replace(/\/[0-9]+/g, '/index');
+ let level = type.split('/').length;
+ if (typeYours === 'boolean' || typeTheirs === 'boolean') {
+ yours = yours ? i18n('Yes') : i18n('No');
+ theirs = theirs ? i18n('Yes') : i18n('No');
+ }
- /*if ((typeYours !== 'string' && typeYours !== 'undefined') || (typeTheirs !== 'string' && typeTheirs !== 'undefined')) {
+ /*if ((typeYours !== 'string' && typeYours !== 'undefined') || (typeTheirs !== 'string' && typeTheirs !== 'undefined')) {
return (<div className='merge-editor-text-field field-error'>{field} cannot be parsed for display</div>);
}*/
- let isDiff = yours !== theirs;
- if (!isObjName &&
- ((!isDiff && conflictsOnly) ||
- (yours === '' && theirs === '') ||
- (typeYours === 'undefined' && typeTheirs === 'undefined')
- )
- ) {
- return null;
- }
+ let isDiff = yours !== theirs;
+ if (
+ !isObjName &&
+ ((!isDiff && conflictsOnly) ||
+ (yours === '' && theirs === '') ||
+ (typeYours === 'undefined' && typeTheirs === 'undefined'))
+ ) {
+ return null;
+ }
- return (
- <GridSection className={isDiff ? 'merge-editor-text-field diff' : 'merge-editor-text-field'}>
- <GridItem className='field-col grid-col-title' stretch>
- <div className={`field ${isDiff ? 'diff' : ''} field-name level-${level} ${isObjName ? 'field-object-name' : ''}`}>
- {i18n(parsedType)}
- </div>
- </GridItem>
- <GridItem className='field-col grid-col-yours' stretch>
- <div className={`field field-yours ${!yours ? 'empty-field' : ''}`} >{yours || (isObjName ? '' : '━━')}</div>
- </GridItem>
- <GridItem className='field-col grid-col-theirs' stretch>
- <div className={`field field-theirs ${!theirs ? 'empty-field' : ''}`}>{theirs || (isObjName ? '' : '━━')}</div>
- </GridItem>
- <GridItem stretch/>
- </GridSection>
- );
- }
-};
+ return (
+ <GridSection
+ className={
+ isDiff
+ ? 'merge-editor-text-field diff'
+ : 'merge-editor-text-field'
+ }>
+ <GridItem className="field-col grid-col-title" stretch>
+ <div
+ className={`field ${
+ isDiff ? 'diff' : ''
+ } field-name level-${level} ${
+ isObjName ? 'field-object-name' : ''
+ }`}>
+ {i18n(parsedType)}
+ </div>
+ </GridItem>
+ <GridItem className="field-col grid-col-yours" stretch>
+ <div
+ className={`field field-yours ${
+ !yours ? 'empty-field' : ''
+ }`}>
+ {yours || (isObjName ? '' : '━━')}
+ </div>
+ </GridItem>
+ <GridItem className="field-col grid-col-theirs" stretch>
+ <div
+ className={`field field-theirs ${
+ !theirs ? 'empty-field' : ''
+ }`}>
+ {theirs || (isObjName ? '' : '━━')}
+ </div>
+ </GridItem>
+ <GridItem stretch />
+ </GridSection>
+ );
+ }
+}
class MergeEditorView extends React.Component {
- state = {
- collapsingSections: {},
- conflictsOnly: false
- };
+ state = {
+ collapsingSections: {},
+ conflictsOnly: false
+ };
- render() {
- let {conflicts, item, conflictFiles, onResolveConflict, currentScreen, resolution} = this.props;
+ render() {
+ let {
+ conflicts,
+ item,
+ conflictFiles,
+ onResolveConflict,
+ currentScreen,
+ resolution
+ } = this.props;
- return (
- <div className='merge-editor'>
- {conflictFiles && this.renderConflictTableTitles()}
- <div className='merge-editor-body'>
- {conflictFiles && conflictFiles.sort((a, b) => a.type > b.type).map(file => (
- <ConflictCategory key={'conflict_' + file.id} conflict={file} item={item} isCollapsed={this.state.collapsingSections[file.id]}
- collapseExpand={()=>{this.updateCollapseState(file.id);}}
- onResolveConflict={cDetails => onResolveConflict({...cDetails, currentScreen})}>
- {(conflicts && conflicts[file.id]) &&
- this.getUnion(conflicts[file.id].yours, conflicts[file.id].theirs).map(field => {
- return this.renderField(field, file, conflicts[file.id].yours[field], conflicts[file.id].theirs[field], resolution);
- })}
- </ConflictCategory>))}
- </div>
- </div>);
- }
+ return (
+ <div className="merge-editor">
+ {conflictFiles && this.renderConflictTableTitles()}
+ <div className="merge-editor-body">
+ {conflictFiles &&
+ conflictFiles
+ .sort((a, b) => a.type > b.type)
+ .map(file => (
+ <ConflictCategory
+ key={'conflict_' + file.id}
+ conflict={file}
+ item={item}
+ isCollapsed={
+ this.state.collapsingSections[file.id]
+ }
+ collapseExpand={() => {
+ this.updateCollapseState(file.id);
+ }}
+ onResolveConflict={cDetails =>
+ onResolveConflict({
+ ...cDetails,
+ currentScreen
+ })
+ }>
+ {conflicts &&
+ conflicts[file.id] &&
+ this.getUnion(
+ conflicts[file.id].yours,
+ conflicts[file.id].theirs
+ ).map(field => {
+ return this.renderField(
+ field,
+ file,
+ conflicts[file.id].yours[field],
+ conflicts[file.id].theirs[
+ field
+ ],
+ resolution
+ );
+ })}
+ </ConflictCategory>
+ ))}
+ </div>
+ </div>
+ );
+ }
- renderConflictTableTitles()
- {
- return (<GridSection className='conflict-titles-section'>
- <GridItem>
- {i18n('Page')}
- </GridItem>
- <GridItem className='yours'>
- {i18n('Local (Me)')}
- </GridItem>
- <GridItem className='theirs'>
- {i18n('Last Committed')}
- </GridItem>
- <GridItem className='resolve'>
- <Input
- label={i18n('Show Conflicts Only')}
- type='checkbox'
- value={this.state.conflictsOnly}
- onChange={e => this.setState({conflictsOnly: e}) } />
- </GridItem>
- </GridSection>);
- }
- // <Checkbox
- // label={i18n('Show Conflicts Only')}
- // value={this.state.conflictsOnly}
- // checked={this.state.conflictsOnly}
- // onChange={checked => this.setState({conflictsOnly: checked})} />
+ renderConflictTableTitles() {
+ return (
+ <GridSection className="conflict-titles-section">
+ <GridItem>{i18n('Page')}</GridItem>
+ <GridItem className="yours">{i18n('Local (Me)')}</GridItem>
+ <GridItem className="theirs">{i18n('Last Committed')}</GridItem>
+ <GridItem className="resolve">
+ <Input
+ label={i18n('Show Conflicts Only')}
+ type="checkbox"
+ value={this.state.conflictsOnly}
+ onChange={e => this.setState({ conflictsOnly: e })}
+ />
+ </GridItem>
+ </GridSection>
+ );
+ }
+ // <Checkbox
+ // label={i18n('Show Conflicts Only')}
+ // value={this.state.conflictsOnly}
+ // checked={this.state.conflictsOnly}
+ // onChange={checked => this.setState({conflictsOnly: checked})} />
- renderObjects(yours, theirs, fileType, field, id, resolution) {
- if (equal(yours, theirs)) {
- return;
- }
- let {conflictsOnly} = this.state;
- return (
- <div key={`obj_${fileType}/${field}_${id}`}>
- <TextCompare field={field} type={fileType} conflictsOnly={conflictsOnly} yours='' theirs='' isObjName resolution={resolution} />
- <div className='field-objects'>
- <div>
- {this.getUnion(yours, theirs).map(key =>
- this.renderField(
- key,
- {type: `${fileType}/${field}`, id},
- yours && yours[key],
- theirs && theirs[key]
- )
- )}
- </div>
- </div>
- </div>
- );
- }
+ renderObjects(yours, theirs, fileType, field, id, resolution) {
+ if (equal(yours, theirs)) {
+ return;
+ }
+ let { conflictsOnly } = this.state;
+ return (
+ <div key={`obj_${fileType}/${field}_${id}`}>
+ <TextCompare
+ field={field}
+ type={fileType}
+ conflictsOnly={conflictsOnly}
+ yours=""
+ theirs=""
+ isObjName
+ resolution={resolution}
+ />
+ <div className="field-objects">
+ <div>
+ {this.getUnion(yours, theirs).map(key =>
+ this.renderField(
+ key,
+ { type: `${fileType}/${field}`, id },
+ yours && yours[key],
+ theirs && theirs[key]
+ )
+ )}
+ </div>
+ </div>
+ </div>
+ );
+ }
- renderList(yours = [], theirs = [], type, field, id, resolution) {
- let theirsList = theirs.join(', ');
- let yoursList = yours.join(', ');
- let {conflictsOnly} = this.state;
- return (<TextCompare key={'text_' + id + '_' + field}
- field={field} type={type} yours={yoursList} theirs={theirsList} conflictsOnly={conflictsOnly} resolution={resolution} />);
- }
+ renderList(yours = [], theirs = [], type, field, id, resolution) {
+ let theirsList = theirs.join(', ');
+ let yoursList = yours.join(', ');
+ let { conflictsOnly } = this.state;
+ return (
+ <TextCompare
+ key={'text_' + id + '_' + field}
+ field={field}
+ type={type}
+ yours={yoursList}
+ theirs={theirsList}
+ conflictsOnly={conflictsOnly}
+ resolution={resolution}
+ />
+ );
+ }
- renderField(field, file, yours, theirs, resolution) {
- if (yours) {
- if (Array.isArray(yours)) {
- return this.renderList(yours, theirs, file.type, field, file.id, resolution);
- }
- else if (typeof yours === 'object') {
- return this.renderObjects(yours, theirs, file.type, field, file.id, resolution);
- }
- } else if (theirs) {
- if (Array.isArray(theirs)) {
- return this.renderList(yours, theirs, file.type, field, file.id, resolution);
- }
- else if (typeof theirs === 'object') {
- return this.renderObjects(yours, theirs, file.type, field, file.id, resolution);
- }
- }
- let {conflictsOnly} = this.state;
- return (<TextCompare key={'text_' + file.id + '_' + field} resolution={resolution}
- field={field} type={file.type} yours={yours} theirs={theirs} conflictsOnly={conflictsOnly} />);
- }
+ renderField(field, file, yours, theirs, resolution) {
+ if (yours) {
+ if (Array.isArray(yours)) {
+ return this.renderList(
+ yours,
+ theirs,
+ file.type,
+ field,
+ file.id,
+ resolution
+ );
+ } else if (typeof yours === 'object') {
+ return this.renderObjects(
+ yours,
+ theirs,
+ file.type,
+ field,
+ file.id,
+ resolution
+ );
+ }
+ } else if (theirs) {
+ if (Array.isArray(theirs)) {
+ return this.renderList(
+ yours,
+ theirs,
+ file.type,
+ field,
+ file.id,
+ resolution
+ );
+ } else if (typeof theirs === 'object') {
+ return this.renderObjects(
+ yours,
+ theirs,
+ file.type,
+ field,
+ file.id,
+ resolution
+ );
+ }
+ }
+ let { conflictsOnly } = this.state;
+ return (
+ <TextCompare
+ key={'text_' + file.id + '_' + field}
+ resolution={resolution}
+ field={field}
+ type={file.type}
+ yours={yours}
+ theirs={theirs}
+ conflictsOnly={conflictsOnly}
+ />
+ );
+ }
- getUnion(yours = {},theirs = {}) {
- let yoursKeys = Object.keys(yours);
- let theirsKeys = Object.keys(theirs);
- let myUn = union(yoursKeys, theirsKeys);
- return myUn;//.sort((a, b) => a > b);
- }
+ getUnion(yours = {}, theirs = {}) {
+ let yoursKeys = Object.keys(yours);
+ let theirsKeys = Object.keys(theirs);
+ let myUn = union(yoursKeys, theirsKeys);
+ return myUn; //.sort((a, b) => a > b);
+ }
- updateCollapseState(conflictId) {
- const {fetchConflict, item: {id: itemId, version}, /*conflicts*/} = this.props;
- let isCollapsed = this.state.collapsingSections[conflictId];
- // if (!isCollapsed && !(conflicts && conflictId in conflicts)) {
- if (!isCollapsed) {
- fetchConflict({cid: conflictId, itemId, version});
- }
- this.setState({
- collapsingSections: {
- ...this.state.collapsingSections,
- [conflictId]: !isCollapsed
- }
- });
- }
+ updateCollapseState(conflictId) {
+ const {
+ fetchConflict,
+ item: { id: itemId, version } /*conflicts*/
+ } = this.props;
+ let isCollapsed = this.state.collapsingSections[conflictId];
+ // if (!isCollapsed && !(conflicts && conflictId in conflicts)) {
+ if (!isCollapsed) {
+ fetchConflict({ cid: conflictId, itemId, version });
+ }
+ this.setState({
+ collapsingSections: {
+ ...this.state.collapsingSections,
+ [conflictId]: !isCollapsed
+ }
+ });
+ }
}
export default MergeEditorView;