Canh Ngo pushed to branch feature/cmng-psp1 at cms-community / hippo-addon-channel-manager
Commits: 78696d37 by Canh Ngo at 2016-03-23T12:49:13+01:00 CHANNELMGR-511: fixed! - - - - - 41d04d8d by Canh Ngo at 2016-03-23T14:24:46+01:00 CHANNELMGR-511: register new container after adding/removing a component with dragula Containers are re-rendered, so the old container element that was registered with dragula no longer exists in the DOM. We now replace the old with the new container elements in the drake.containers array. - - - - - 5 changed files: - frontend-ng/src/angularjs/channel/hippoIframe/componentAdder/componentAdder.controller.js - frontend-ng/src/angularjs/channel/hippoIframe/dragDrop.service.js - frontend-ng/src/angularjs/channel/hippoIframe/hippoIframe.controller.js - frontend-ng/src/angularjs/channel/hippoIframe/hippoIframe.controller.spec.js - frontend-ng/src/angularjs/channel/page/pageStructure.service.js Changes: ===================================== frontend-ng/src/angularjs/channel/hippoIframe/componentAdder/componentAdder.controller.js ===================================== --- a/frontend-ng/src/angularjs/channel/hippoIframe/componentAdder/componentAdder.controller.js +++ b/frontend-ng/src/angularjs/channel/hippoIframe/componentAdder/componentAdder.controller.js @@ -15,7 +15,7 @@ */ export class ComponentAdderCtrl { - constructor($scope, $element, ComponentAdderService, PageStructureService, CatalogService) { + constructor($scope, $log, $element, ComponentAdderService, PageStructureService, CatalogService, DragDropService) { 'ngInject'; const drake = window.dragula({ @@ -33,7 +33,7 @@ export class ComponentAdderCtrl { }); drake.on('cloned', (clone, original) => { $scope.$apply(() => { - this.newComponent = CatalogService.getComponentByDomElement(original); // remember the to-be-added component + this.selectedCatalogItem = CatalogService.getComponentByDomElement(original); $element.addClass('add-mode'); }); }); @@ -64,8 +64,16 @@ export class ComponentAdderCtrl { $(target).removeClass('has-shadow'); $(el).detach(); // delete the (hidden) dropped DOM element. - PageStructureService.addComponentToContainer(this.newComponent, target) - .then((component) => PageStructureService.showComponentProperties(component)); + const container = PageStructureService.getContainerByOverlayElement(target); + if (container) { + PageStructureService.addComponentToContainer(this.selectedCatalogItem, container) + .then((newComponent) => { + DragDropService.replaceContainer(container, newComponent.getContainer()); + PageStructureService.showComponentProperties(newComponent); + }); + } else { + $log.debug(`Cannot add catalog item ${this.selectedCatalogItem.id} because container cannot be found for overlay element`, target); + } }); } }); ===================================== frontend-ng/src/angularjs/channel/hippoIframe/dragDrop.service.js ===================================== --- a/frontend-ng/src/angularjs/channel/hippoIframe/dragDrop.service.js +++ b/frontend-ng/src/angularjs/channel/hippoIframe/dragDrop.service.js @@ -74,10 +74,7 @@ export class DragDropService { this.drake.on('dragend', (el) => this._onStopDrag(el)); this.drake.on('drop', (el, target, source, sibling) => this._onDrop(el, target, source, sibling)); - this._onComponentClick(containers, (component) => { - this._onStopDrag(component.getBoxElement()); - this.PageStructureService.showComponentProperties(component); - }); + this._handleComponentClick(containers); }); } @@ -91,18 +88,29 @@ export class DragDropService { return this.DomService.addScript(iframe, dragulaJs); } - _onComponentClick(containers, callback) { + _handleComponentClick(containers) { containers.forEach((container) => { container.getComponents().forEach((component) => { component.getBoxElement().on('mouseup', () => { if (!this.drake.dragging) { - callback(component); + this._onStopDrag(component.getBoxElement()); + this.PageStructureService.showComponentProperties(component); } }); }); }); } + replaceContainer(oldContainer, newContainer) { + return this.dragulaPromise.then(() => { + const oldIndex = this.drake.containers.indexOf(oldContainer.getBoxElement()[0]); + if (oldIndex >= 0 && newContainer) { + this.drake.containers[oldIndex] = newContainer.getBoxElement()[0]; + this._handleComponentClick([newContainer]); + } + }); + } + disable() { this._destroyDrake(); } ===================================== frontend-ng/src/angularjs/channel/hippoIframe/hippoIframe.controller.js ===================================== --- a/frontend-ng/src/angularjs/channel/hippoIframe/hippoIframe.controller.js +++ b/frontend-ng/src/angularjs/channel/hippoIframe/hippoIframe.controller.js @@ -73,11 +73,11 @@ export class HippoIframeCtrl { } deleteComponent(componentId) { - this._confirmDelete().then(() => { - this.PageStructureService.removeComponentById(componentId); - }, () => { - this.PageStructureService.showComponentProperties(this.selectedComponent); - }); + this._confirmDelete() + .then(() => this.PageStructureService.removeComponentById(componentId) + .then(({ oldContainer, newContainer }) => this.DragDropService.replaceContainer(oldContainer, newContainer)) + ) + .catch(() => this.PageStructureService.showComponentProperties(this.selectedComponent)); } _confirmDelete() { ===================================== frontend-ng/src/angularjs/channel/hippoIframe/hippoIframe.controller.spec.js ===================================== --- a/frontend-ng/src/angularjs/channel/hippoIframe/hippoIframe.controller.spec.js +++ b/frontend-ng/src/angularjs/channel/hippoIframe/hippoIframe.controller.spec.js @@ -70,7 +70,8 @@ describe('hippoIframeCtrl', () => { }); it('shows the confirmation dialog and deletes selected component on confirmation', () => { - spyOn(PageStructureService, 'removeComponentById').and.returnValue($q.resolve()); + spyOn(DragDropService, 'replaceContainer'); + spyOn(PageStructureService, 'removeComponentById').and.returnValue($q.when({ oldContainer: 'old', newContainer: 'new' })); spyOn($mdDialog, 'show').and.returnValue($q.resolve()); spyOn($mdDialog, 'confirm').and.callThrough(); @@ -81,6 +82,7 @@ describe('hippoIframeCtrl', () => { expect($mdDialog.confirm).toHaveBeenCalled(); expect($mdDialog.show).toHaveBeenCalled(); expect(PageStructureService.removeComponentById).toHaveBeenCalledWith('1234'); + expect(DragDropService.replaceContainer).toHaveBeenCalledWith('old', 'new'); }); it('shows component properties dialog after rejecting the delete operation', () => { ===================================== frontend-ng/src/angularjs/channel/page/pageStructure.service.js ===================================== --- a/frontend-ng/src/angularjs/channel/page/pageStructure.service.js +++ b/frontend-ng/src/angularjs/channel/page/pageStructure.service.js @@ -95,21 +95,24 @@ export class PageStructureService { /** * Remove the component identified by given Id * @param componentId + * @return a promise with the object { oldContainer, newContainer } */ removeComponentById(componentId) { const component = this.getComponentById(componentId); if (component) { - const container = component.getContainer(); - this.HstService.removeHstComponent(container.getId(), componentId) + const oldContainer = component.getContainer(); + return this.HstService.removeHstComponent(oldContainer.getId(), componentId) .then(() => { this.ChannelService.recordOwnChange(); - this._renderContainer(container); + return this._renderContainer(oldContainer).then((newContainer) => { // eslint-disable-line arrow-body-style + return { oldContainer, newContainer }; + }); }); // TODO handle error - } else { - this.$log.debug(`Was asked to remove component with ID '${componentId}', but couldn't find it in the page structure.`); } + this.$log.debug(`Could not remove component with ID '${componentId}' because it does not exist in the page structure.`); + return this.$q.reject(); } getContainerByIframeElement(containerIFrameElement) { @@ -166,6 +169,12 @@ export class PageStructureService { this.OverlaySyncService.syncIframe(); } + /** + * Lets the back-end re-render a container. + * @param container + * @returns {*} a promise with the new container object + * @private + */ _renderContainer(container) { return this.RenderingService.fetchContainerMarkup(container) .then((markup) => this._updateContainer(container, markup)); @@ -173,7 +182,7 @@ export class PageStructureService { _updateContainer(container, newMarkup) { // consider following three actions to be an atomic operation - this._replaceContainer(container, this._createContainer(container.replaceDOM(newMarkup))); + return this._replaceContainer(container, this._createContainer(container.replaceDOM(newMarkup))); } _replaceComponent(oldComponent, newComponent) { @@ -185,22 +194,16 @@ export class PageStructureService { } } - addComponentToContainer(catalogComponent, overlayDomElementOfContainer) { - const container = this._findContainerByOverlayElement(overlayDomElementOfContainer); - - if (container) { - return this.HstService.addHstComponent(catalogComponent, container.getId()) - .then((newComponentJson) => { - this.ChannelService.recordOwnChange(); - return this._renderContainer(container).then(() => this.getComponentById(newComponentJson.id)); - }); - // TODO: handle error - } - console.log('container not found'); - return this.$q.reject('container not found'); + addComponentToContainer(catalogComponent, container) { + return this.HstService.addHstComponent(catalogComponent, container.getId()) + .then((newComponentJson) => { + this.ChannelService.recordOwnChange(); + return this._renderContainer(container).then(() => this.getComponentById(newComponentJson.id)); + }); + // TODO: handle error } - _findContainerByOverlayElement(overlayElement) { + getContainerByOverlayElement(overlayElement) { return this.containers.find((container) => container.getOverlayElement()[0] === overlayElement); } @@ -208,13 +211,14 @@ export class PageStructureService { const index = this.containers.indexOf(oldContainer); if (index === -1) { this.$log.warn('Cannot find container', oldContainer); - return; + return null; } if (newContainer) { this.containers[index] = newContainer; } else { this.containers.splice(index, 1); } + return newContainer; } /** View it on GitLab: https://code.onehippo.org/cms-community/hippo-addon-channel-manager/compare/f1ad12c1755c9d43b74389c2ed2b10bf2323af8c...41d04d8dc1f9c1ed8c8eb58ced246f31296893eb
_______________________________________________ Hippocms-svn mailing list Hippocms-svn@lists.onehippo.org https://lists.onehippo.org/mailman/listinfo/hippocms-svn