@esri/solution-common 1.3.14 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -19,7 +19,7 @@
19
19
  * @module featureServiceHelpers
20
20
  */
21
21
  export { queryFeatures as rest_queryFeatures, addFeatures as rest_addFeatures } from "@esri/arcgis-rest-feature-layer";
22
- import { IDependency, IItemTemplate, INumberValuePair, UserSession } from "./interfaces";
22
+ import { IDependency, IFeatureServiceProperties, IItemTemplate, INumberValuePair, UserSession } from "./interfaces";
23
23
  /**
24
24
  * Templatize the ID, url, field references ect
25
25
  *
@@ -46,10 +46,18 @@ export declare function deleteViewProps(layer: any): void;
46
46
  *
47
47
  * @param layer The data layer instance with field name references within
48
48
  * @param fieldInfos the object that stores the cached field infos
49
- * @param isPortal Controls what properties should be removed.
50
49
  * @returns An updated instance of the fieldInfos
51
50
  */
52
- export declare function cacheFieldInfos(layer: any, fieldInfos: any, isPortal: boolean): any;
51
+ export declare function cacheFieldInfos(layer: any, fieldInfos: any): any;
52
+ /**
53
+ * Cache the stored contingent values so we can add them in subsequent addToDef calls
54
+ *
55
+ * @param id The layer id for the associated values to be stored with
56
+ * @param fieldInfos The object that stores the cached field infos
57
+ * @param itemTemplate The current itemTemplate being processed
58
+ * @returns An updated instance of the fieldInfos
59
+ */
60
+ export declare function cacheContingentValues(id: string, fieldInfos: any, itemTemplate: IItemTemplate): any;
53
61
  /**
54
62
  * Helper function to cache a single property into the fieldInfos object
55
63
  * This property will be removed from the layer instance.
@@ -139,6 +147,18 @@ export declare function updateSettingsFieldInfos(itemTemplate: IItemTemplate, se
139
147
  * @private
140
148
  */
141
149
  export declare function updateTemplateForInvalidDesignations(template: IItemTemplate, authentication: UserSession): Promise<IItemTemplate>;
150
+ /**
151
+ * Get the contingent values for each layer in the service.
152
+ * Remove key props that cannot be included with the addToDef call on deploy.
153
+ * Store the values alongside other key feature service properties in the template
154
+ *
155
+ * @param properties the current feature services properties
156
+ * @param adminUrl the current feature service url
157
+ * @param authentication Credentials for the request to AGOL
158
+ * @returns A promise that will resolve when the contingent values have been fetched.
159
+ * This function will update the provided properties argument when contingent values are found.
160
+ */
161
+ export declare function processContingentValues(properties: IFeatureServiceProperties, adminUrl: string, authentication: UserSession): Promise<void>;
142
162
  /**
143
163
  * Replace the field name reference templates with the new field names after deployment.
144
164
  *
@@ -332,73 +352,35 @@ export declare function updateLayerFieldReferences(itemTemplate: IItemTemplate,
332
352
  */
333
353
  export declare function postProcessFields(itemTemplate: IItemTemplate, layerInfos: any, popupInfos: any, adminLayerInfos: any, templateDictionary: any): Promise<any>;
