Add layer name to transaction change view

Test: Make sure layer names show up when looking at the changes view
Change-Id: I29efcc6522fb5701d86e44da2cb29655df15beb5
This commit is contained in:
Pablo Gamito
2020-07-29 14:10:13 +01:00
parent d120b06c91
commit 19db1a5688
3 changed files with 110 additions and 17 deletions

View File

@@ -78,6 +78,7 @@ export default {
}, },
sufacesAffectedBy(transaction) { sufacesAffectedBy(transaction) {
if (transaction.type !== 'transaction') { if (transaction.type !== 'transaction') {
// TODO (b/162402459): Shorten layer name
return [{name: transaction.layerName, id: transaction.obj.id}]; return [{name: transaction.layerName, id: transaction.obj.id}];
} }

View File

@@ -170,9 +170,10 @@ export default {
transactionSelected(transaction) { transactionSelected(transaction) {
this.selectedTransaction = transaction; this.selectedTransaction = transaction;
let obj = this.removeNullFields(transaction.obj); const META_DATA_KEY = "metadata"
let name = transaction.type;
let obj;
let name;
if (transaction.type == "transaction") { if (transaction.type == "transaction") {
name = "changes"; name = "changes";
obj = {}; obj = {};
@@ -180,11 +181,27 @@ export default {
const [surfaceChanges, displayChanges] = const [surfaceChanges, displayChanges] =
this.aggregateTransactions(transaction.transactions); this.aggregateTransactions(transaction.transactions);
// Prepare the surface and display changes to be passed through
// the ObjectTransformer — in particular, remove redundant properties
// and add metadata that can be accessed post transformation
const perpareForTreeViewTransform = (change) => {
this.removeNullFields(change);
change[META_DATA_KEY] = {
// TODO (b/162402459): Shorten layer name
layerName: change.layerName,
}
// remove redundant properties
delete change.layerName;
delete change.id;
console.log(change)
};
for (const changeId in surfaceChanges) { for (const changeId in surfaceChanges) {
this.removeNullFields(surfaceChanges[changeId]); perpareForTreeViewTransform(surfaceChanges[changeId])
} }
for (const changeId in displayChanges) { for (const changeId in displayChanges) {
this.removeNullFields(displayChanges[changeId]); perpareForTreeViewTransform(displayChanges[changeId])
} }
if (Object.keys(surfaceChanges).length > 0) { if (Object.keys(surfaceChanges).length > 0) {
@@ -194,8 +211,12 @@ export default {
if (Object.keys(displayChanges).length > 0) { if (Object.keys(displayChanges).length > 0) {
obj.displayChanges = displayChanges; obj.displayChanges = displayChanges;
} }
} else {
obj = this.removeNullFields(transaction.obj);
name = transaction.type;
} }
// Transform the raw JS object to be TreeView compatible
const transactionUniqueId = transaction.timestamp; const transactionUniqueId = transaction.timestamp;
let tree = new ObjectTransformer( let tree = new ObjectTransformer(
obj, obj,
@@ -203,8 +224,29 @@ export default {
transactionUniqueId transactionUniqueId
).setOptions({ ).setOptions({
formatter: () => {}, formatter: () => {},
}).transform(); }).transform({
keepOriginal: true,
metadataKey: META_DATA_KEY,
freeze: false
});
// Add the layer name as the kind of the object to be shown in the TreeView
const addLayerNameAsKind = (tree) => {
for (const layerChanges of tree.children) {
layerChanges.kind = layerChanges.metadata.layerName;
}
}
if (transaction.type == "transaction") {
for (const child of tree.children) {
// child = surfaceChanges or displayChanges tree node
addLayerNameAsKind(child)
}
}
// If there are only surfaceChanges or only displayChanges and not both
// remove the extra top layer node which is meant to hold both types of
// changes when both are present
if (tree.name == "changes" && tree.children.length === 1) { if (tree.name == "changes" && tree.children.length === 1) {
tree = tree.children[0]; tree = tree.children[0];
} }
@@ -227,7 +269,7 @@ export default {
}; };
}, },
isMeaningfulChange(object, key) { isMeaningfulChange(object, key) {
// TODO: Handle cases of non null objects but meaningless change // TODO (b/159799733): Handle cases of non null objects but meaningless change
return object[key] !== null && object.hasOwnProperty(key) return object[key] !== null && object.hasOwnProperty(key)
}, },
mergeChanges(a, b) { mergeChanges(a, b) {
@@ -257,15 +299,22 @@ export default {
for (const transaction of transactions) { for (const transaction of transactions) {
const obj = transaction.obj; const obj = transaction.obj;
// Create a new base object to merge all changes into
const newBaseObj = () => {
return {
layerName: transaction.layerName,
}
}
switch (transaction.type) { switch (transaction.type) {
case "surfaceChange": case "surfaceChange":
surfaceChanges[obj.id] = surfaceChanges[obj.id] =
this.mergeChanges(surfaceChanges[obj.id] ?? {}, obj); this.mergeChanges(surfaceChanges[obj.id] ?? newBaseObj(), obj);
break; break;
case "displayChange": case "displayChange":
displayChanges[obj.id] = displayChanges[obj.id] =
this.mergeChanges(displayChanges[obj.id] ?? {}, obj); this.mergeChanges(displayChanges[obj.id] ?? newBaseObj(), obj);
break; break;
default: default:

View File

@@ -137,7 +137,16 @@ class ObjectTransformer {
return this; return this;
} }
transform() { /**
* Transform the raw JS Object into a TreeView compatible object
* @param {bool} keepOriginal whether or not to store the original object in
* the obj property of a tree node for future reference
* @param {bool} freeze whether or not the returned objected should be frozen
* to prevent changing any of its properties
* @param {string} metadataKey the key that contains a node's metadata to be
* accessible after the transformation
*/
transform(transformOptions = { keepOriginal: false, freeze: true, metadataKey: null }) {
const { formatter } = this.options; const { formatter } = this.options;
if (!formatter) { if (!formatter) {
throw new Error("Missing formatter, please set with setOptions()"); throw new Error("Missing formatter, please set with setOptions()");
@@ -145,10 +154,13 @@ class ObjectTransformer {
return this._transform(this.obj, this.rootName, null, return this._transform(this.obj, this.rootName, null,
this.compareWithObj, this.rootName, null, this.compareWithObj, this.rootName, null,
this.stableId); this.stableId, transformOptions);
} }
_transformObject(obj, fieldOptions) { /**
* @param {*} metadataKey if 'obj' contains this key, it is excluded from the transformation
*/
_transformObject(obj, fieldOptions, metadataKey) {
const { skip, formatter } = this.options; const { skip, formatter } = this.options;
const transformedObj = { const transformedObj = {
obj: {}, obj: {},
@@ -178,6 +190,9 @@ class ObjectTransformer {
transformedObj.fieldOptions["" + obj] = fieldOptions; transformedObj.fieldOptions["" + obj] = fieldOptions;
} else if (obj && typeof obj == 'object') { } else if (obj && typeof obj == 'object') {
Object.keys(obj).forEach((key) => { Object.keys(obj).forEach((key) => {
if (key === metadataKey) {
return;
}
transformedObj.obj[key] = obj[key]; transformedObj.obj[key] = obj[key];
transformedObj.fieldOptions[key] = obj.$type?.fields[key]?.options; transformedObj.fieldOptions[key] = obj.$type?.fields[key]?.options;
}); });
@@ -190,18 +205,38 @@ class ObjectTransformer {
return transformedObj; return transformedObj;
} }
/**
* Extract the value of obj's property with key 'metadataKey'
* @param {Object} obj the obj we want to extract the metadata from
* @param {string} metadataKey the key that stores the metadata in the object
* @return the metadata value or null in no metadata is present
*/
_getMetadata(obj, metadataKey) {
if (metadataKey && obj[metadataKey]) {
const metadata = obj[metadataKey];
obj[metadataKey] = undefined;
return metadata;
} else {
return null;
}
}
_transform(obj, name, fieldOptions, _transform(obj, name, fieldOptions,
compareWithObj, compareWithName, compareWithFieldOptions, compareWithObj, compareWithName, compareWithFieldOptions,
stableId) { stableId, transformOptions) {
const originalObj = obj;
const metadata = this._getMetadata(obj, transformOptions.metadataKey);
const children = []; const children = [];
if (!isTerminal(obj)) { if (!isTerminal(obj)) {
const transformedObj = this._transformObject(obj, fieldOptions); const transformedObj = this._transformObject(obj, fieldOptions, transformOptions.metadataKey);
obj = transformedObj.obj; obj = transformedObj.obj;
fieldOptions = transformedObj.fieldOptions; fieldOptions = transformedObj.fieldOptions;
} }
if (!isTerminal(compareWithObj)) { if (!isTerminal(compareWithObj)) {
const transformedObj = this._transformObject(compareWithObj, compareWithFieldOptions); const transformedObj = this._transformObject(compareWithObj, compareWithFieldOptions, transformOptions.metadataKey);
compareWithObj = transformedObj.obj; compareWithObj = transformedObj.obj;
compareWithFieldOptions = transformedObj.fieldOptions; compareWithFieldOptions = transformedObj.fieldOptions;
} }
@@ -218,7 +253,7 @@ class ObjectTransformer {
} }
children.push(this._transform(obj[key], key, fieldOptions[key], children.push(this._transform(obj[key], key, fieldOptions[key],
compareWithChild, compareWithChildName, compareWithChildFieldOptions, compareWithChild, compareWithChildName, compareWithChildFieldOptions,
`${stableId}.${key}`)); `${stableId}.${key}`, transformOptions));
} }
} }
@@ -226,7 +261,7 @@ class ObjectTransformer {
for (const key in compareWithObj) { for (const key in compareWithObj) {
if (!obj.hasOwnProperty(key) && compareWithObj.hasOwnProperty(key)) { if (!obj.hasOwnProperty(key) && compareWithObj.hasOwnProperty(key)) {
children.push(this._transform(new Terminal(), new Terminal(), undefined, children.push(this._transform(new Terminal(), new Terminal(), undefined,
compareWithObj[key], key, compareWithFieldOptions[key], `${stableId}.${key}`)); compareWithObj[key], key, compareWithFieldOptions[key], `${stableId}.${key}`, transformOptions));
} }
} }
@@ -282,7 +317,15 @@ class ObjectTransformer {
} }
} }
return Object.freeze(transformedObj); if (transformOptions.keepOriginal) {
transformedObj.obj = originalObj;
}
if (metadata) {
transformedObj[transformOptions.metadataKey] = metadata;
}
return transformOptions.freeze ? Object.freeze(transformedObj) : transformedObj;
} }
} }