Repository: zeppelin Updated Branches: refs/heads/master 15a6ee520 -> 401c81370
ZEPPELIN-1440 Notebook clone: prefix name with "Copy of" and end with count ### What is this PR for? While cloning a notebook create a new name using the current notebook name by prefixing "Copy of" and end with count e.g: name: test pre-filled clone name: Copy of test 1 ### What type of PR is it? Improvement ### What is the Jira issue? https://issues.apache.org/jira/browse/ZEPPELIN-1440 ### How should this be tested? Create a new book and clone on ui or see unit test in notename.js ### Screenshots (if appropriate) Before <img width="1221" alt="before" src="https://cloud.githubusercontent.com/assets/2031306/18517800/302309bc-7abb-11e6-8808-b98b9b75a0f4.png"> After <img width="1247" alt="after" src="https://cloud.githubusercontent.com/assets/2031306/18517805/349d27f2-7abb-11e6-8702-0c064db52697.png"> ### Questions: * Does the licenses files need update? na * Is there breaking changes for older versions? na * Does this needs documentation? na Author: Renjith Kamath <[email protected]> Closes #1429 from r-kamath/ZEPPELIN-1440 and squashes the following commits: b8b4f24 [Renjith Kamath] ZEPPELIN-1440 remove redundant beforeEach from test 282e912 [Renjith Kamath] Merge remote-tracking branch 'upstream/master' into ZEPPELIN-1440 9770a20 [Renjith Kamath] ZEPPELIN-1440 remove prefix. fix folder bug b1f5b5c [Renjith Kamath] ZEPPELIN-1440 Notebook clone: prefix name with "Copy of" and endwith count Project: http://git-wip-us.apache.org/repos/asf/zeppelin/repo Commit: http://git-wip-us.apache.org/repos/asf/zeppelin/commit/401c8137 Tree: http://git-wip-us.apache.org/repos/asf/zeppelin/tree/401c8137 Diff: http://git-wip-us.apache.org/repos/asf/zeppelin/diff/401c8137 Branch: refs/heads/master Commit: 401c81370c48930a4887a529f522773dd6ffb66e Parents: 15a6ee5 Author: Renjith Kamath <[email protected]> Authored: Thu Sep 29 10:50:14 2016 +0530 Committer: Renjith Kamath <[email protected]> Committed: Fri Sep 30 11:52:00 2016 +0530 ---------------------------------------------------------------------- .../src/app/notebook/notebook-actionBar.html | 2 +- .../noteName-create/notename.controller.js | 31 ++++++++++++++- .../noteName-create/visible.directive.js | 13 +++--- zeppelin-web/test/spec/controllers/notename.js | 42 ++++++++++++++++++++ 4 files changed, 79 insertions(+), 9 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/zeppelin/blob/401c8137/zeppelin-web/src/app/notebook/notebook-actionBar.html ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/notebook/notebook-actionBar.html b/zeppelin-web/src/app/notebook/notebook-actionBar.html index 22ae67c..fcc0e67 100644 --- a/zeppelin-web/src/app/notebook/notebook-actionBar.html +++ b/zeppelin-web/src/app/notebook/notebook-actionBar.html @@ -53,7 +53,7 @@ limitations under the License. <button type="button" class="btn btn-default btn-xs" ng-hide="viewOnly" - tooltip-placement="bottom" tooltip="Clone the notebook" + tooltip-placement="bottom" tooltip="Clone the notebook" data-source-note-name="{{note.name}}" data-toggle="modal" data-target="#noteNameModal" data-clone="true" > <i class="fa fa-copy"></i> http://git-wip-us.apache.org/repos/asf/zeppelin/blob/401c8137/zeppelin-web/src/components/noteName-create/notename.controller.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/components/noteName-create/notename.controller.js b/zeppelin-web/src/components/noteName-create/notename.controller.js index 4f85dda..e42f862 100644 --- a/zeppelin-web/src/components/noteName-create/notename.controller.js +++ b/zeppelin-web/src/components/noteName-create/notename.controller.js @@ -36,9 +36,10 @@ angular.module('zeppelinWebApp').controller('NotenameCtrl', function($scope, not vm.createNote(); }; - vm.preVisible = function(clone) { - $scope.note.notename = vm.newNoteName(); + vm.preVisible = function(clone, sourceNoteName) { vm.clone = clone; + vm.sourceNoteName = sourceNoteName; + $scope.note.notename = vm.clone ? vm.cloneNoteName() : vm.newNoteName(); $scope.$apply(); }; @@ -56,4 +57,30 @@ angular.module('zeppelinWebApp').controller('NotenameCtrl', function($scope, not return 'Untitled Note ' + newCount; }; + vm.cloneNoteName = function() { + var copyCount = 1; + var newCloneName = ''; + var lastIndex = vm.sourceNoteName.lastIndexOf(' '); + var endsWithNumber = !!vm.sourceNoteName.match('^.+?\\s\\d$'); + var noteNamePrefix = endsWithNumber ? vm.sourceNoteName.substr(0, lastIndex) : vm.sourceNoteName; + var regexp = new RegExp('^' + noteNamePrefix + ' .+'); + + angular.forEach(vm.notes.flatList, function(noteName) { + noteName = noteName.name; + if (noteName.match(regexp)) { + var lastCopyCount = noteName.substr(lastIndex).trim(); + newCloneName = noteNamePrefix; + lastCopyCount = parseInt(lastCopyCount); + if (copyCount <= lastCopyCount) { + copyCount = lastCopyCount + 1; + } + } + }); + + if (!newCloneName) { + newCloneName = vm.sourceNoteName; + } + return newCloneName + ' ' + copyCount; + }; + }); http://git-wip-us.apache.org/repos/asf/zeppelin/blob/401c8137/zeppelin-web/src/components/noteName-create/visible.directive.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/components/noteName-create/visible.directive.js b/zeppelin-web/src/components/noteName-create/visible.directive.js index d0fe977..e50864b 100644 --- a/zeppelin-web/src/components/noteName-create/visible.directive.js +++ b/zeppelin-web/src/components/noteName-create/visible.directive.js @@ -21,17 +21,18 @@ angular.module('zeppelinWebApp').directive('modalvisible', function() { postVisibleCallback: '&postvisiblecallback', targetinput: '@targetinput' }, - link: function(scope, elem, attrs) { + link: function(scope, element, attrs) { // Add some listeners var previsibleMethod = scope.preVisibleCallback; var postVisibleMethod = scope.postVisibleCallback; - elem.on('show.bs.modal',function(e) { - var relatedTgt = angular.element(e.relatedTarget); - var clone = relatedTgt.data('clone'); + element.on('show.bs.modal',function(e) { + var relatedTarget = angular.element(e.relatedTarget); + var clone = relatedTarget.data('clone'); + var sourceNoteName = relatedTarget.data('source-note-name'); var cloneNote = clone ? true : false; - previsibleMethod()(cloneNote); + previsibleMethod()(cloneNote, sourceNoteName); }); - elem.on('shown.bs.modal', function(e) { + element.on('shown.bs.modal', function(e) { if (scope.targetinput) { angular.element(e.target).find('input#' + scope.targetinput).select(); } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/401c8137/zeppelin-web/test/spec/controllers/notename.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/test/spec/controllers/notename.js b/zeppelin-web/test/spec/controllers/notename.js new file mode 100644 index 0000000..8f6b85a --- /dev/null +++ b/zeppelin-web/test/spec/controllers/notename.js @@ -0,0 +1,42 @@ +'use strict'; + +describe('Controller: NotenameCtrl', function() { + beforeEach(module('zeppelinWebApp')); + + var scope; + var ctrl; + var notebookList; + + beforeEach(inject(function($injector, $rootScope, $controller) { + notebookList = $injector.get('notebookListDataFactory'); + scope = $rootScope.$new(); + ctrl = $controller('NotenameCtrl', { + $scope: scope, + notebookListDataFactory: notebookList + }); + })); + + it('should create a new name from current name when cloneNoteName is called', function() { + var notesList = [ + {name: 'dsds 1', id: '1'}, + {name: 'dsds 2', id: '2'}, + {name: 'test name', id: '3'}, + {name: 'aa bb cc', id: '4'}, + {name: 'Untitled Note 6', id: '4'} + ]; + + notebookList.setNotes(notesList); + + ctrl.sourceNoteName = 'test name'; + expect(ctrl.cloneNoteName()).toEqual('test name 1'); + ctrl.sourceNoteName = 'aa bb cc'; + expect(ctrl.cloneNoteName()).toEqual('aa bb cc 1'); + ctrl.sourceNoteName = 'Untitled Note 6'; + expect(ctrl.cloneNoteName()).toEqual('Untitled Note 7'); + ctrl.sourceNoteName = 'My_note'; + expect(ctrl.cloneNoteName()).toEqual('My_note 1'); + ctrl.sourceNoteName = 'dsds 2'; + expect(ctrl.cloneNoteName()).toEqual('dsds 3'); + }); + +});