334
354
  /**
335
- * when deploying to portal if a view has a different typeIdField than what it being set on the source service
336
- * we need to pass it via an updateDef call or it will be set as the typeIdField of the source service
337
- *
338
- * @param item current layer or table
339
- * @returns name of field to set for typeIdField in the update call
340
- * @private
341
- */
342
- export declare function _getTypeIdField(item: any): string;
343
- /**
344
- * Update a views field visibility to match that of the source
345
- * Fields that are marked as visible false on a view are all set to
346
- * visible true when added with the layer definition
355
+ * View field domain, alias, editable, and visible props can contain
356
+ * different values from the source.
347
357
  *
348
- * @param fieldInfo current layers or tables fieldInfo
349
- * @returns Array of fields that should not be visible in the view
350
- * @private
351
- */
352
- export declare function _getFieldVisibilityUpdates(fieldInfo: any): any[];
353
- /**
354
- * view field domains can contain different values than the source feature service field domains
355
- * use the cached domain when it differs from the source view field domain
358
+ * We need to check and set isFieldOverride to true when this occurs and false when it does not
356
359
  *
357
360
  * @param fieldInfo current view layer or table fieldInfo
358
- * @param fieldUpdates any existing field updates
359
- * @returns Array of fields to be updated
360
- * @private
361
- */
362
- export declare function _validateDomains(fieldInfo: any, fieldUpdates: any[]): any[];
363
- /**
364
- * Get portal field updates to be added with an updateDefinition call after the
365
- * initial addToDef
361
+ * @param item that stores the view fields
366
362
  *
367
- * @param field the current field instance
368
- * @param names the alias of domain field names
369
- * @param fields the alias or domain fields
370
- * @param key the field key to evaluate
371
- * @param fieldUpdates any existing field updates
372
- * @private
373
- */
374
- export declare function _getPortalViewFieldUpdates(field: any, names: string[], fields: any[], key: string, fieldUpdates: any[]): void;
375
- /**
376
- * view field domains can contain different values than the source feature service field domains
377
- * use the cached domain when it differs from the source view field domain
378
- *
379
- * @param fieldInfo current view layer or table fieldInfo
380
- * @param fieldUpdates any existing field updates
381
- * @returns Array of fields to be updated
363
+ * This function will update the item that is provided
382
364
  * @private
383
365
  */
384
- export declare function _validateViewDomainsAndAlias(fieldInfo: any, item: any): void;
366
+ export declare function _validateViewFieldInfos(fieldInfo: any, item: any): void;
385
367
  /**
386
- * Get array of domain fields and names and alias fields and names
368
+ * Get arrays of fields and names for domain, alias, and editable props
387
369
  *
388
370
  * @param fieldInfo current view layer or table fieldInfo
389
371
  * @private
390
372
  */
391
- export declare function _getDomainAndAliasInfos(fieldInfo: any): any;
373
+ export declare function _getViewFieldInfos(fieldInfo: any): any;
392
374
  /**
393
375
  * Set isViewOverride for view fields when they have differences from the source FS field
394
376
  *
395
377
  * @param field the field instance we are testing
396
378
  * @param names array of field names
397
- * @param fields array of fields
379
+ * @param vals array of values
398
380
  * @param key the field key to compare
399
381
  * @private
400
382
  */
401
- export declare function _isViewFieldOverride(field: any, names: string[], fields: any[], key: string): void;
383
+ export declare function _isViewFieldOverride(field: any, names: string[], vals: any[], key: string): void;
402
384
  /**
403
385
  * Add popup info back to the layer item
404
386
  *
@@ -20,9 +20,9 @@
20
20
  */
21
21
  // ------------------------------------------------------------------------------------------------------------------ //
22
22
  export { queryFeatures as rest_queryFeatures, addFeatures as rest_addFeatures } from "@esri/arcgis-rest-feature-layer";
23
- import { checkUrlPathTermination, deleteProp, fail, getProp, setCreateProp, setProp } from "./generalHelpers";
23
+ import { checkUrlPathTermination, deleteProp, deleteProps, fail, getProp, setCreateProp, setProp } from "./generalHelpers";
24
24
  import { replaceInTemplate, templatizeTerm, templatizeIds } from "./templatization";
25
- import { getFinalServiceUpdates, addToServiceDefinition, getLayerUpdates, getRequest, rest_request } from "./restHelpers";
25
+ import { addToServiceDefinition, getLayerUpdates, getRequest, rest_request } from "./restHelpers";
26
26
  import { isTrackingViewTemplate, templatizeTracker } from "./trackingHelpers";
27
27
  //#endregion ------------------------------------------------------------------------------------------------------------//
28
28
  //#region Public functions ----------------------------------------------------------------------------------------------//
