Skip to content

Commit

Permalink
Fix gallery disappearing (#3599)
Browse files Browse the repository at this point in the history
  • Loading branch information
tomaskikutis authored and petrjasek committed Sep 16, 2020
1 parent 19cbfaa commit 4708ee9
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 95 deletions.
164 changes: 87 additions & 77 deletions scripts/apps/authoring/authoring/controllers/AssociationController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,26 @@ export function getAssociationsByFieldId(associations: IArticle['associations'],
*
* @description Controller for handling adding/uploading images to association fields
*/
AssociationController.$inject = ['content', 'superdesk', 'renditions', 'notify'];
export function AssociationController(content, superdesk, renditions, notify) {
const self = this;

this.checkRenditions = checkRenditions;
export class AssociationController {
content: any;
superdesk: any;
renditions: any;
notify: any;
checkRenditions: typeof checkRenditions;

constructor(content, superdesk, renditions, notify) {
this.content = content;
this.superdesk = superdesk;
this.renditions = renditions;
this.notify = notify;

this.checkRenditions = checkRenditions;
}

/**
* @ngdoc method
* @name AssociationController#isMediaEditable
* @public
* @description Check if featured media can be edited or not. i.e. metadata/crops can be changed or not.
*/
this.isMediaEditable = function(item?: IArticle) {
// Check if featured media can be edited or not. i.e. metadata/crops can be changed or not.
isMediaEditable(item?: IArticle) {
return isMediaEditable(item);
};
}

/**
* @ngdoc method
Expand All @@ -46,7 +51,7 @@ export function AssociationController(content, superdesk, renditions, notify) {
* @param {Object} scope Directive scope
* @param {Array} files
*/
this.uploadAndCropImages = function(scope, files) {
uploadAndCropImages(scope, files): Promise<boolean> {
// in case of feature media we dont have scope.field available as it is not a vocabulary.
const maxUploadsRemaining = scope.maxUploads != null && scope.field != null
? scope.maxUploads - getAssociationsByFieldId(scope.item.associations, scope.field._id).length
Expand All @@ -62,45 +67,48 @@ export function AssociationController(content, superdesk, renditions, notify) {
parent: scope.item,
};

superdesk.intent('upload', 'media', uploadData).then((images) => {
// open the view to edit the point of interest and the cropping areas
if (images) {
scope.$applyAsync(() => {
var [rootField, index] = mediaIdGenerator.getFieldParts(scope.rel);
var imagesWithIds = [];

function editNextFile() {
if (imagesWithIds.length > 0) {
var imageWithId = imagesWithIds.shift();

self.edit(scope, imageWithId.image, {
customRel: imageWithId.id,
isNew: true,
}, editNextFile);
}
}

forEach(images, (image) => {
imagesWithIds.push({id: scope.rel, image: image});
scope.rel = mediaIdGenerator.getFieldVersionName(rootField, (++index).toString());
return new Promise<boolean>((resolve) => {
this.superdesk.intent('upload', 'media', uploadData).then((images) => {
// open the view to edit the point of interest and the cropping areas
if (images) {
scope.$applyAsync(() => {
var [rootField, index] = mediaIdGenerator.getFieldParts(scope.rel);
var imagesWithIds = [];

const editNextFile = () => {
if (imagesWithIds.length > 0) {
var imageWithId = imagesWithIds.shift();

this.edit(scope, imageWithId.image, {
customRel: imageWithId.id,
isNew: true,
}, editNextFile);
} else {
resolve(true);
}
};

forEach(images, (image) => {
imagesWithIds.push({id: scope.rel, image: image});
scope.rel = mediaIdGenerator.getFieldVersionName(rootField, (++index).toString());
});
editNextFile();
});
editNextFile();
});
}
}
});
});
};
}

/**
* @ngdoc method
* @name AssociationController#updateItemAssociation
* @private
* @description If the item is not published then it saves the changes otherwise calls autosave.
* @param {Object} scope Directive scope
* @param {Object} updated Item to be edited
* @param {String} customRel association identifier
* @param {Function} callback to call after save
*/
this.updateItemAssociation = function(scope, updated, customRel, callback = null, autosave = false) {
updateItemAssociation(scope, updated, customRel, callback = null, autosave = false): Promise<boolean> {
let data = {};
// if the media is of type media-gallery, update same association-key not the next one
// as the scope.rel contains the next association-key of the new item
Expand All @@ -119,19 +127,19 @@ export function AssociationController(content, superdesk, renditions, notify) {
: 1;

if (mediaItemsForCurrentField.length + 1 > allowedItemsCount) {
notify.error(gettextPlural(
this.notify.error(gettextPlural(
allowedItemsCount,
'Item was not added. Only 1 item is allowed for this field.',
'Item was not added. Only {{number}} items are allowed in this field.',
{number: allowedItemsCount},
));

return;
return Promise.resolve(false);
}

if (mediaItemsForCurrentField.find((mediaItem) => mediaItem._id === updated._id) != null) {
notify.error(gettext('This item is already added.'));
return;
this.notify.error(gettext('This item is already added.'));
return Promise.resolve(false);
}
}

Expand All @@ -157,12 +165,12 @@ export function AssociationController(content, superdesk, renditions, notify) {
promise = scope.onchange({item: scope.item, data: data});
}

if (callback) {
return promise.then(callback);
}
return promise.then(() => {
callback?.();

return promise;
};
return true;
});
}

/**
* @ngdoc method
Expand All @@ -173,14 +181,14 @@ export function AssociationController(content, superdesk, renditions, notify) {
* @param {Object} item Item to be edited
* @param {Function} callback Callback function
*/
this.edit = function(
edit(
scope,
item,
options: {isNew?: boolean, customRel?: string, defaultTab?: any, showMetadata?: boolean} = {},
callback = null,
) {
if (!self.isMediaEditable()) {
return;
): Promise<boolean> {
if (!this.isMediaEditable()) {
return Promise.resolve(false);
}

const _isImage = checkRenditions.isImage(item.renditions.original);
Expand All @@ -196,48 +204,48 @@ export function AssociationController(content, superdesk, renditions, notify) {

if (item.renditions && item.renditions.original) {
scope.loading = true;
return renditions.crop(item, cropOptions)
return this.renditions.crop(item, cropOptions)
.then((rendition) => {
self.updateItemAssociation(scope, rendition, options.customRel, callback);
return this.updateItemAssociation(scope, rendition, options.customRel, callback);
})
.finally(() => {
scope.loading = false;
});
} else {
scope.loading = false;
}

self.updateItemAssociation(scope, item, options.customRel, callback);
};
return this.updateItemAssociation(scope, item, options.customRel, callback);
}
}

this.addAssociation = function(scope, __item: IArticle): void {
addAssociation(scope, __item: IArticle): Promise<boolean> {
if (!scope.editable) {
return;
return Promise.resolve(false);
}

content.dropItem(__item)
return this.content.dropItem(__item)
.then((item) => {
if (item.lock_user) {
notify.error(gettext('Item is locked. Cannot associate media item.'));
return;
this.notify.error(gettext('Item is locked. Cannot associate media item.'));
return false;
}

// save generated association id in order to be able to update the same item after editing.
const originalRel = scope.rel;

if (self.isMediaEditable(item) && get(item, '_type') === 'externalsource') {
// if media is editable then association will be updated by self.edit method
return renditions.ingest(item)
.then((_item) => self.edit(scope, _item, {customRel: originalRel}));
if (this.isMediaEditable(item) && get(item, '_type') === 'externalsource') {
// if media is editable then association will be updated by this.edit method
return this.renditions.ingest(item)
.then((_item) => this.edit(scope, _item, {customRel: originalRel}));
} else {
// Update the association if media is not editable.
self.updateItemAssociation(scope, item, null, null, true);
return this.updateItemAssociation(scope, item, null, null, true);
}
})
.finally(() => {
scope.loading = false;
});
};
}

/**
* @ngdoc method
Expand All @@ -246,30 +254,32 @@ export function AssociationController(content, superdesk, renditions, notify) {
* @param {Object} scope Directive scope
* @param {Object} event Drop event
*/
this.initializeUploadOnDrop = function(scope, event): void {
initializeUploadOnDrop(scope, event): Promise<boolean> {
const superdeskType = getSuperdeskType(event);

if (superdeskType === 'Files') {
if (!scope.editable) {
return;
return Promise.resolve(false);
}

if (self.isMediaEditable()) {
if (this.isMediaEditable()) {
const files = event.originalEvent.dataTransfer.files;

return self.uploadAndCropImages(scope, files);
return this.uploadAndCropImages(scope, files);
}

return;
return Promise.resolve(false);
}

const __item: IArticle = JSON.parse(event.originalEvent.dataTransfer.getData(superdeskType));

scope.loading = true;
this.addAssociation(scope, __item);
};
return this.addAssociation(scope, __item);
}
}

AssociationController.$inject = ['content', 'superdesk', 'renditions', 'notify'];

const isImage = (rendition) => {
return startsWith(rendition.mimetype, 'image');
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ describe('item association directive', () => {

event.preventDefault = jasmine.createSpy('preventDefault');
event.stopPropagation = jasmine.createSpy('stopPropagation');
scope.onChange = jasmine.createSpy('onchange');
scope.save = jasmine.createSpy('save');
scope.onChange = jasmine.createSpy('onchange').and.returnValue(Promise.resolve(true));
scope.save = jasmine.createSpy('save').and.returnValue(Promise.resolve(true));
elem.triggerHandler(event);
$rootScope.$digest();
expect(renditions.ingest).toHaveBeenCalled();
Expand All @@ -100,8 +100,9 @@ describe('item association directive', () => {

event.preventDefault = jasmine.createSpy('preventDefault');
event.stopPropagation = jasmine.createSpy('stopPropagation');
scope.onChange = jasmine.createSpy('onchange');
scope.save = jasmine.createSpy('save');
scope.onChange = jasmine.createSpy('onchange').and.returnValue(Promise.resolve(true));
scope.save = jasmine.createSpy('save').and.returnValue(Promise.resolve(true));

elem.triggerHandler(event);
$rootScope.$digest();
expect(renditions.ingest).toHaveBeenCalled();
Expand Down Expand Up @@ -134,8 +135,8 @@ describe('item association directive', () => {

event.preventDefault = jasmine.createSpy('preventDefault');
event.stopPropagation = jasmine.createSpy('stopPropagation');
scope.onChange = jasmine.createSpy('onchange');
scope.save = jasmine.createSpy('save');
scope.onChange = jasmine.createSpy('onchange').and.returnValue(Promise.resolve(true));
scope.save = jasmine.createSpy('save').and.returnValue(Promise.resolve(true));
elem.triggerHandler(event);
$rootScope.$digest();
expect(renditions.ingest).not.toHaveBeenCalled();
Expand Down
Loading

0 comments on commit 4708ee9

Please sign in to comment.