Gets image cropper working between variants, even with invariant properties, adds unit test to ensure invariant properties in the model are the same reference

This commit is contained in:
Shannon
2018-08-10 00:39:20 +10:00
parent 9183a9987b
commit 2f0f43e605
8 changed files with 185 additions and 21 deletions

View File

@@ -51,6 +51,19 @@
vm.fileUploadForm.$setDirty();
}
function notifyInit(val, files) {
if (!val) {
val = null;
}
if (!files) {
files = null;
}
if (vm.onInit) {
vm.onInit({ value: val, files: files });
}
}
/** Called when the component initializes */
function onInit() {
$scope.$on("filesSelected", onFilesSelected);
@@ -85,7 +98,7 @@
if (existingClientFiles.length > 0) {
updateModelFromSelectedFiles(existingClientFiles).then(function(newVal) {
//notify the callback
vm.onValueChanged({ value: newVal, files: vm.files });
notifyInit(newVal, vm.files);
});
}
else if (vm.value) {
@@ -101,12 +114,16 @@
f.fileSrc = getThumbnail(f);
return f;
});
//notify the callback
notifyInit();
}
else {
vm.files = [];
}
//vm.clearFiles = false;
//notify the callback
notifyInit();
}
}
///** Method required by the valPropertyValidator directive (returns true if the property editor has at least one file selected) */
@@ -250,8 +267,9 @@
culture: "@?",
propertyAlias: "@",
value: "<",
hideSelection: "<",
onValueChanged: "&",
hideSelection: "<"
onInit: "&"
},
transclude: true,
controllerAs: 'vm',

View File

@@ -332,12 +332,15 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) {
*/
getById: function (id) {
return umbRequestHelper.resourcePromise(
$http.get(
umbRequestHelper.getApiUrl(
"contentApiBaseUrl",
"GetById",
{ id: id })),
'Failed to retrieve data for content id ' + id);
$http.get(
umbRequestHelper.getApiUrl(
"contentApiBaseUrl",
"GetById",
{ id: id })),
'Failed to retrieve data for content id ' + id)
.then(function(result) {
return $q.when(umbDataFormatter.formatContentGetData(result));
});
},
getBlueprintById: function (id) {

View File

@@ -383,6 +383,52 @@
saveModel.templateAlias = propTemplate ? propTemplate : null;
return saveModel;
},
/**
* This formats the server GET response for a content display item
* @param {} displayModel
* @returns {}
*/
formatContentGetData: function(displayModel) {
//We need to check for invariant properties among the variant variants.
//When we detect this, we want to make sure that the property object instance is the
//same reference object between all variants instead of a copy (which it will be when
//return from the JSON structure).
if (displayModel.variants && displayModel.variants.length > 1) {
var invariantProperties = [];
//collect all invariant properties on the first first variant
var firstVariant = displayModel.variants[0];
_.each(firstVariant.tabs, function(tab, tabIndex) {
_.each(tab.properties, function (property, propIndex) {
//in theory if there's more than 1 variant, that means they would all have a language
//but we'll do our safety checks anyways here
if (firstVariant.language && !property.culture) {
invariantProperties.push({
tabIndex: tabIndex,
propIndex: propIndex,
property: property
});
}
});
});
//now assign this same invariant property instance to the same index of the other variants property array
for (var j = 1; j < displayModel.variants.length; j++) {
var variant = displayModel.variants[j];
_.each(invariantProperties, function (invProp) {
variant.tabs[invProp.tabIndex].properties[invProp.propIndex] = invProp.property;
});
}
}
return displayModel;
}
};
}

View File

@@ -8,9 +8,7 @@
<p><localize key="media_clickToUpload">Click to upload</localize></p>
<umb-single-file-upload></umb-single-file-upload>
</div>
<pre><code>{{vm.files.length}}</code></pre>
<div ng-if="vm.files.length > 0">
<div ng-if="!vm.hideSelection">

View File