@@ -121,10 +121,9 @@ export function deleteViewProps(layer) {
121
121
  *
122
122
  * @param layer The data layer instance with field name references within
123
123
  * @param fieldInfos the object that stores the cached field infos
124
- * @param isPortal Controls what properties should be removed.
125
124
  * @returns An updated instance of the fieldInfos
126
125
  */
127
- export function cacheFieldInfos(layer, fieldInfos, isPortal) {
126
+ export function cacheFieldInfos(layer, fieldInfos) {
128
127
  // cache the source fields as they are in the original source
129
128
  if (layer && layer.fields) {
130
129
  fieldInfos[layer.id] = {
@@ -137,19 +136,34 @@ export function cacheFieldInfos(layer, fieldInfos, isPortal) {
137
136
  // and will have associated updateDefinition calls when deploying to portal
138
137
  // as well as online for relationships...as relationships added with addToDef will cause failure
139
138
  const props = {
140
- editFieldsInfo: isPortal,
141
- types: isPortal,
142
- templates: isPortal,
139
+ editFieldsInfo: false,
140
+ types: false,
141
+ templates: false,
143
142
  relationships: true,
144
- drawingInfo: isPortal,
145
- timeInfo: isPortal,
146
- viewDefinitionQuery: isPortal
143
+ drawingInfo: false,
144
+ timeInfo: false,
145
+ viewDefinitionQuery: false
147
146
  };
148
147
  Object.keys(props).forEach(k => {
149
148
  _cacheFieldInfo(layer, k, fieldInfos, props[k]);
150
149
  });
151
150
  return fieldInfos;
152
151
  }
152
+ /**
153
+ * Cache the stored contingent values so we can add them in subsequent addToDef calls
154
+ *
155
+ * @param id The layer id for the associated values to be stored with
156
+ * @param fieldInfos The object that stores the cached field infos
157
+ * @param itemTemplate The current itemTemplate being processed
158
+ * @returns An updated instance of the fieldInfos
159
+ */
160
+ export function cacheContingentValues(id, fieldInfos, itemTemplate) {
161
+ const contingentValues = getProp(itemTemplate, 'properties.contingentValues');
162
+ if (contingentValues && contingentValues[id]) {
163
+ fieldInfos[id]['contingentValues'] = contingentValues[id];
164
+ }
165
+ return fieldInfos;
166
+ }
153
167
  /**
154
168
  * Helper function to cache a single property into the fieldInfos object
155
169
  * This property will be removed from the layer instance.
@@ -169,7 +183,7 @@ export function _cacheFieldInfo(layer, prop, fieldInfos, removeProp) {
169
183
  // editFieldsInfo does not come through unless its with the layer
170
184
  // when it's being added
171
185
  /* istanbul ignore else */
172
- if (removeProp && prop !== "editFieldsInfo") {
186
+ if (removeProp) {
173
187
  layer[prop] = null;
174
188
  }
175
189
  }
@@ -395,6 +409,57 @@ export function updateTemplateForInvalidDesignations(template, authentication) {
395
409
  }
396
410
  });
397
411
  }
412
+ /**
413
+ * Get the contingent values for each layer in the service.
414
+ * Remove key props that cannot be included with the addToDef call on deploy.
415
+ * Store the values alongside other key feature service properties in the template
416
+ *
417
+ * @param properties the current feature services properties
418
+ * @param adminUrl the current feature service url
419
+ * @param authentication Credentials for the request to AGOL
420
+ * @returns A promise that will resolve when the contingent values have been fetched.
421
+ * This function will update the provided properties argument when contingent values are found.
422
+ */
423
+ export function processContingentValues(properties, adminUrl, authentication) {
424
+ return new Promise((resolve, reject) => {
425
+ if (getProp(properties, 'service.isView')) {
426
+ // views will inherit from the source service
427
+ resolve();
428
+ }
429
+ else {
430
+ const layersAndTables = (properties.layers || []).concat(properties.tables || []);
431
+ const layerIds = [];
432
+ const contingentValuePromises = layersAndTables.reduce((prev, cur) => {
433
+ /* istanbul ignore else */
434
+ if (cur.hasContingentValuesDefinition) {
435
+ prev.push(rest_request(`${adminUrl}/${cur['id']}/contingentValues?f=json`, { authentication }));
436
+ layerIds.push(cur['id']);
437
+ }
438
+ return prev;
439
+ }, []);
440
+ if (contingentValuePromises.length > 0) {
441
+ Promise.all(contingentValuePromises).then((results) => {
442
+ const contingentValues = {};
443
+ results.forEach((r, i) => {
444
+ deleteProp(r, 'typeCodes');
445
+ /* istanbul ignore else */
446
+ if (getProp(r, 'stringDicts') && getProp(r, 'contingentValuesDefinition')) {
447
+ r.contingentValuesDefinition['stringDicts'] = r.stringDicts;
448
+ deleteProp(r, 'stringDicts');
449
+ }
450
+ deleteProps(getProp(r, 'contingentValuesDefinition'), ['layerID', 'layerName', 'geometryType', 'hasSubType']);
451
+ contingentValues[layerIds[i]] = r;
452
+ });
453
+ properties.contingentValues = contingentValues;
454
+ resolve();
455
+ }, reject);
456
+ }
457
+ else {
458
+ resolve();
459
+ }
460
+ }
461
+ });
462
+ }
398
463
  /**
399
464
  * Replace the field name reference templates with the new field names after deployment.
400
465
  *
@@ -503,16 +568,12 @@ export function addFeatureServiceLayersAndTables(itemTemplate, templateDictionar
503
568
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
504
569
  updateLayerFieldReferences(itemTemplate, fieldInfos, popupInfos, adminLayerInfos, templateDictionary).then(r => {
505
570
  // Update relationships and layer definitions
506
- let updates = getLayerUpdates({
571
+ const updates = getLayerUpdates({
507
572
  message: "updated layer definition",
508
573
  objects: r.layerInfos.fieldInfos,
509
574
  itemTemplate: r.itemTemplate,
510
575
  authentication
511
576
  }, templateDictionary.isPortal);
512
- // Get any updates for the service that should be performed after updates to the layers
513
- if (templateDictionary.isPortal) {
514
- updates = getFinalServiceUpdates(r.itemTemplate, authentication, updates);
515
- }
516
577
  // Process the updates sequentially
517
578
  updates
518
579
  .reduce((prev, update) => {
@@ -569,7 +630,9 @@ export function addFeatureServiceDefinition(serviceUrl, listToAdd, templateDicti
569
630
  listToAdd.forEach((toAdd, i) => {
570
631
  let item = toAdd.item;
571
632
  const originalId = item.id;
572
- fieldInfos = cacheFieldInfos(item, fieldInfos, templateDictionary.isPortal);
633
+ fieldInfos = cacheFieldInfos(item, fieldInfos);
634
+ // cache the values to be added in seperate addToDef calls
635
+ fieldInfos = cacheContingentValues(item.id, fieldInfos, itemTemplate);
573
636
  /* istanbul ignore else */
574
637
  if (item.isView) {
575
638
  deleteViewProps(item);
@@ -585,9 +648,7 @@ export function addFeatureServiceDefinition(serviceUrl, listToAdd, templateDicti
585
648
  // update adminLayerInfo before add to definition with view source fieldInfo settings
586
649
  item.adminLayerInfo = replaceInTemplate(item.adminLayerInfo, templateDictionary);
587
650
  /* istanbul ignore else */
588
- if (!templateDictionary.isPortal &&
589
- fieldInfos &&
590
- fieldInfos.hasOwnProperty(item.id)) {
651
+ if (fieldInfos && fieldInfos.hasOwnProperty(item.id)) {
591
652
  Object.keys(templateDictionary).some(k => {
592
653
  if (templateDictionary[k].itemId === itemTemplate.itemId) {
593
654
  fieldInfos[item.id]["sourceServiceFields"] =
@@ -600,7 +661,7 @@ export function addFeatureServiceDefinition(serviceUrl, listToAdd, templateDicti
600
661
  });
601
662
  // view field domain and alias can contain different values than the source field
602
663
  // we need to set isViewOverride when added fields that differ from the source field
603
- _validateViewDomainsAndAlias(fieldInfos[item.id], item);
664
+ _validateViewFieldInfos(fieldInfos[item.id], item);
604
665
  }
605
666
  }
606
667
  /* istanbul ignore else */
@@ -752,7 +813,6 @@ export function _updateForPortal(item, itemTemplate, templateDictionary) {
752
813
  }
753
814
  // not allowed to set sourceSchemaChangesAllowed or isView for portal
754
815
  // these are set when you create the service
755
- deleteProp(item, "sourceSchemaChangesAllowed");
756
816
  deleteProp(item, "isView");
757
817
  return item;
758
818
  }
@@ -1028,25 +1088,10 @@ export function postProcessFields(itemTemplate, layerInfos, popupInfos, adminLay
1028
1088
  // more than case change when deployed to protal so keep track of the new names
1029
1089
  layerInfo["newEditFieldsInfo"] = JSON.parse(JSON.stringify(item.editFieldsInfo));
1030
1090
  }
1031
- // fields that are marked as visible false on a view are all set to
1032
- // visible true when added with the layer definition
1033
- // update the field visibility to match that of the source
1034
1091
  /* istanbul ignore else */
1035
1092
  if (isView && templateInfo && templateDictionary.isPortal) {
1036
1093
  // when the item is a view bring over the source service fields so we can compare the domains
1037
1094
  layerInfo["sourceServiceFields"] = templateInfo.sourceServiceFields;
1038
- let fieldUpdates = _getFieldVisibilityUpdates(layerInfo);
1039
- // view field domains can contain different values than the source field domains
1040
- // use the cached view domain when it differs from the source view domain
1041
- fieldUpdates = _validateDomains(layerInfo, fieldUpdates);
1042
- /* istanbul ignore else */
1043
- if (fieldUpdates.length > 0) {
1044
- layerInfo.fields = fieldUpdates;
1045
- }
1046
- layerInfo.typeIdField = _getTypeIdField(item);
1047
- const fieldNames = layerInfo.newFields.map((f) => f.name);
1048
- _validateTemplatesFields(layerInfo, fieldNames);
1049
- _validateTypesTemplates(layerInfo, fieldNames);
1050
1095
  }
1051
1096
  }
1052
1097
  });
@@ -1062,141 +1107,35 @@ export function postProcessFields(itemTemplate, layerInfos, popupInfos, adminLay
1062
1107
  });
1063
1108
  }
