Repository: ambari Updated Branches: refs/heads/branch-2.5 7f9a5123e -> bf25d310f
AMBARI-20303. HiveView2.0: Issues in worksheet (Venkata Sairam via pallavkul) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/bf25d310 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/bf25d310 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/bf25d310 Branch: refs/heads/branch-2.5 Commit: bf25d310f6755c50b12a6fafa02fd097c02d9658 Parents: 7f9a512 Author: pallavkul <pallav....@gmail.com> Authored: Tue Mar 7 14:25:58 2017 +0530 Committer: pallavkul <pallav....@gmail.com> Committed: Tue Mar 7 14:27:29 2017 +0530 ---------------------------------------------------------------------- .../main/resources/ui/app/models/worksheet.js | 1 + .../src/main/resources/ui/app/routes/queries.js | 5 +- .../main/resources/ui/app/routes/queries/new.js | 9 ++- .../resources/ui/app/routes/queries/query.js | 85 +++++++++++++++++++- .../src/main/resources/ui/app/styles/app.scss | 5 ++ .../main/resources/ui/app/templates/queries.hbs | 11 ++- .../ui/app/templates/queries/query.hbs | 35 +++++++- 7 files changed, 140 insertions(+), 11 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/bf25d310/contrib/views/hive20/src/main/resources/ui/app/models/worksheet.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/resources/ui/app/models/worksheet.js b/contrib/views/hive20/src/main/resources/ui/app/models/worksheet.js index f820ea0..12a681c 100644 --- a/contrib/views/hive20/src/main/resources/ui/app/models/worksheet.js +++ b/contrib/views/hive20/src/main/resources/ui/app/models/worksheet.js @@ -38,6 +38,7 @@ export default DS.Model.extend({ logFile: DS.attr('string', {defaultValue: ""}), logResults: DS.attr('string', {defaultValue: ""}), isQueryRunning: DS.attr('boolean', {defaultValue: false}), + isQueryDirty: DS.attr('boolean', {defaultValue: false}), isQueryResultContainer: DS.attr('boolean', {defaultValue: false}), visualExplainJson: DS.attr({defaultValue: null}), lastResultRoute: DS.attr({defaultValue: ""}), http://git-wip-us.apache.org/repos/asf/ambari/blob/bf25d310/contrib/views/hive20/src/main/resources/ui/app/routes/queries.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/resources/ui/app/routes/queries.js b/contrib/views/hive20/src/main/resources/ui/app/routes/queries.js index 4ef3834..8c7c17c 100644 --- a/contrib/views/hive20/src/main/resources/ui/app/routes/queries.js +++ b/contrib/views/hive20/src/main/resources/ui/app/routes/queries.js @@ -19,9 +19,12 @@ import Ember from 'ember'; export default Ember.Route.extend({ - + 'worksheetCount': 1, actions: { createNewWorksheet(){ + let id = this.get('worksheetCount'); + this.get('controller').set('worksheetCount',parseInt(id)+1); + this.set('worksheetCount',parseInt(id)+1); this.transitionTo('queries.new'); } } http://git-wip-us.apache.org/repos/asf/ambari/blob/bf25d310/contrib/views/hive20/src/main/resources/ui/app/routes/queries/new.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/resources/ui/app/routes/queries/new.js b/contrib/views/hive20/src/main/resources/ui/app/routes/queries/new.js index 7bd2214..b48b8df 100644 --- a/contrib/views/hive20/src/main/resources/ui/app/routes/queries/new.js +++ b/contrib/views/hive20/src/main/resources/ui/app/routes/queries/new.js @@ -21,11 +21,18 @@ import Ember from 'ember'; export default Ember.Route.extend({ beforeModel() { let existingWorksheets = this.store.peekAll('worksheet'); - let newWorksheetName = `worksheet${existingWorksheets.get('length') + 1}`; + let newWorksheetName = 'worksheet'; + if(!this.controllerFor("queries").worksheetCount) { + newWorksheetName = newWorksheetName + 1; + } else { + let id = parseInt(this.controllerFor("queries").worksheetCount); + newWorksheetName = newWorksheetName + id; + } let newWorksheetTitle = newWorksheetName.capitalize(); this.store.createRecord('worksheet', { id: newWorksheetName, title: newWorksheetTitle, + isQueryDirty: false, //query: 'select 1;', //owner: 'admin', selected: true http://git-wip-us.apache.org/repos/asf/ambari/blob/bf25d310/contrib/views/hive20/src/main/resources/ui/app/routes/queries/query.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/resources/ui/app/routes/queries/query.js b/contrib/views/hive20/src/main/resources/ui/app/routes/queries/query.js index 062f93a..e1ab620 100644 --- a/contrib/views/hive20/src/main/resources/ui/app/routes/queries/query.js +++ b/contrib/views/hive20/src/main/resources/ui/app/routes/queries/query.js @@ -80,7 +80,6 @@ export default Ember.Route.extend(UILoggerMixin, { this._super(...arguments); this.get("tezViewInfo").getTezViewInfo(); - let self = this, selectedDb; let alldatabases = this.store.peekAll('database'); controller.set('alldatabases',alldatabases); @@ -127,7 +126,6 @@ export default Ember.Route.extend(UILoggerMixin, { controller.set('worksheet', model); - controller.set('selectedTablesModels',model.get('selectedTablesModels') || selectedTablesModels ); controller.set('selectedMultiDb', model.get('selectedMultiDb') || selectedMultiDb); @@ -175,6 +173,12 @@ export default Ember.Route.extend(UILoggerMixin, { this.get('controller.model').set('selectedDb', null); } }, + closeWorksheetAfterSave(){ + let tabDataToClose = this.get('controller.model').get('tabDataToClose'); + if(tabDataToClose) { + this.send('closeWorksheet', tabDataToClose.index, tabDataToClose.id); + } + }, actions: { resetDefaultWorksheet(){ @@ -230,8 +234,13 @@ export default Ember.Route.extend(UILoggerMixin, { }, updateQuery(query){ - this.get('controller').set('currentQuery', query); this.get('controller.model').set('query', query); + if(Ember.isBlank(query)){ + this.get('controller.model').set('isQueryDirty', false); + } else if(this.get('controller').get('currentQuery').indexOf(query) !== 0){ + this.get('controller.model').set('isQueryDirty', true); + } + this.get('controller').set('currentQuery', query); }, executeQuery(isVisualExplainQuery){ @@ -492,8 +501,72 @@ export default Ember.Route.extend(UILoggerMixin, { this.transitionTo('queries.query.results', myWs); }, 1 * 100); }, + confirmWorksheetClose(index, id) { + let existingWorksheets = this.store.peekAll('worksheet'); + let selectedWorksheet = existingWorksheets.filterBy('id', id.toLowerCase()).get('firstObject'); + if(selectedWorksheet.get("isQueryDirty")){ + this.transitionTo('queries.query', id); + } + Ember.run.later(() => { + + if(this.get('controller.model').get('isQueryDirty')) { + this.get('controller.model').set('tabDataToClose', {index:index, id:id}) + this.send('openWorksheetModal'); + } else { + this.send('closeWorksheet', index, id); + } + }, 1 * 100); + }, + closeWorksheet(index, id) { + let existingWorksheets = this.store.peekAll('worksheet'); + let selectedWorksheet = existingWorksheets.filterBy('id', id.toLowerCase()).get('firstObject'); + this.store.unloadRecord(selectedWorksheet); + this.controllerFor('queries').set('worksheets', this.store.peekAll('worksheet')); + let idToTransition = 0; + if(selectedWorksheet.get('selected')) { + if(index){ + idToTransition = existingWorksheets.get('content')[parseInt(index)-1].id; + } else { + idToTransition = existingWorksheets.get('content')[1].id; + } + this.transitionTo('queries.query', idToTransition); + } else { + idToTransition = existingWorksheets.get('content')[existingWorksheets.get('length')-1].id; + } + }, + openWorksheetRenameModal(title){ + let wf = this.store.peekAll('worksheet').filterBy('id', this.paramsFor('queries.query').worksheetId.toLowerCase()).get('firstObject'); + this.get('controller').set('worksheetTitle', title); + this.get('controller').set('showWorksheetRenameModal', true); + this.get('controller').set('renameWorksheetModalSuccess', false); + }, + closeRenameWorksheetModal() { + this.get('controller').set('showWorksheetRenameModal', false); + }, + renameWorksheetModal(){ + let wf = this.store.peekAll('worksheet').filterBy('id', this.paramsFor('queries.query').worksheetId.toLowerCase()).get('firstObject'); + let newTitle = Ember.$('#worksheet-title').val(); + if(wf) { + wf.set('title', newTitle); + this.get('controller').set('renameWorksheetModalSuccess', true); + } else { + this.get('controller').set('renameWorksheetModalFail', true); + } + + Ember.run.later(() => { + this.get('controller').set('showWorksheetRenameModal', false); + }, 2 * 1000); + }, openWorksheetModal(){ + let originalQuery = this.get('controller').get('currentQuery'); + if(Ember.isBlank(originalQuery)) { + this.get('logger').danger('Query cannot be empty.'); + this.send('resetDefaultWorksheet'); + return; + } + let wf = this.store.peekAll('worksheet').filterBy('id', this.paramsFor('queries.query').worksheetId.toLowerCase()).get('firstObject'); + this.get('controller').set('worksheetTitle', wf.get('title')); this.get('controller').set('showWorksheetModal', true); }, @@ -527,10 +600,12 @@ export default Ember.Route.extend(UILoggerMixin, { console.log('saved query saved'); this.get('controller.model').set('title', newTitle); + this.get('controller.model').set('isQueryDirty', false); this.get('controller').set('worksheetModalSuccess', true); Ember.run.later(() => { this.get('controller').set('showWorksheetModal', false); + this.closeWorksheetAfterSave(); }, 2 * 1000); }); @@ -539,7 +614,9 @@ export default Ember.Route.extend(UILoggerMixin, { closeWorksheetModal(){ this.get('controller').set('showWorksheetModal', false); - }, + this.closeWorksheetAfterSave(); + this.get('controller.model').set('tabDataToClose', null) + }, expandQueryEdidorPanel(){ if(!this.get('isQueryEdidorPaneExpanded')){ http://git-wip-us.apache.org/repos/asf/ambari/blob/bf25d310/contrib/views/hive20/src/main/resources/ui/app/styles/app.scss ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/resources/ui/app/styles/app.scss b/contrib/views/hive20/src/main/resources/ui/app/styles/app.scss index 6b7fc6a..1b18955 100644 --- a/contrib/views/hive20/src/main/resources/ui/app/styles/app.scss +++ b/contrib/views/hive20/src/main/resources/ui/app/styles/app.scss @@ -953,3 +953,8 @@ rect.operator__box { margin-top: auto !important; top: 200px !important; } + +.closeTab { + cursor: pointer; + padding-left:10px; +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/bf25d310/contrib/views/hive20/src/main/resources/ui/app/templates/queries.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/resources/ui/app/templates/queries.hbs b/contrib/views/hive20/src/main/resources/ui/app/templates/queries.hbs index b8e19da..17b7768 100644 --- a/contrib/views/hive20/src/main/resources/ui/app/templates/queries.hbs +++ b/contrib/views/hive20/src/main/resources/ui/app/templates/queries.hbs @@ -18,9 +18,14 @@ <div class="worksheet-container"> <ul class="worksheet-nav row nav nav-tabs inverse"> - {{#each worksheets as |worksheet| }} - <li class="{{if worksheet.selected 'active'}}" style=""> - {{#link-to 'queries.query' worksheet.id classBinding='worksheet.selected:active'}}{{ worksheet.title }}{{/link-to}} + {{#each worksheets as |worksheet index| }} + <li class="{{if worksheet.selected 'active'}}" style="" {{action "openWorksheetRenameModal" wf.title on="doubleClick"}}> + {{#link-to 'queries.query' worksheet.id classBinding='worksheet.selected:active' }}{{ worksheet.title }} + {{#if worksheet.isQueryDirty}}*{{/if}} + {{#if (gt worksheets.length 1)}} + <span class="closeTab" {{action "confirmWorksheetClose" index worksheet.id bubbles=false }}>{{fa-icon "times"}}</span> + {{/if}} + {{/link-to}} </li> {{/each}} <li> http://git-wip-us.apache.org/repos/asf/ambari/blob/bf25d310/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query.hbs b/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query.hbs index 8a771eb..989cfc3 100644 --- a/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query.hbs +++ b/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query.hbs @@ -116,7 +116,7 @@ <div class="form-group"> <label for="title" class="col-sm-2 control-label">Title</label> <div class="col-sm-10"> - {{input type="text" class="form-control" id="worksheet-title" placeholder="Title" value=worksheet.title }} + {{input type="text" class="form-control" id="worksheet-title" placeholder="Title" value=worksheetTitle }} </div> </div> {{#if worksheetModalSuccess }} @@ -129,7 +129,7 @@ </div> <div class="modal-footer"> - <button type="button" class="btn btn-default" {{action "saveWorksheetModal"}}>{{fa-icon "check"}} Save</button> + <button type="button" class="btn btn-default" disabled={{not worksheetTitle}} {{action "saveWorksheetModal"}}>{{fa-icon "check"}} Save</button> <button type="button" class="btn btn-default" {{action "closeWorksheetModal"}}>{{fa-icon "close"}}Cancel </button> </div> @@ -137,3 +137,34 @@ {{/modal-dialog}} {{/if}} +{{#if showWorksheetRenameModal}} + {{#modal-dialog translucentOverlay=true clickOutsideToClose=true container-class="modal-dialog modal-sm"}} + <div class="modal-content"> + <div class="modal-header"> + <h4 class="modal-title">Renaming worksheet</h4> + </div> + <div class="modal-body"> + <div class="form-horizontal"> + <div class="form-group"> + <label for="title" class="col-sm-2 control-label">Title</label> + <div class="col-sm-10"> + {{input type="text" class="form-control" id="worksheet-title" placeholder="Title" value=worksheetTitle }} + </div> + </div> + {{#if renameWorksheetModalSuccess }} + <div class="text-success">Renamed successfully.</div> + {{/if}} + {{#if renameWorksheetModalFail }} + <div class="text-danger">Error while renaming.</div> + {{/if}} + </div> + </div> + + <div class="modal-footer"> + <button type="button" class="btn btn-default" disabled={{not worksheetTitle}} {{action "renameWorksheetModal"}}>{{fa-icon "check"}} Save</button> + <button type="button" class="btn btn-default" {{action "closeRenameWorksheetModal"}}>{{fa-icon "close"}}Cancel + </button> + </div> + </div> + {{/modal-dialog}} +{{/if}}