@@ -12,7 +12,7 @@
*/
function fileUploadController($scope) {
$scope.fileChanged = fileChanged;
$scope.fileChanged = onFileChanged;
//declare a special method which will be called whenever the value has changed from the server
$scope.model.onValueChanged = onValueChanged;
@@ -20,7 +20,7 @@
* Called when the file selection value changes
* @param {any} value
*/
function fileChanged(value) {
function onFileChanged(value) {
$scope.model.value = value;
//if the value is empty, then tell the server to clear the files

View File

@@ -4,7 +4,8 @@ angular.module('umbraco')
var config = angular.copy($scope.model.config);
$scope.fileChanged = fileChanged;
$scope.fileChanged = onFileChanged;
$scope.fileUploaderInit = onFileUploaderInit;
$scope.crop = crop;
$scope.done = done;
$scope.clear = clear;
@@ -40,7 +41,7 @@ angular.module('umbraco')
* Called when the file selection value changes
* @param {any} value
*/
function fileChanged(value, files) {
function onFileChanged(value, files) {
setModelValueWithSrc(value);
if (files && files[0]) {
@@ -50,7 +51,11 @@ angular.module('umbraco')
}
}
function onInit() {
/**
* Called when the file uploader initializes
* @param {any} value
*/
function onFileUploaderInit(value, files) {
//move previously saved value to the editor
if ($scope.model.value) {
//backwards compat with the old file upload (incase some-one swaps them..)
@@ -74,7 +79,14 @@ angular.module('umbraco')
}
}
$scope.imageSrc = $scope.model.value.src;
//if there are already files in the client assigned then set the src
if (files && files[0]) {
$scope.imageSrc = files[0].fileSrc;
}
else {
$scope.imageSrc = $scope.model.value.src;
}
}
}
@@ -120,8 +132,6 @@ angular.module('umbraco')
//set form to dirty to track changes
$scope.imageCropperForm.$setDirty();
};
onInit();
var unsubscribe = $scope.$on("formSubmitting", function () {
$scope.currentCrop = null;

View File

@@ -7,6 +7,7 @@
property-alias="{{model.alias}}"
value="model.value.src"
on-value-changed="fileChanged(value, files)"
on-init="fileUploaderInit(value, files)"
hide-selection="true">
<div class="imagecropper clearfix">

View File

@@ -0,0 +1,88 @@
describe('umbDataFormatter service tests', function () {
var umbDataFormatter;
beforeEach(module('umbraco.services'));
beforeEach(inject(function ($injector) {
umbDataFormatter = $injector.get('umbDataFormatter');
}));
describe('formatting GET content data', function () {
it('will set the same invariant property instance reference between all variants', function () {
var model = {
variants: [
{
language: { culture: "en-US" },
tabs: [
{
properties: [
{ alias: "test1", culture: null, value: "test1" },
{ alias: "test2", culture: "en-US", value: "test2" }
]
},
{
properties: [
{ alias: "test3", culture: "en-US", value: "test3" },
{ alias: "test4", culture: null, value: "test4" }
]
}
]
},
{
language: { culture: "es-ES" },
tabs: [
{
properties: [
{ alias: "test1", culture: null, value: "test5" },
{ alias: "test2", culture: "en-US", value: "test6" }
]
},
{
properties: [
{ alias: "test3", culture: "en-US", value: "test7" },
{ alias: "test4", culture: null, value: "test8" }
]
}
]
},
{
language: { culture: "fr-FR" },
tabs: [
{
properties: [
{ alias: "test1", culture: null, value: "test9" },
{ alias: "test2", culture: "en-US", value: "test10" }
]
},
{
properties: [
{ alias: "test3", culture: "en-US", value: "test11" },
{ alias: "test4", culture: null, value: "test12" }
]
}
]
}
]
};
var result = umbDataFormatter.formatContentGetData(model);
//make sure the same property reference exists for property 0 and 3 for each variant
for (var i = 1; i < result.variants.length; i++) {
expect(result.variants[0].tabs[0].properties[0]).toBe(result.variants[i].tabs[0].properties[0]);
expect(result.variants[0].tabs[1].properties[3]).toBe(result.variants[i].tabs[1].properties[3]);
}
//test that changing a property value in one variant is definitely updating the same object reference and therefor
//is done on all variants.
result.variants[0].tabs[0].properties[0].value = "hello";
for (var i = 1; i < result.variants.length; i++) {
expect(result.variants[0].tabs[0].properties[0].value).toBe("hello");
}
});
});
});