1064
1109
  /**
1065
- * when deploying to portal if a view has a different typeIdField than what it being set on the source service
1066
- * we need to pass it via an updateDef call or it will be set as the typeIdField of the source service
1110
+ * View field domain, alias, editable, and visible props can contain
1111
+ * different values from the source.
1067
1112
  *
1068
- * @param item current layer or table
1069
- * @returns name of field to set for typeIdField in the update call
1070
- * @private
1071
- */
1072
- export function _getTypeIdField(item) {
1073
- const typeIdFields = item.fields.filter((f) => {
1074
- return (f.name &&
1075
- item.typeIdField &&
1076
- f.name.toLowerCase() === item.typeIdField.toLowerCase());
1077
- });
1078
- return Array.isArray(typeIdFields) && typeIdFields.length === 1
1079
- ? typeIdFields[0].name
1080
- : item.typeIdField;
1081
- }
1082
- /**
1083
- * Update a views field visibility to match that of the source
1084
- * Fields that are marked as visible false on a view are all set to
1085
- * visible true when added with the layer definition
1086
- *
1087
- * @param fieldInfo current layers or tables fieldInfo
1088
- * @returns Array of fields that should not be visible in the view
1089
- * @private
1090
- */
1091
- export function _getFieldVisibilityUpdates(fieldInfo) {
1092
- const visibilityUpdates = [];
1093
- if (fieldInfo && fieldInfo["sourceFields"] && fieldInfo["newFields"]) {
1094
- const sourceFields = fieldInfo["sourceFields"].reduce((hash, f) => {
1095
- hash[String(f.name).toLocaleLowerCase()] = f.visible;
1096
- return hash;
1097
- }, {});
1098
- fieldInfo["newFields"].forEach((f) => {
1099
- const name = String(f.name).toLocaleLowerCase();
1100
- // only add fields that are not visible
1101
- if (sourceFields.hasOwnProperty(name) && !sourceFields[name]) {
1102
- visibilityUpdates.push({
1103
- name: f.name,
1104
- visible: sourceFields[name]
1105
- });
1106
- }
1107
- });
1108
- }
1109
- return visibilityUpdates;
1110
- }
1111
- /**
1112
- * view field domains can contain different values than the source feature service field domains
1113
- * use the cached domain when it differs from the source view field domain
1113
+ * We need to check and set isFieldOverride to true when this occurs and false when it does not
1114
1114
  *
1115
1115
  * @param fieldInfo current view layer or table fieldInfo
1116
- * @param fieldUpdates any existing field updates
1117
- * @returns Array of fields to be updated
1118
- * @private
1119
- */
1120
- export function _validateDomains(fieldInfo, fieldUpdates) {
1121
- const domainAliasInfos = _getDomainAndAliasInfos(fieldInfo);
1122
- const domainFields = domainAliasInfos.domainFields;
1123
- const domainNames = domainAliasInfos.domainNames;
1124
- const aliasFields = domainAliasInfos.aliasFields;
1125
- const aliasNames = domainAliasInfos.aliasNames;
1126
- // loop through the fields from the new view service
1127
- // add an update when the domains don't match
1128
- fieldInfo.newFields.forEach((field) => {
1129
- _getPortalViewFieldUpdates(field, domainNames, domainFields, "domain", fieldUpdates);
1130
- _getPortalViewFieldUpdates(field, aliasNames, aliasFields, "alias", fieldUpdates);
1131
- });
1132
- return fieldUpdates;
1133
- }
1134
- /**
1135
- * Get portal field updates to be added with an updateDefinition call after the
1136
- * initial addToDef
1116
+ * @param item that stores the view fields
1137
1117
  *
1138
- * @param field the current field instance
1139
- * @param names the alias of domain field names
1140
- * @param fields the alias or domain fields
1141
- * @param key the field key to evaluate
1142
- * @param fieldUpdates any existing field updates
1118
+ * This function will update the item that is provided
1143
1119
  * @private
1144
1120
  */
