http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/components/alert-message-widget.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/components/alert-message-widget.hbs b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/components/alert-message-widget.hbs index 7106f0a..0901b30 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/components/alert-message-widget.hbs +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/components/alert-message-widget.hbs @@ -18,11 +18,11 @@ <div {{bind-attr class=":alert :alert-dismissible message.typeClass"}}> <button type="button" class="close" data-dismiss="alert" aria-hidden="true" {{action "remove"}}>×</button> - <strong>{{tb-helper message.title}}</strong> + <strong {{action 'toggleMessage'}}>{{tb-helper message.title}}</strong> {{#if message.isExpanded}} <div class="alert-message"> {{message.content}} </div> {{/if}} -</div> \ No newline at end of file +</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/components/collapsible-widget.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/components/collapsible-widget.hbs b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/components/collapsible-widget.hbs index f6af59b..230ec3b 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/components/collapsible-widget.hbs +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/components/collapsible-widget.hbs @@ -18,7 +18,12 @@ <div> <a {{action "toggle"}} {{bind-attr class=":fa iconClass"}}> {{heading}}</a> + <div class="pull-right"> + {{#each control in controls}} + <a {{action 'sendControlAction' control.action}} {{bind-attr class=":fa control.icon" title="control.tooltip"}}></a> + {{/each}} + </div> </div> {{#if isExpanded}} {{yield}} -{{/if}} \ No newline at end of file +{{/if}} http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/components/notify-widget.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/components/notify-widget.hbs b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/components/notify-widget.hbs new file mode 100644 index 0000000..5f905a8 --- /dev/null +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/components/notify-widget.hbs @@ -0,0 +1,21 @@ +{{! +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +}} + +{{#each notification in notifications}} + {{view "notification" notification=notification}} +{{/each}} http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/components/panel-widget.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/components/panel-widget.hbs b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/components/panel-widget.hbs index 45c4edf..1e29033 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/components/panel-widget.hbs +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/components/panel-widget.hbs @@ -16,7 +16,7 @@ * limitations under the License. }} -<div class="panel panel-default" {{bind-attr class=classNames}}> +<div {{bind-attr class=":panel :panel-default classNames"}}> {{#if heading}} <div class="panel-heading"> {{#if menuItems}} @@ -34,6 +34,14 @@ </ul> </div> {{/if}} + + {{#if iconActions}} + {{#each iconAction in iconActions}} + <i {{action "sendMenuItemAction" iconAction.action}} + {{bind-attr class=":pull-right :panel-action-icon :fa iconAction.icon"}}></i> + {{/each}} + {{/if}} + <strong>{{heading}}</strong> {{#if isLoading}} <div class="spinner small pull-right"></div> @@ -43,4 +51,4 @@ <div class="panel-body"> {{yield}} </div> -</div> \ No newline at end of file +</div> http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/components/query-tabs.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/components/query-tabs.hbs b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/components/query-tabs.hbs new file mode 100644 index 0000000..f131367 --- /dev/null +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/components/query-tabs.hbs @@ -0,0 +1,29 @@ +{{! +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +}} + +{{#each tab in tabs}} + <span {{action tab.action tab}} {{bind-attr class=":query-menu-tab tabClassNames tab.iconClass tab.active:active"}}> + {{#if tab.badge}} + <span class="badge">{{tab.badge}}</span> + {{/if}} + + {{#if tab.text}} + {{tab.text}} + {{/if}} + </span> +{{/each}} http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/components/tabs-widget.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/components/tabs-widget.hbs b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/components/tabs-widget.hbs index e5f313a..5f9c18c 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/components/tabs-widget.hbs +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/components/tabs-widget.hbs @@ -23,6 +23,7 @@ {{#link-to tab.path tab.id tagName="li"}} <a> {{tab.name}} + {{#if tab.isDirty}}*{{/if}} {{#if view.removeEnabled}} <i class="fa fa-remove" {{action 'remove' tab}}></i> {{/if}} @@ -37,4 +38,4 @@ {{/each}} </ul> -{{yield}} \ No newline at end of file +{{yield}} http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/databases-search-results.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/databases-search-results.hbs b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/databases-search-results.hbs index 354d7bd..007d9ca 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/databases-search-results.hbs +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/databases-search-results.hbs @@ -44,5 +44,7 @@ </div> </div> {{else}} - <h4>{{t "labels.noTablesMatches"}} "{{tablesSearchTerm}}"</h4> + <div class="alert alert-warning database-explorer-alert" role="alert"> + {{t "labels.noTablesMatch"}} <strong>"{{tablesSearchTerm}}"</strong> + </div> {{/if}} http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/databases-tree.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/databases-tree.hbs b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/databases-tree.hbs index 5da9760..bdac484 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/databases-tree.hbs +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/databases-tree.hbs @@ -18,11 +18,11 @@ <div class="databases"> {{#each database in content}} - {{#collapsible-widget heading=database.name isExpanded=database.isExpanded iconClass="fa-database" expanded="getTables"}} + {{#collapsible-widget heading=database.name isExpanded=database.isExpanded iconClass="fa-database" expanded="getTables" toggledParam=database}} {{#if database.isExpanded}} <div class="tables"> {{#each table in database.visibleTables}} - {{#collapsible-widget heading=table.name isExpanded=table.isExpanded toggledParam=database iconClass="fa-th" expanded="getColumns"}} + {{#collapsible-widget heading=table.name isExpanded=table.isExpanded toggledParam=database iconClass="fa-table" expanded="getColumns" controls=tableControls}} {{#if table.isExpanded}} <div class="columns"> {{#each column in table.visibleColumns}} @@ -45,4 +45,4 @@ {{/if}} {{/collapsible-widget}} {{/each}} -</div> \ No newline at end of file +</div> http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/databases.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/databases.hbs b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/databases.hbs index a0ce19f..392b8f3 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/databases.hbs +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/databases.hbs @@ -16,7 +16,7 @@ * limitations under the License. }} -{{#panel-widget headingTranslation="titles.database" isLoading=isLoading classNames="database-explorer"}} +{{#panel-widget headingTranslation="titles.database" isLoading=isLoading classNames="database-explorer" iconActions=panelIconActions}} {{#if model}} {{typeahead-widget @@ -51,4 +51,4 @@ {{partial selectedTab.view}} {{/tabs-widget}} {{/if}} -{{/panel-widget}} \ No newline at end of file +{{/panel-widget}} http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/index.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/index.hbs b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/index.hbs index 8621baa..1551072 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/index.hbs +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/index.hbs @@ -23,22 +23,22 @@ </aside> <div class="col-md-9 col-xs-12 query-container"> - {{render 'alerts'}} {{#panel-widget headingTranslation="titles.query.editor" classNames="query-editor-panel"}} {{render 'open-queries'}} <div class="toolbox"> - <button type="button" class="btn btn-sm btn-success execute-query" - {{bind-attr class="canExecute::disabled"}} + <button type="button" + {{bind-attr class=":btn :btn-sm :btn-success :execute-query canExecute::disabled"}} {{action "executeQuery"}}> {{t "buttons.execute"}} </button> - <button type="button" class="btn btn-sm btn-default" - {{bind-attr class="canExecute::disabled"}} + <button type="button" + {{bind-attr class=":btn :btn-sm :btn-default canExecute::disabled"}} {{action "explainQuery"}}> {{t "buttons.explain"}} </button> + <button type="button" class="btn btn-sm btn-default save-query-as" {{action "saveQuery"}}>{{t "buttons.saveAs"}}</button> {{render 'insert-udfs'}} @@ -76,13 +76,7 @@ </div> </div> - {{#if tezUI.showOverlay}} - {{render 'tez-ui'}} - {{/if}} - - {{#if visualExplain.showOverlay}} - {{render 'visual-explain'}} - {{/if}} + {{outlet 'overlay'}} <div class="query-menu"> {{#popover-widget classNames="fa fa-info-circle queries-icon" titleTranslation="popover.queryEditorHelp.title" }} @@ -93,10 +87,6 @@ </ul> {{/popover-widget}} - <span {{bind-attr class="settings.showOverlay:active :fa :fa-gear :queries-icon"}} {{action 'toggleOverlay' 'settings'}}></span> - - <span {{bind-attr class="visualExplain.showOverlay:active :fa :fa-bar-chart :queries-icon"}} {{action 'toggleOverlay' 'visualExplain'}}></span> - - <span {{bind-attr class="tezUI.showOverlay:active shouldShowTez::hide :queries-icon :text-icon"}} {{action 'toggleOverlay' 'tezUI'}}>TEZ</span> + {{query-tabs}} </div> </div> http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/index/history-query/results.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/index/history-query/results.hbs b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/index/history-query/results.hbs index ed6fba6..06c21e4 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/index/history-query/results.hbs +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/index/history-query/results.hbs @@ -20,13 +20,13 @@ <table class="table table-expandable"> <thead> <tr> - {{#each column in results.schema}} + {{#each column in formattedResults.schema}} <th> {{column.name}} </th> {{/each}} </tr> </thead> <tbody> - {{#each row in results.rows}} + {{#each row in formattedResults.rows}} <tr> {{#each item in row}} <td>{{item}}</td> @@ -44,4 +44,4 @@ </div> {{else}} {{error}} -{{/if}} \ No newline at end of file +{{/if}} http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/insert-udfs.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/insert-udfs.hbs b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/insert-udfs.hbs index 0ea2c99..0911835 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/insert-udfs.hbs +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/insert-udfs.hbs @@ -16,29 +16,31 @@ * limitations under the License. }} -<div class="dropdown"> - <a role="button" data-toggle="dropdown" class="btn btn-default btn-sm" data-target="#"> - {{t "placeholders.select.udfs"}} - <span class="caret"></span> - </a> - <ul class="dropdown-menu pull-right" role="menu" aria-labelledby="dropdownMenu"> - {{#each item in this}} - <li class="dropdown dropdown-submenu"> - {{#if item.file}} - <a tabindex="-1">{{item.file.name}}</a> - {{else}} - <a tabindex="-1">{{tb-helper item.name}}</a> - {{/if}} - <ul class="dropdown-menu"> - {{#each udf in item.udfs}} - <li> - {{#no-bubbling click="insertUdf" data=udf tagName="a"}} - {{udf.name}} - {{/no-bubbling}} - </li> - {{/each}} - </ul> - </li> - {{/each}} - </ul> -</div> \ No newline at end of file +{{#if this.length}} + <div class="dropdown"> + <a role="button" data-toggle="dropdown" class="btn btn-default btn-sm" data-target="#"> + {{t "placeholders.select.udfs"}} + <span class="caret"></span> + </a> + <ul class="dropdown-menu pull-right" role="menu" aria-labelledby="dropdownMenu"> + {{#each item in this}} + <li class="dropdown dropdown-submenu"> + {{#if item.file}} + <a tabindex="-1">{{item.file.name}}</a> + {{else}} + <a tabindex="-1">{{tb-helper item.name}}</a> + {{/if}} + <ul class="dropdown-menu"> + {{#each udf in item.udfs}} + <li> + {{#no-bubbling click="insertUdf" data=udf tagName="a"}} + {{udf.name}} + {{/no-bubbling}} + </li> + {{/each}} + </ul> + </li> + {{/each}} + </ul> + </div> +{{/if}} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/message.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/message.hbs b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/message.hbs new file mode 100644 index 0000000..ad7fb9a --- /dev/null +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/message.hbs @@ -0,0 +1,36 @@ +{{! +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +}} + +<div {{bind-attr class=":alert :notification view.typeClass"}}> + <button type="button" class="close" {{action "close" target="view"}}><span aria-hidden="true">×</span></button> + <i {{bind-attr class=":fa view.typeIcon"}}></i> + + {{#if view.notification.body}} + <a {{action "expand" target="view"}}> + {{view.notification.message}} + </a> + {{else}} + {{view.notification.message}} + {{/if}} + + {{#if view.isExpanded}} + <pre class="message-body"> + {{preformatted-string view.notification.body}} + </pre> + {{/if}} +</div> http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/messages.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/messages.hbs b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/messages.hbs new file mode 100644 index 0000000..7c494b6 --- /dev/null +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/messages.hbs @@ -0,0 +1,30 @@ +{{! +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +}} + +<div class="editor-overlay messages-container"> + <h3>Messages + {{#if messages.length}} + <button class="btn btn-danger btn-xs" {{action 'removeAllMessages'}}><i class="fa fa-minus"></i> Clear All</button> + {{/if}} + </h3> + + + {{#each message in messages}} + {{view 'message' notification=message}} + {{/each}} +</div> http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/modal-delete.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/modal-delete.hbs b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/modal-delete.hbs index a870a0e..032c144 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/modal-delete.hbs +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/modal-delete.hbs @@ -17,5 +17,5 @@ }} {{#modal-widget heading=heading close="close" ok="delete"}} - {{text}} + {{tb-helper text}} {{/modal-widget}} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/modal-save-query.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/modal-save-query.hbs b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/modal-save-query.hbs new file mode 100644 index 0000000..6853550 --- /dev/null +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/modal-save-query.hbs @@ -0,0 +1,24 @@ +{{! +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +}} + +{{#modal-widget heading=heading close="close" ok="save"}} + {{input type="text" class="form-control" value=text }} + {{#if showMessage}} + <span class="label label-warning">{{tb-helper message}}</span> + {{/if}} +{{/modal-widget}} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/notification.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/notification.hbs b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/notification.hbs new file mode 100644 index 0000000..35c2fe1 --- /dev/null +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/notification.hbs @@ -0,0 +1,23 @@ +{{! +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +}} + +<div {{bind-attr class=":alert :notification view.typeClass"}}> + <button type="button" class="close" {{action "close" target="view"}}><span aria-hidden="true">×</span></button> + <i {{bind-attr class=":fa view.typeIcon"}}></i> + {{view.notification.message}} +</div> http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/open-queries.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/open-queries.hbs b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/open-queries.hbs index ad1d9bd..fdf5597 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/open-queries.hbs +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/open-queries.hbs @@ -17,7 +17,7 @@ }} {{#tabs-widget tabs=queryTabs removeClicked="removeQueryTab" canRemove=true}} - {{render 'settings'}} + {{outlet 'overlay'}} {{query-editor tables=selectedTables query=currentQuery.fileContent editor=view.editor highlightedText=highlightedText columnsNeeded="getColumnsForAutocomplete"}} {{/tabs-widget}} http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/settings.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/settings.hbs b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/settings.hbs index 791b7d0..98f0b54 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/settings.hbs +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/settings.hbs @@ -16,44 +16,51 @@ * limitations under the License. }} -{{#if showOverlay}} - <div class="settings-container fadeIn"> - <h3> Settings - <button class="btn btn-success btn-xs" {{action 'add'}}><i class="fa fa-plus"></i> Add</button> - </h3> +<div class="editor-overlay settings-container fadeIn"> + <h3> Settings + <button class="btn btn-success btn-xs" {{action 'add'}}><i class="fa fa-plus"></i> Add</button> + {{#if currentSettings.settings}} + <button class="btn btn-danger btn-xs" {{action 'removeAll'}}><i class="fa fa-minus"></i> Remove All</button> + {{/if}} - {{#each setting in currentSettings.settings}} - <div class="setting col-md-6 col-sm-12"> - <form> - <div class="form-group"> - <div class="input-group"> - <div class="input-group-addon"> - {{typeahead-widget - content=predefinedSettings - optionLabelPath="name" - optionValuePath="name" - selection=setting.key - create="addKey" - }} - </div> - <div {{bind-attr class=":input-group-addon setting.valid::has-error"}}> - {{#if setting.key.values}} - {{select-widget items=setting.key.values - labelPath="value" - selectedValue=setting.selection - defaultLabelTranslation="placeholders.select.value" - }} - {{else}} - {{input class="input-sm form-control" placeholderTranslation="placeholders.select.value" value=setting.selection.value}} - {{/if}} + {{#if canInvalidateSession}} + <button class="btn btn-danger btn-xs pull-right" {{action 'invalidateSession'}}><i class="fa fa-times"></i> Invalidate Session</button> + {{/if}} + </h3> + + {{#each setting in currentSettings.settings}} + <div class="setting col-md-6 col-sm-12"> + <form> + <div class="form-group"> + <div class="input-group"> + <div class="input-group-addon"> + {{typeahead-widget + options=predefinedSettings + excluded=selectedSettings + optionLabelPath="name" + optionValuePath="name" + selection=setting.key + create="addKey" + }} + </div> + <div {{bind-attr class=":input-group-addon setting.valid::has-error"}}> + + {{#if setting.key.values}} + {{select-widget items=setting.key.values + labelPath="value" + selectedValue=setting.selection + defaultLabelTranslation="placeholders.select.value" + }} + {{else}} + {{input class="input-sm form-control" placeholderTranslation="placeholders.select.value" value=setting.selection.value}} + {{/if}} - <span class="fa fa-times-circle remove pull-right" {{action 'remove' setting}}></span> - </div> + <span class="fa fa-times-circle remove pull-right" {{action 'remove' setting}}></span> </div> </div> - </form> - </div> - {{/each}} - </div> -{{/if}} + </div> + </form> + </div> + {{/each}} +</div> http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/tez-ui.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/tez-ui.hbs b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/tez-ui.hbs index 4bee4d6..4bc0c0e 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/tez-ui.hbs +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/tez-ui.hbs @@ -23,6 +23,8 @@ {{else}} {{#if error}} <div class="alert alert-danger" role="alert"><strong>{{tb-helper error}}</strong></div> + {{else}} + <div class="alert alert-danger" role="alert"><strong>{{tb-helper 'tez.errors.no.dag'}}</strong></div> {{/if}} {{/if}} {{/panel-widget}} http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/visual-explain.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/visual-explain.hbs b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/visual-explain.hbs index a823ef2..a831b8c 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/visual-explain.hbs +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/templates/visual-explain.hbs @@ -18,5 +18,63 @@ <div id="visual-explain"> {{#panel-widget headingTranslation="titles.query.visualExplain"}} + + {{#each edge in view.edges}} + <div class="edge"> + <div class="edge-path" {{bind-attr style="edge.style"}}> + {{edge.type}} + </div> + {{!-- <div class="edge-arrow" ></div> --}} + </div> + {{/each}} + + <div class="nodes"> + {{#each group in view.verticesGroups}} + <div class="node-container"> + {{#if group.contents}} + {{#each node in group.contents}} + <div {{bind-attr class="node.isTableNode:table-node node.isOutputNode:output-node :node" title="node.id"}}> + {{#if node.isTableNode}} + <p><strong>{{t 'labels.table'}}</strong></p> + {{node.label}} + {{else}} + {{#if node.isOutputNode}} + {{node.label}} + {{else}} + <div class="node-heading"> + <strong>{{node.label}}</strong> + </div> + <div class="node-content"> + {{#each section in node.contents}} + <p> + {{#popover-widget classNames="fa fa-info-circle" titleTranslation="popover.visualExplain.statistics" }} + {{section.statistics}} + {{/popover-widget}} + <strong> + {{section.index}}. {{section.title}} + </strong> + {{section.value}} + </p> + + {{#each field in section.fields}} + {{#if field.value}} + <p>{{field.label}} {{field.value}}</p> + {{/if}} + {{/each}} + {{/each}} + </div> + {{/if}} + {{/if}} + </div> + {{/each}} + {{else}} + <div class="node" {{bind-attr title="group.label"}}> + {{group.label}} + </div> + {{/if}} + </div> + {{/each}} + </div> + {{/panel-widget}} </div> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/app/utils/constants.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/utils/constants.js b/contrib/views/hive/src/main/resources/ui/hive-web/app/utils/constants.js index 888275d..b099ce6 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/app/utils/constants.js +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/utils/constants.js @@ -55,6 +55,7 @@ export default Ember.Object.create({ udfInsertPrefix: 'create temporary function ', fileInsertPrefix: 'add jar ', explainPrefix: 'EXPLAIN ', + explainFormattedPrefix: 'EXPLAIN FORMATTED ', insertUdfs: 'insert-udfs', job: 'job', jobs: 'jobs', @@ -180,7 +181,7 @@ export default Ember.Object.create({ //this can be replaced by a string.format implementation adapter: { - version: '0.0.1', + version: '0.2.0', instance: 'Hive', apiPrefix: '/api/v1/views/HIVE/versions/', instancePrefix: '/instances/', @@ -189,5 +190,25 @@ export default Ember.Object.create({ settings: { executionEngine: 'hive.execution.engine' + }, + sampleDataQuery: 'SELECT * FROM %@ LIMIT 100;', + + notify: { + ERROR: { + typeClass : 'alert-danger', + typeIcon : 'fa-exclamation-triangle' + }, + WARN: { + typeClass : 'alert-warning', + typeIcon : 'fa-times-circle' + }, + SUCCESS: { + typeClass : 'alert-success', + typeIcon : 'fa-check' + }, + INFO: { + typeClass : 'alert-info', + typeIcon : 'fa-info' + } } }); http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/app/utils/dag-rules.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/utils/dag-rules.js b/contrib/views/hive/src/main/resources/ui/hive-web/app/utils/dag-rules.js new file mode 100644 index 0000000..f4b7f5d --- /dev/null +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/utils/dag-rules.js @@ -0,0 +1,141 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Ember from 'ember'; + +export default Ember.ArrayProxy.create({ + content: Ember.A( + [ + { + targetOperator: 'TableScan', + targetProperty: 'alias:', + label: 'Table Scan:', + + fields: [ + { + label: 'filterExpr:', + targetProperty: 'filterExpr:' + } + ] + }, + { + targetOperator: 'Filter Operator', + targetProperty: 'predicate:', + label: 'Filter:', + + fields: [] + }, + { + targetOperator: 'Map Join Operator', + label: 'Map Join', + + fields: [] + }, + { + targetOperator: 'Merge Join Operator', + label: 'Merge Join', + + fields: [] + }, + { + targetOperator: 'Select Operator', + label: 'Select', + + fields: [] + }, + { + targetOperator: 'Reduce Output Operator', + label: 'Reduce', + + fields: [ + { + label: 'Partition columns:', + targetProperty: 'Map-reduce partition columns:' + }, + { + label: 'Key expressions:', + targetProperty: 'key expressions:' + }, + { + label: 'Sort order:', + targetProperty: 'sort order:' + } + ] + }, + { + targetOperator: 'File Output Operator', + label: 'File Output Operator', + + fields: [] + }, + { + targetOperator: 'Group By Operator', + label: 'Group By:', + + fields: [ + { + label: 'Aggregations:', + targetProperties: 'aggregations:' + }, + { + label: 'Keys:', + targetProperty: 'keys:' + } + ] + }, + { + targetOperator: 'Limit', + targetProperty: 'Number of rows:', + label: 'Limit:', + + fields: [] + }, + { + targetOperator: 'Extract', + label: 'Extract', + + fields: [] + }, + { + targetOperator: 'PTF Operator', + label: 'Partition Table Function', + + fields: [] + }, + { + targetOperator: 'Dynamic Partitioning Event Operator', + labelel: 'Dynamic Partitioning Event', + + fields: [ + { + label: 'Target column:', + targetProperty: 'Target column:' + }, + { + label: 'Target Vertex:', + targetProperty: 'Target Vertex:' + }, + { + label: 'Partition key expr:', + targetProperty: 'Partition key expr:' + } + ] + } + ] + ) +}); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/app/views/message.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/views/message.js b/contrib/views/hive/src/main/resources/ui/hive-web/app/views/message.js new file mode 100644 index 0000000..dd32a15 --- /dev/null +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/views/message.js @@ -0,0 +1,36 @@ + /** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Ember from 'ember'; +import NotificationView from 'hive/views/notification'; + +export default NotificationView.extend({ + templateName : 'message', + removeLater : Ember.K, + isExpanded : false, + removeMessage: 'removeMessage', + + actions: { + expand: function() { + this.toggleProperty('isExpanded'); + }, + + close: function() { + this.get('controller').send('removeMessage', this.get('notification')); + } + } +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/app/views/notification.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/views/notification.js b/contrib/views/hive/src/main/resources/ui/hive-web/app/views/notification.js new file mode 100644 index 0000000..291bfeb --- /dev/null +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/views/notification.js @@ -0,0 +1,51 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Ember from 'ember'; + +export default Ember.View.extend({ + closeAfter : 500000, + isHovering : false, + templateName : 'notification', + removeNotification : 'removeNotification', + + setup: function() { + this.set('typeClass', this.get('notification.type.typeClass')); + this.set('typeIcon', this.get('notification.type.typeIcon')); + }.on('init'), + + removeLater: function() { + Ember.run.later(this, function() { + if (this.get('isHovering')) { + this.removeLater(); + } else if (this.element) { + this.send('close'); + } + }, this.get('closeAfter')); + }.on('didInsertElement'), + + mouseEnter: function() { this.set('isHovering', true); }, + mouseLeave: function() { this.set('isHovering', false); }, + + actions: { + close: function() { + this.remove(); + this.get('parentView').send('removeNotification', this.get('notification')); + } + } +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/app/views/visual-explain.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/views/visual-explain.js b/contrib/views/hive/src/main/resources/ui/hive-web/app/views/visual-explain.js index 4a887e2..07baedb 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/app/views/visual-explain.js +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/views/visual-explain.js @@ -17,13 +17,28 @@ */ import Ember from 'ember'; +import dagRules from '../utils/dag-rules'; export default Ember.View.extend({ + willInsertElement: function () { + this.set('verticesGroups', []); + this.set('edges', []); + this.set('graph', new dagre.graphlib.Graph()); + + if (this.get('controller.json')) { + this.renderDag(); + } + }, + didInsertElement: function () { + this._super(); + var target = this.$('#visual-explain'); target.css('min-height', $('.main-content').height()); target.animate({ width: $('.main-content').width() }, 'fast'); + + Ember.run.scheduleOnce('afterRender', this, this.afterRenderEvent); }, willDestroyElement: function () { @@ -31,5 +46,391 @@ export default Ember.View.extend({ target.css('min-height', 0); target.css('width', 0); + }, + + getOffset: function (el) { + var _x = 0; + var _y = 0; + var _w = el.offsetWidth|0; + var _h = el.offsetHeight|0; + while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) ) { + _x += el.offsetLeft - el.scrollLeft; + _y += el.offsetTop - el.scrollTop; + el = el.offsetParent; + } + return { top: _y, left: _x, width: _w, height: _h }; + }, + + addEdge: function (div1, div2, thickness, type) { + var off1 = this.getOffset(div1); + var off2 = this.getOffset(div2); + // bottom right + var x1 = off1.left + off1.width / 2; + var y1 = off1.top + off1.height; + // top right + var x2 = off2.left + off2.width / 2; + var y2 = off2.top; + // distance + var length = Math.sqrt(((x2-x1) * (x2-x1)) + ((y2-y1) * (y2-y1))); + // center + var cx = ((x1 + x2) / 2) - (length / 2); + var cy = ((y1 + y2) / 2) - (thickness / 2) - 73; + // angle + var angle = Math.round(Math.atan2((y1-y2), (x1-x2)) * (180 / Math.PI)); + + if (angle < -90) { + angle = 180 + angle; + } + + var style = "left: %@px; top: %@px; width: %@px;" + + "-moz-transform:rotate(%@4deg);" + + "-webkit-transform:rotate(%@4deg);" + + "-ms-transform:rotate(%@4deg);" + + "-transform:rotate(%@4deg);"; + + style = style.fmt(cx, cy, length, angle); + + var edgeType; + + if (type) { + if (type === 'BROADCAST_EDGE') { + edgeType = 'BROADCAST'; + } else { + edgeType = 'SHUFFLE'; + } + } + + this.get('edges').pushObject({ + style: style, + type: edgeType + }); + }, + + afterRenderEvent : function () { + var g = this.get('graph'); + var self = this; + + //draw edges after the slide aniamtion for the visual explain container is done + Ember.run.later(function () { + g.edges().forEach(function (value) { + var edge = g.edge(value); + var v = value.v; + + var firstNode = self.$("[title='" + value.v + "']")[0]; + var secondNode = self.$("[title='" + value.w + "']")[0]; + + self.addEdge(firstNode, secondNode, 2, g.edge(value).type); + }); + }, 300); + }, + + getNodeContents: function (operator, contents, table, vertex) { + var currentTable = table, + contents = contents || [], + nodeName, + node, + ruleNode, + nodeLabelValue, + self = this; + + if (operator.constructor === Array) { + operator.forEach(function (childOperator) { + self.getNodeContents(childOperator, contents, currentTable, vertex); + }); + + return contents; + } else { + nodeName = Object.getOwnPropertyNames(operator)[0]; + node = operator[nodeName]; + ruleNode = dagRules.findBy('targetOperator', nodeName); + + if (ruleNode) { + if (nodeName.indexOf('Map Join') > -1) { + nodeLabelValue = this.handleMapJoinNode(node, currentTable); + currentTable = null; + } else if (nodeName.indexOf('Merge Join') > -1) { + nodeLabelValue = this.handleMergeJoinNode(node, vertex); + } else { + nodeLabelValue = node[ruleNode.targetProperty]; + } + + contents.pushObject({ + title: ruleNode.label, + statistics: node["Statistics:"], + index: contents.length + 1, + value: nodeLabelValue, + fields: ruleNode.fields.map(function (field) { + var value = node[field.targetProperty || field.targetProperties]; + + return { + label: field.label, + value: value + } + }) + }); + + if (node.children) { + return this.getNodeContents(node.children, contents, currentTable, vertex); + } else { + return contents; + } + } else { + return contents; + } + } + }, + + handleMapJoinNode: function (node, table) { + var rows = table || "<rows from above>"; + var firstTable = node["input vertices:"][0] || rows; + var secondTable = node["input vertices:"][1] || rows; + + var joinString = node["condition map:"][0][""]; + joinString = joinString.replace("0", firstTable); + joinString = joinString.replace("1", secondTable); + joinString += " on "; + joinString += node["keys:"][0] + "="; + joinString += node["keys:"][1]; + + return joinString; + }, + + handleMergeJoinNode: function (node, vertex) { + var graphData = this.get('controller.json')['STAGE PLANS']['Stage-1']['Tez']; + var edges = graphData['Edges:']; + var index = 0; + var joinString = node["condition map:"][0][""]; + + edges[vertex].toArray().forEach(function (edge) { + if (edge.type === "SIMPLE_EDGE") { + joinString.replace(String(index), edge.parent); + index++; + } + }); + + return joinString; + }, + + //sets operator nodes + setNodes: function (vertices) { + var g = this.get('graph'); + var self = this; + + vertices.forEach(function (vertex) { + var contents = []; + var operator; + var currentTable; + + if (vertex.name.indexOf('Map') > -1) { + operator = vertex.value['Map Operator Tree:'][0]; + currentTable = operator["TableScan"]["alias:"]; + } else if (vertex.name.indexOf('Reducer') > -1) { + operator = vertex.value['Reduce Operator Tree:']; + } + + // else if (vertex.name.indexOf('Union') > -1) { + // g.setNode(vertex, { + // id: vertex.name, + // label: vertex.name + // }); + // } + + if (operator) { + contents = self.getNodeContents(operator, null, currentTable, vertex.name); + + g.setNode(vertex.name, { + contents: contents, + id: vertex.name, + label: vertex.name + }); + } + }); + + return this; + }, + + //sets edges between operator nodes + setEdges: function (edges) { + var i; + var g = this.get('graph'); + var invalidEdges = []; + var edgesToBeRemoved = []; + var isValidEdgeType = function (type) { + return type === "SIMPLE_EDGE" || + type === "BROADCAST_EDGE"; + }; + + edges.forEach(function (edge) { + var parent; + var type; + + if (edge.value.constructor === Array) { + edge.value.forEach(function (childEdge) { + parent = childEdge.parent; + type = childEdge.type; + + if (isValidEdgeType(type)) { + g.setEdge(parent, edge.name); + g.edge({v: parent, w: edge.name}).type = type; + } else { + invalidEdges.pushObject({ + vertex: edge.name, + edge: childEdge + }); + } + }); + } else { + parent = edge.value.parent; + type = edge.value.type; + + if (isValidEdgeType(type)) { + g.setEdge(parent, edge.name); + g.edge({v: parent, w: edge.name}).type = type; + } else { + invalidEdges.pushObject({ + vertex: edge.name, + edge: edge.name + }); + } + } + }); + + invalidEdges.forEach(function (invalidEdge) { + var targetEdge = g.edges().find(function (graphEdge) { + return graphEdge.v === invalidEdge.edge.parent || + graphEdge.w === invalidEdge.edge.parent; + }); + + var targetVertex; + + if (targetEdge) { + edgesToBeRemoved.pushObject(targetEdge); + + if (targetEdge.v === invalidEdge.edge.parent) { + targetVertex = targetEdge.w; + } else { + targetVertex = targetEdge.v; + } + + parent = invalidEdge.vertex; + + g.setEdge({v: parent, w: targetVertex}); + g.setEdge({v: parent, w: targetVertex}).type = "BROADCAST_EDGE"; + } + }); + + edgesToBeRemoved.uniq().forEach(function (edge) { + g.removeEdge(edge.v, edge.w, edge.name); + }); + + return this; + }, + + //sets nodes for tables and their edges + setTableNodesAndEdges: function (vertices) { + var g = this.get('graph'); + + vertices.forEach(function (vertex) { + var operator; + var table; + var id; + + if (vertex.name.indexOf('Map') > -1) { + operator = vertex.value['Map Operator Tree:'][0]; + for (var node in operator) { + table = operator[node]['alias:']; + + //create unique identifier by using table + map pairs so that we have + //different nodes for the same table if it's a table connected to multiple Map operators + id = table + ' for ' + vertex.name; + + g.setNode(id, { id: id, label: table, isTableNode: true }); + g.setEdge(id, vertex.name); + } + } + }); + + return this; + }, + + createNodeGroups: function () { + var groupedNodes = []; + var g = this.get('graph'); + var lastRowNode; + var fileOutputOperator; + + g.nodes().forEach(function (value) { + var node = g.node(value); + + if (node) { + var existentRow = groupedNodes.findBy('topOffset', node.y); + + if (!existentRow) { + groupedNodes.pushObject({ + topOffset: node.y, + contents: [ node ] + }); + } else { + existentRow.contents.pushObject(node); + } + } + }); + + groupedNodes = groupedNodes.sortBy('topOffset'); + groupedNodes.forEach(function (group) { + group.contents = group.contents.sortBy('x'); + }); + + lastRowNode = groupedNodes.get('lastObject.contents.lastObject'); + fileOutputOperator = lastRowNode.contents.get('lastObject'); + + g.setNode(fileOutputOperator.title, { id: fileOutputOperator.title, label: fileOutputOperator.title, isOutputNode: true }); + g.setEdge(fileOutputOperator.title, lastRowNode.id); + + groupedNodes.pushObject({ + contents: [ g.node(fileOutputOperator.title) ] + }); + + lastRowNode.contents.removeObject(fileOutputOperator); + + this.set('verticesGroups', groupedNodes); + }, + + renderDag: function () { + var convert = function (inputObj) { + var array = []; + + for (var key in inputObj) { + if (inputObj.hasOwnProperty(key)) { + array.pushObject({ + name: key, + value: inputObj[key] + }); + } + } + + return array; + }; + + // Create a new directed graph + var g = this.get('graph'); + + var graphData = this.get('controller.json')['STAGE PLANS']['Stage-1']['Tez']; + var vertices = convert(graphData['Vertices:']); + var edges = convert(graphData['Edges:']); + + // Set an object for the graph label + g.setGraph({}); + + // Default to assigning a new object as a label for each new edge. + g.setDefaultEdgeLabel(function () { return {}; }); + + this.setNodes(vertices) + .setEdges(edges) + .setTableNodesAndEdges(vertices); + + dagre.layout(g); + + this.createNodeGroups(); } }); http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/bower.json ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/bower.json b/contrib/views/hive/src/main/resources/ui/hive-web/bower.json index 161a626..24e8821 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/bower.json +++ b/contrib/views/hive/src/main/resources/ui/hive-web/bower.json @@ -1,27 +1,25 @@ { "name": "hive", "dependencies": { - "handlebars": "2.0.0", "jquery": "^1.11.1", - "ember": "1.9.0", - "ember-data": "1.0.0-beta.14.1", - "ember-resolver": "~0.1.7", - "loader.js": "stefanpenner/loader.js#1.0.1", + "ember": "1.10.0", + "ember-data": "1.0.0-beta.16.1", + "ember-resolver": "~0.1.12", + "loader.js": "stefanpenner/loader.js#3.2.0", "ember-cli-shims": "stefanpenner/ember-cli-shims#0.0.3", - "ember-cli-test-loader": "rwjblue/ember-cli-test-loader#0.0.4", + "ember-cli-test-loader": "rwjblue/ember-cli-test-loader#0.1.3", "ember-load-initializers": "stefanpenner/ember-load-initializers#0.0.2", "ember-qunit": "0.2.8", "ember-qunit-notifications": "0.0.7", - "qunit": "~1.15.0", + "qunit": "~1.17.1", "bootstrap": "~3.2.0", - "ember-i18n": "~2.9.0", + "ember-i18n": "~3.0.0", "blanket": "~1.1.5", "jquery-ui": "~1.11.2", "selectize": "~0.12.0", "pretender": "0.1.0" }, "resolutions": { - "handlebars": "2.0.0", - "ember": "1.9.0" + "ember": "1.10.0" } } http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/package.json ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/package.json b/contrib/views/hive/src/main/resources/ui/hive-web/package.json index c2523b1..95f6897 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/package.json +++ b/contrib/views/hive/src/main/resources/ui/hive-web/package.json @@ -22,24 +22,24 @@ "devDependencies": { "body-parser": "^1.2.0", "bower": ">= 1.3.12", - "broccoli-asset-rev": "0.3.1", - "broccoli-sass": "^0.3.2", - "ember-cli": "0.1.15", - "ember-cli-blanket": "^0.2.2", + "broccoli-asset-rev": "^2.0.0", + "broccoli-sass": "0.6.3", + "ember-cli": "0.2.2", + "ember-cli-blanket": "^0.4.0", "ember-cli-content-security-policy": "0.3.0", "ember-cli-font-awesome": "0.0.4", - "ember-cli-htmlbars": "^0.5.3", + "ember-cli-htmlbars": "0.7.4", "ember-cli-ic-ajax": "0.1.1", "ember-cli-inject-live-reload": "^1.3.0", "ember-cli-jquery-ui": "0.0.12", "ember-cli-moment": "0.0.1", "ember-cli-pretender": "^0.3.1", - "ember-cli-qunit": "0.3.7", + "ember-cli-qunit": "0.3.9", "ember-cli-selectize": "0.0.19", - "ember-data": "1.0.0-beta.14.1", + "ember-data": "1.0.0-beta.16.1", "ember-dynamic-component": "0.0.1", "ember-export-application-global": "^1.0.0", "express": "^4.8.5", - "glob": "4.4.0" + "ember-cli-uglify": "1.0.1" } } http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/testem.json ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/testem.json b/contrib/views/hive/src/main/resources/ui/hive-web/testem.json index eff93f9..5a8d375 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/testem.json +++ b/contrib/views/hive/src/main/resources/ui/hive-web/testem.json @@ -1,6 +1,6 @@ { "framework": "qunit", - "test_page": "tests/index.html", + "test_page": "tests/index.html?hidepassed&nocontainer", "launch_in_ci": [ "PhantomJS" ], http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/tests/helpers/api-mock.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/tests/helpers/api-mock.js b/contrib/views/hive/src/main/resources/ui/hive-web/tests/helpers/api-mock.js index 46a73f9..8567f30 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/tests/helpers/api-mock.js +++ b/contrib/views/hive/src/main/resources/ui/hive-web/tests/helpers/api-mock.js @@ -86,7 +86,7 @@ export default function() { "fileResources":[], "statusDir":"job1", "id":1, - "title":"New Query", + "title":"Worksheet", "duration":2, "forcedContent":"", "owner":"admin", http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/tests/index.html ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/tests/index.html b/contrib/views/hive/src/main/resources/ui/hive-web/tests/index.html index 6adbc89..b8928ff 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/tests/index.html +++ b/contrib/views/hive/src/main/resources/ui/hive-web/tests/index.html @@ -46,6 +46,9 @@ zoom: 50%; } </style> + + {{content-for 'head-footer'}} + {{content-for 'test-head-footer'}} </head> <body> <div id="qunit"></div> @@ -60,5 +63,8 @@ <script src="assets/blanket-loader.js"></script> <script src="testem.js"></script> <script src="assets/test-loader.js"></script> + + {{content-for 'body-footer'}} + {{content-for 'test-body-footer'}} </body> </html> http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/tests/integration/database-test.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/tests/integration/database-test.js b/contrib/views/hive/src/main/resources/ui/hive-web/tests/integration/database-test.js index 5be4fdc..0a6b12c 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/tests/integration/database-test.js +++ b/contrib/views/hive/src/main/resources/ui/hive-web/tests/integration/database-test.js @@ -58,7 +58,7 @@ test('Expanding a database will retrieve the first page of tables for that datab click(targetDB); andThen(function () { - equal(find('.fa-th').length, 3); + equal(find('.fa-table').length, 3); }); }); }); @@ -74,7 +74,7 @@ test('Expanding a table will retrieve the first page of columns for that table.' click(targetDB); andThen(function () { - var targetTable = find('.fa-th').first(); + var targetTable = find('.fa-table').first(); click(targetTable); @@ -102,4 +102,4 @@ test('Searching for a table will display table results and column search field', equal(find('.nav-tabs li').length, 2, 'Results tab has been redendered.'); }); }); -}); \ No newline at end of file +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/tests/test-helper.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/tests/test-helper.js b/contrib/views/hive/src/main/resources/ui/hive-web/tests/test-helper.js index 53d9f9b..96975ee 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/tests/test-helper.js +++ b/contrib/views/hive/src/main/resources/ui/hive-web/tests/test-helper.js @@ -22,9 +22,3 @@ import { } from 'ember-qunit'; setResolver(resolver); - -document.write('<div id="ember-testing-container"><div id="ember-testing"></div></div>'); - -QUnit.config.urlConfig.push({ id: 'nocontainer', label: 'Hide container'}); -var containerVisibility = QUnit.urlParams.nocontainer ? 'hidden' : 'visible'; -document.getElementById('ember-testing-container').style.visibility = containerVisibility; http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/components/alert-message-widget-test.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/components/alert-message-widget-test.js b/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/components/alert-message-widget-test.js index c7deabb..8f0f245 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/components/alert-message-widget-test.js +++ b/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/components/alert-message-widget-test.js @@ -33,19 +33,19 @@ test('isExpanded is toggled on click', function() { }); Ember.run(function() { - component.click(); + component.send('toggleMessage'); }); equal(component.get('message.isExpanded'), true, 'isExpanded is set to true'); Ember.run(function() { - component.click(); + component.send('toggleMessage'); }); equal(component.get('message.isExpanded'), false, 'isExpanded is set to false'); }); -test('removeLater should be called on click', function() { +test('removeLater should be called when the message is toggled', function() { expect(1); var message = Ember.Object.create({ isExpanded: false}); @@ -63,11 +63,11 @@ test('removeLater should be called on click', function() { }); Ember.run(function() { - component.click(); + component.send('toggleMessage'); }); Ember.run(function() { - component.click(); + component.send('toggleMessage'); }); }); http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/controllers/index-test.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/controllers/index-test.js b/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/controllers/index-test.js index 291cc7e..7d7b531 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/controllers/index-test.js +++ b/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/controllers/index-test.js @@ -26,7 +26,9 @@ moduleFor('controller:index', 'IndexController', { 'controller:index/history-query/results', 'controller:index/history-query/explain', 'controller:settings', - 'adapter:database', 'controller:tables', 'controller:columns'] + 'adapter:database', 'controller:tables', 'controller:columns', + 'controller:visual-explain', 'controller:tez-ui' + ] }); test('when initialized, controller sets the queryProcessTabs.', function () { @@ -106,14 +108,19 @@ test('bindQueryParams replaces same param multiple times', function() { test('parseQueryParams sets queryParams when query changes', function() { expect(3); - var controller = this.subject(); - var query = "select $what from $where"; + var query = Ember.Object.create({ + id: 1, + fileContent: "select $what from $where" + }); + + var controller = this.subject({ + model: query + }); Ember.run(function() { - controller.set('openQueries.currentQuery', { - 'fileContent': query - }); + controller.set('openQueries.queryTabs', [query]); + controller.set('openQueries.currentQuery', query); }); equal(controller.get('queryParams.length'), 2, '2 queryParams parsed'); http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/controllers/queries-test.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/controllers/queries-test.js b/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/controllers/queries-test.js index d14f2cc..2578c33 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/controllers/queries-test.js +++ b/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/controllers/queries-test.js @@ -20,7 +20,10 @@ import Ember from 'ember'; import { moduleFor, test } from 'ember-qunit'; moduleFor('controller:queries', 'QueriesController', { - needs: [ 'controller:history' ] + needs: [ + 'controller:history', + 'controller:open-queries' + ] }); test('controller is initialized', function() { http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/controllers/settings-test.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/controllers/settings-test.js b/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/controllers/settings-test.js index ef1b3d8..0101ceb 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/controllers/settings-test.js +++ b/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/controllers/settings-test.js @@ -29,7 +29,12 @@ moduleFor('controller:settings', 'SettingsController', { 'controller:index/history-query/explain', 'controller:columns', 'controller:udfs', - 'controller:index/history-query/logs' + 'controller:index/history-query/logs', + 'controller:visual-explain', + 'controller:tez-ui', + 'controller:tables', + 'adapter:database', + 'adapter:application' ] }); @@ -48,6 +53,7 @@ test('can add a setting', function() { test('hasSettings return true if there are settings', function() { var controller = this.subject(); + controller.get('currentSettings'); ok(!controller.hasSettings(null), 'No settings => return false'); Ember.run(function() { @@ -81,12 +87,21 @@ test('validate', function() { predefinedSettings: predefinedSettings }); + controller.set('openQueries.update', function () { + var defer = Ember.RSVP.defer(); + defer.resolve(); + + return defer.promise; + }); + var settings = [ Ember.Object.create({key: { name: 'some.key' }, value: 'value'}), Ember.Object.create({key: { name: 'some.key' }, value: '123'}) ]; Ember.run(function() { + controller.set('index.model', Ember.Object.create({ id: 1 })); + controller.get('currentSettings'); controller.setSettingForQuery(1, settings); }); http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/controllers/tez-ui-test.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/controllers/tez-ui-test.js b/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/controllers/tez-ui-test.js index f2755c5..e04abd5 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/controllers/tez-ui-test.js +++ b/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/controllers/tez-ui-test.js @@ -23,7 +23,7 @@ import { moduleFor('controller:tez-ui', 'TezUiController', { // Specify the other units that are required for this test. - // needs: ['controller:foo'] + needs: ['controller:index'] }); // Replace this with your real tests.