diff --git a/frontend/app/js/editor/editor.controller.js b/frontend/app/js/editor/editor.controller.js index a3dceb09e..454e16e63 100644 --- a/frontend/app/js/editor/editor.controller.js +++ b/frontend/app/js/editor/editor.controller.js @@ -57,6 +57,18 @@ angular.module('bonitasoft.designer.editor').controller('EditorCtrl', function($ }); }); + keyBindingService.bind(['d', 'ctrl+d'], function(e) { + e.preventDefault(); + + if (!$scope.currentComponent) { + return; + } + + $scope.$apply(function() { + $scope.duplicateCurrentComponent(); + }); + }); + keyBindingService.bind('right', function() { moveSelection(+1); }); @@ -77,7 +89,7 @@ angular.module('bonitasoft.designer.editor').controller('EditorCtrl', function($ } $scope.$on('$destroy', function() { - keyBindingService.unbind(['del', 'right', 'left']); + keyBindingService.unbind(['del', 'right', 'd', 'ctrl+d', 'left']); }); $scope.componentClasses = componentUtils.getResolutionClasses; @@ -266,6 +278,24 @@ angular.module('bonitasoft.designer.editor').controller('EditorCtrl', function($ $scope.currentComponent = null; }; + /** + * Duplicates the currently selected component, inserts it after the currently + * selected one and selects it. + */ + $scope.duplicateCurrentComponent = function() { + var component = $scope.currentComponent; + var currentRow = component.$$parentContainerRow.row; + var componentIndex = currentRow.indexOf(component); + var newComponent = whiteboardComponentWrapper.wrapWidget( + component.$$widget, + angular.copy(component), + component.$$parentContainerRow + ); + delete newComponent.reference; + arrays.insertAtPosition(newComponent, componentIndex, currentRow); + $scope.selectComponent(newComponent); + }; + /** * * @returns {boolean} @@ -437,6 +467,7 @@ angular.module('bonitasoft.designer.editor').controller('EditorCtrl', function($ componentClasses: $scope.componentClasses, removeCurrentRow: $scope.removeCurrentRow, removeCurrentComponent: $scope.removeCurrentComponent, + duplicateCurrentComponent: $scope.duplicateCurrentComponent, switchCurrentComponent: $scope.switchCurrentComponent, rowSize: $scope.rowSize, isCurrentRow: $scope.isCurrentRow, diff --git a/frontend/app/js/editor/whiteboard/component-mover.directive.js b/frontend/app/js/editor/whiteboard/component-mover.directive.js index 6be006db1..755ccd47e 100644 --- a/frontend/app/js/editor/whiteboard/component-mover.directive.js +++ b/frontend/app/js/editor/whiteboard/component-mover.directive.js @@ -22,6 +22,7 @@ angular.module('bonitasoft.designer.editor.whiteboard').directive('componentMove scope: { component: '=', onDelete: '&', + onDuplicate: '&', onSwitch: '&' }, templateUrl: 'js/editor/whiteboard/component-mover.html', diff --git a/frontend/app/js/editor/whiteboard/component-mover.html b/frontend/app/js/editor/whiteboard/component-mover.html index b1c97ffaf..769f79b99 100644 --- a/frontend/app/js/editor/whiteboard/component-mover.html +++ b/frontend/app/js/editor/whiteboard/component-mover.html @@ -3,5 +3,6 @@ + diff --git a/frontend/app/js/editor/whiteboard/component.html b/frontend/app/js/editor/whiteboard/component.html index 12a939ff6..d7d417d49 100644 --- a/frontend/app/js/editor/whiteboard/component.html +++ b/frontend/app/js/editor/whiteboard/component.html @@ -1,5 +1,5 @@
- +
diff --git a/frontend/test/unit/editor/editor.controller.spec.js b/frontend/test/unit/editor/editor.controller.spec.js index 9eba884a9..70b25ab3e 100644 --- a/frontend/test/unit/editor/editor.controller.spec.js +++ b/frontend/test/unit/editor/editor.controller.spec.js @@ -1,4 +1,4 @@ -import aWidget from '../utils/builders/WidgetElementBuilder'; +import aWidget from '../utils/builders/WidgetElementBuilder'; describe('EditorCtrl', function() { var $scope, pageRepo, $q, $state, $window, componentUtils, whiteboardService, $timeout, widgetRepo; @@ -335,6 +335,36 @@ describe('EditorCtrl', function() { expect(whiteboardService.triggerRowRemoved).not.toHaveBeenCalled(); }); + it('should be able to duplicate the current component', function() { + + var container = { + rows: [ + [] + ] + }; + + $scope.currentContainerRow = { + container: container, + row: container.rows[0] + }; + + var component = aWidget().withParentContainerRow($scope.currentContainerRow); + + var dragData = { + create: function() { + return component; + } + }; + + $scope.addComponent(dragData, 0); + expect(container.rows[0].length).toBe(1); + + $scope.duplicateCurrentComponent(); + + expect(container.rows[0].length).toBe(2); + expect($scope.currentComponent).not.toBe(component); + }); + it('should remove the current component and trigger "removed" while removing it', function() { var container = {