1145
- export function _getPortalViewFieldUpdates(field, names, fields, key, fieldUpdates) {
1146
- if (field.hasOwnProperty(key) && field[key]) {
1147
- const i = names.indexOf(String(field.name).toLocaleLowerCase());
1148
- if (JSON.stringify(field[key]) !== (i > -1 ? JSON.stringify(fields[i]) : "")) {
1149
- // should mixin the update if the field already has some other update
1150
- let hasUpdate = false;
1151
- fieldUpdates.some((update) => {
1152
- if (update.name === field.name) {
1153
- hasUpdate = true;
1154
- update[key] = field[key];
1155
- }
1156
- return hasUpdate;
1157
- });
1158
- if (!hasUpdate) {
1159
- const update = { name: field.name };
1160
- update[key] = field[key];
1161
- fieldUpdates.push(update);
1162
- }
1163
- }
1164
- }
1165
- }
1166
- /**
1167
- * view field domains can contain different values than the source feature service field domains
1168
- * use the cached domain when it differs from the source view field domain
1169
- *
1170
- * @param fieldInfo current view layer or table fieldInfo
1171
- * @param fieldUpdates any existing field updates
1172
- * @returns Array of fields to be updated
1173
- * @private
1174
- */
1175
- export function _validateViewDomainsAndAlias(fieldInfo, item) {
1176
- const domainAliasInfos = _getDomainAndAliasInfos(fieldInfo);
1177
- const domainFields = domainAliasInfos.domainFields;
1178
- const domainNames = domainAliasInfos.domainNames;
1179
- const aliasFields = domainAliasInfos.aliasFields;
1180
- const aliasNames = domainAliasInfos.aliasNames;
1181
- // loop through the fields from the item
1182
- // add isViewOverride when the domains or alias don't match
1121
+ export function _validateViewFieldInfos(fieldInfo, item) {
1122
+ const fieldInfos = _getViewFieldInfos(fieldInfo);
1183
1123
  item.fields.map((field) => {
1184
- _isViewFieldOverride(field, domainNames, domainFields, "domain");
1185
- _isViewFieldOverride(field, aliasNames, aliasFields, "alias");
1124
+ Object.keys(fieldInfos).forEach(fi => {
1125
+ _isViewFieldOverride(field, fieldInfos[fi].names, fieldInfos[fi].vals, fi);
1126
+ });
1186
1127
  return field;
1187
1128
  });
1188
1129
  }
1189
1130
  /**
1190
- * Get array of domain fields and names and alias fields and names
1131
+ * Get arrays of fields and names for domain, alias, and editable props
1191
1132
  *
1192
1133
  * @param fieldInfo current view layer or table fieldInfo
1193
1134
  * @private
1194
1135
  */
1195
- export function _getDomainAndAliasInfos(fieldInfo) {
1196
- const domainFields = [];
1197
- const domainNames = [];
1198
- const aliasFields = [];
1199
- const aliasNames = [];
1136
+ export function _getViewFieldInfos(fieldInfo) {
1137
+ const fieldInfos = {};
1138
+ const fieldOverrideKeys = ["domain", "alias", "editable"];
1200
1139
  /* istanbul ignore else */
1201
1140
  if (fieldInfo.sourceServiceFields) {
1202
1141
  Object.keys(fieldInfo.sourceServiceFields).forEach(k => {
@@ -1204,44 +1143,49 @@ export function _getDomainAndAliasInfos(fieldInfo) {
1204
1143
  if (fieldInfo.sourceServiceFields[k]) {
1205
1144
  Object.keys(fieldInfo.sourceServiceFields[k]).forEach(_k => {
1206
1145
  fieldInfo.sourceServiceFields[k][_k].forEach((field) => {
1207
- /* istanbul ignore else */
1208
- if (field.hasOwnProperty("domain") && field.domain) {
1209
- domainFields.push(field.domain);
1210
- domainNames.push(String(field.name).toLocaleLowerCase());
1211
- }
1212
- /* istanbul ignore else */
1213
- if (field.hasOwnProperty("alias") && field.alias) {
1214
- aliasFields.push(field.alias);
1215
- aliasNames.push(String(field.name).toLocaleLowerCase());
1216
- }
1146
+ fieldOverrideKeys.forEach(o_k => {
1147
+ /* istanbul ignore else */
1148
+ if (field.hasOwnProperty(o_k)) {
1149
+ const name = String(field.name).toLocaleLowerCase();
1150
+ const v = field[o_k];
1151
+ if (getProp(fieldInfos, o_k)) {
1152
+ fieldInfos[o_k].names.push(name);
1153
+ fieldInfos[o_k].vals.push(v);
1154
+ }
1155
+ else {
1156
+ fieldInfos[o_k] = {
1157
+ names: [name],
1158
+ vals: [v]
1159
+ };
1160
+ }
1161
+ }
1162
+ });
1217
1163
  });
1218
1164
  });
1219
1165
  }
1220
1166
  });
1221
1167
  }
1222
- return {
1223
- aliasFields,
1224
- aliasNames,
1225
- domainFields,
1226
- domainNames
1227
- };
1168
+ return fieldInfos;
1228
1169
  }
1229
1170
  /**
1230
1171
  * Set isViewOverride for view fields when they have differences from the source FS field
1231
1172
  *
1232
1173
  * @param field the field instance we are testing
1233
1174
  * @param names array of field names
1234
- * @param fields array of fields
1175
+ * @param vals array of values
1235
1176
  * @param key the field key to compare
1236
1177
  * @private
1237
1178
  */
1238
- export function _isViewFieldOverride(field, names, fields, key) {
1179
+ export function _isViewFieldOverride(field, names, vals, key) {
1239
1180
  /* istanbul ignore else */
1240
- if (field.hasOwnProperty(key) && field[key]) {
1181
+ if (field.hasOwnProperty(key)) {
1241
1182
  const i = names.indexOf(String(field.name).toLocaleLowerCase());
1183
+ const isOverride = JSON.stringify(field[key]) !== (i > -1 ? JSON.stringify(vals[i]) : "");
1184
+ const overrideSet = field.hasOwnProperty('isViewOverride');
1185
+ // need to skip this check if isViewOverride has already been set to true
1242
1186
  /* istanbul ignore else */
1243
- if (JSON.stringify(field[key]) !== (i > -1 ? JSON.stringify(fields[i]) : "")) {
1244
- field.isViewOverride = true;
1187
+ if (((overrideSet && !field.isViewOverride) || !overrideSet)) {
1188
+ field.isViewOverride = isOverride;
1245
1189
  }
1246
1190
  }
1247
1191
  }