TEZ-3529. Tez UI: Add 'All Queries' table in the landing page along 'All DAGs' page (sree)
Project: http://git-wip-us.apache.org/repos/asf/tez/repo Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/22e4fe19 Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/22e4fe19 Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/22e4fe19 Branch: refs/heads/master Commit: 22e4fe19dd3d9b47956a976be88ddd6e86f99bd5 Parents: 506c9bc Author: Sreenath Somarajapuram <[email protected]> Authored: Wed Jan 18 18:05:52 2017 +0530 Committer: Sreenath Somarajapuram <[email protected]> Committed: Wed Jan 18 18:05:52 2017 +0530 ---------------------------------------------------------------------- CHANGES.txt | 1 + tez-ui/src/main/webapp/app/adapters/timeline.js | 5 +- .../webapp/app/components/dags-pagination-ui.js | 106 ---------- .../main/webapp/app/components/pagination-ui.js | 106 ++++++++++ .../app/components/queries-page-search.js | 47 +++++ .../main/webapp/app/controllers/application.js | 4 +- tez-ui/src/main/webapp/app/controllers/dags.js | 166 ---------------- tez-ui/src/main/webapp/app/controllers/home.js | 31 +++ .../main/webapp/app/controllers/home/index.js | 169 ++++++++++++++++ .../main/webapp/app/controllers/home/queries.js | 191 +++++++++++++++++++ tez-ui/src/main/webapp/app/entities/entity.js | 38 +++- tez-ui/src/main/webapp/app/models/hive-query.js | 48 +++++ tez-ui/src/main/webapp/app/router.js | 6 +- tez-ui/src/main/webapp/app/routes/dags.js | 172 ----------------- tez-ui/src/main/webapp/app/routes/home.js | 29 +++ tez-ui/src/main/webapp/app/routes/home/index.js | 103 ++++++++++ .../src/main/webapp/app/routes/home/queries.js | 66 +++++++ .../main/webapp/app/routes/server-side-ops.js | 107 +++++++++++ .../main/webapp/app/serializers/hive-query.js | 63 +++++- tez-ui/src/main/webapp/app/styles/app.less | 1 + .../webapp/app/styles/queries-page-search.less | 78 ++++++++ .../templates/components/dags-pagination-ui.hbs | 48 ----- .../app/templates/components/pagination-ui.hbs | 48 +++++ .../components/queries-page-search.hbs | 48 +++++ tez-ui/src/main/webapp/app/templates/dags.hbs | 42 ---- tez-ui/src/main/webapp/app/templates/home.hbs | 20 ++ .../main/webapp/app/templates/home/index.hbs | 40 ++++ .../main/webapp/app/templates/home/queries.hbs | 40 ++++ .../components/dags-pagination-ui-test.js | 158 --------------- .../components/pagination-ui-test.js | 158 +++++++++++++++ .../components/queries-page-search-test.js | 61 ++++++ .../webapp/tests/unit/adapters/timeline-test.js | 5 + .../tests/unit/controllers/application-test.js | 10 +- .../webapp/tests/unit/controllers/dags-test.js | 52 ----- .../webapp/tests/unit/controllers/home-test.js | 46 +++++ .../tests/unit/controllers/home/index-test.js | 126 ++++++++++++ .../tests/unit/controllers/home/queries-test.js | 115 +++++++++++ .../webapp/tests/unit/entities/entity-test.js | 57 +++++- .../webapp/tests/unit/models/hive-query-test.js | 28 +++ .../main/webapp/tests/unit/routes/dags-test.js | 175 ----------------- .../main/webapp/tests/unit/routes/home-test.js | 32 ++++ .../webapp/tests/unit/routes/home/index-test.js | 162 ++++++++++++++++ .../tests/unit/routes/home/queries-test.js | 75 ++++++++ .../tests/unit/routes/server-side-ops-test.js | 176 +++++++++++++++++ .../tests/unit/serializers/hive-query-test.js | 76 +++++++- 45 files changed, 2380 insertions(+), 955 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tez/blob/22e4fe19/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index 6538006..9eb7a55 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -163,6 +163,7 @@ ALL CHANGES: TEZ-3555. Tez UI: Build is failing in RHEL6 TEZ-3570. Tez UI: Wait for sometime before tooltips are displayed TEZ-3504. Tez UI: Duration is displaying invalid values when start or end time is invalid + TEZ-3529. Tez UI: Add 'All Queries' table in the landing page along 'All DAGs' page Release 0.8.5: Unreleased http://git-wip-us.apache.org/repos/asf/tez/blob/22e4fe19/tez-ui/src/main/webapp/app/adapters/timeline.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/adapters/timeline.js b/tez-ui/src/main/webapp/app/adapters/timeline.js index e2b4ef3..4b74dd1 100644 --- a/tez-ui/src/main/webapp/app/adapters/timeline.js +++ b/tez-ui/src/main/webapp/app/adapters/timeline.js @@ -37,7 +37,10 @@ export default AbstractAdapter.extend({ dagName: 'dagName', user: "user", status: "status", - callerID: "callerId" + callerID: "callerId", + requestuser: "requestuser", + executionMode: "executionmode", + callerId: "callerId" }, stringifyFilters: function (filters) { http://git-wip-us.apache.org/repos/asf/tez/blob/22e4fe19/tez-ui/src/main/webapp/app/components/dags-pagination-ui.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/components/dags-pagination-ui.js b/tez-ui/src/main/webapp/app/components/dags-pagination-ui.js deleted file mode 100644 index 4983ea2..0000000 --- a/tez-ui/src/main/webapp/app/components/dags-pagination-ui.js +++ /dev/null @@ -1,106 +0,0 @@ -/** - * 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.Component.extend({ - tableDefinition: null, - dataProcessor: null, - - classNames: ['pagination-ui'], - isVisible: Ember.computed.alias('tableDefinition.enablePagination'), - - showFirst: Ember.computed('_possiblePages', function () { - return this.get("dataProcessor.totalPages") && this.get('_possiblePages.0.pageNum') !== 1; - }), - - rowCountOptions: Ember.computed('tableDefinition.rowCountOptions', 'tableDefinition.rowCount', function () { - var options = this.get('tableDefinition.rowCountOptions'), - rowCount = this.get('tableDefinition.rowCount'); - - return options.map(function (option) { - return { - value: option, - selected: option === rowCount - }; - }); - }), - - _possiblePages: Ember.computed('tableDefinition.pageNum', - 'tableDefinition.moreAvailable', - 'dataProcessor.totalPages', function () { - var pageNum = this.get('tableDefinition.pageNum'), - totalPages = this.get('dataProcessor.totalPages'), - possiblePages = [], - startPage = 1, - endPage = totalPages, - delta = 0; - - if(this.get('tableDefinition.moreAvailable')) { - totalPages++; - } - - if(totalPages > 1) { - startPage = pageNum - 1; - endPage = pageNum + 1; - - if(startPage < 1) { - delta = 1 - startPage; - } - else if(endPage > totalPages) { - delta = totalPages - endPage; - } - - startPage += delta; - endPage += delta; - } - - startPage = Math.max(startPage, 1); - endPage = Math.min(endPage, totalPages); - - while(startPage <= endPage) { - possiblePages.push({ - isCurrent: startPage === pageNum, - isLoadPage: startPage === totalPages, - pageNum: startPage++, - }); - } - - return possiblePages; - }), - - actions: { - rowSelected: function (value) { - value = parseInt(value); - if(this.get('tableDefinition.rowCount') !== value) { - this.get('parentView').send('rowChanged', value); - } - }, - changePage: function (value) { - if(value === 1) { - this.get('parentView').sendAction('reload'); - } - else if(this.get('dataProcessor.totalPages') < value) { - this.get('parentView').sendAction('loadPage', value); - } - else { - this.get('parentView').send('pageChanged', value); - } - }, - } -}); http://git-wip-us.apache.org/repos/asf/tez/blob/22e4fe19/tez-ui/src/main/webapp/app/components/pagination-ui.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/components/pagination-ui.js b/tez-ui/src/main/webapp/app/components/pagination-ui.js new file mode 100644 index 0000000..4983ea2 --- /dev/null +++ b/tez-ui/src/main/webapp/app/components/pagination-ui.js @@ -0,0 +1,106 @@ +/** + * 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.Component.extend({ + tableDefinition: null, + dataProcessor: null, + + classNames: ['pagination-ui'], + isVisible: Ember.computed.alias('tableDefinition.enablePagination'), + + showFirst: Ember.computed('_possiblePages', function () { + return this.get("dataProcessor.totalPages") && this.get('_possiblePages.0.pageNum') !== 1; + }), + + rowCountOptions: Ember.computed('tableDefinition.rowCountOptions', 'tableDefinition.rowCount', function () { + var options = this.get('tableDefinition.rowCountOptions'), + rowCount = this.get('tableDefinition.rowCount'); + + return options.map(function (option) { + return { + value: option, + selected: option === rowCount + }; + }); + }), + + _possiblePages: Ember.computed('tableDefinition.pageNum', + 'tableDefinition.moreAvailable', + 'dataProcessor.totalPages', function () { + var pageNum = this.get('tableDefinition.pageNum'), + totalPages = this.get('dataProcessor.totalPages'), + possiblePages = [], + startPage = 1, + endPage = totalPages, + delta = 0; + + if(this.get('tableDefinition.moreAvailable')) { + totalPages++; + } + + if(totalPages > 1) { + startPage = pageNum - 1; + endPage = pageNum + 1; + + if(startPage < 1) { + delta = 1 - startPage; + } + else if(endPage > totalPages) { + delta = totalPages - endPage; + } + + startPage += delta; + endPage += delta; + } + + startPage = Math.max(startPage, 1); + endPage = Math.min(endPage, totalPages); + + while(startPage <= endPage) { + possiblePages.push({ + isCurrent: startPage === pageNum, + isLoadPage: startPage === totalPages, + pageNum: startPage++, + }); + } + + return possiblePages; + }), + + actions: { + rowSelected: function (value) { + value = parseInt(value); + if(this.get('tableDefinition.rowCount') !== value) { + this.get('parentView').send('rowChanged', value); + } + }, + changePage: function (value) { + if(value === 1) { + this.get('parentView').sendAction('reload'); + } + else if(this.get('dataProcessor.totalPages') < value) { + this.get('parentView').sendAction('loadPage', value); + } + else { + this.get('parentView').send('pageChanged', value); + } + }, + } +}); http://git-wip-us.apache.org/repos/asf/tez/blob/22e4fe19/tez-ui/src/main/webapp/app/components/queries-page-search.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/components/queries-page-search.js b/tez-ui/src/main/webapp/app/components/queries-page-search.js new file mode 100644 index 0000000..2b3f196 --- /dev/null +++ b/tez-ui/src/main/webapp/app/components/queries-page-search.js @@ -0,0 +1,47 @@ +/** + * 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.Component.extend({ + classNames: ['queries-page-search'], + + queryID: Ember.computed.oneWay("tableDefinition.queryID"), + user: Ember.computed.oneWay("tableDefinition.user"), + requestUser: Ember.computed.oneWay("tableDefinition.requestUser"), + + sendSearch: function () { + this.get('parentView').sendAction('search', { + queryID: this.get("queryID"), + user: this.get("user"), + requestUser: this.get("requestUser"), + }); + }, + + actions: { + statusChanged: function (value) { + this.set("status", value); + }, + statusKeyPress: function () { + this.sendSearch(); + }, + search: function () { + this.sendSearch(); + } + } +}); http://git-wip-us.apache.org/repos/asf/tez/blob/22e4fe19/tez-ui/src/main/webapp/app/controllers/application.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/controllers/application.js b/tez-ui/src/main/webapp/app/controllers/application.js index 4911a16..5377b92 100644 --- a/tez-ui/src/main/webapp/app/controllers/application.js +++ b/tez-ui/src/main/webapp/app/controllers/application.js @@ -19,8 +19,8 @@ import Ember from 'ember'; const BREADCRUMB_PREFIX = [{ - text: "All DAGs", - routeName: 'application' + text: "Home", + routeName: "application" }]; export default Ember.Controller.extend({ http://git-wip-us.apache.org/repos/asf/tez/blob/22e4fe19/tez-ui/src/main/webapp/app/controllers/dags.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/controllers/dags.js b/tez-ui/src/main/webapp/app/controllers/dags.js deleted file mode 100644 index a25ffa3..0000000 --- a/tez-ui/src/main/webapp/app/controllers/dags.js +++ /dev/null @@ -1,166 +0,0 @@ -/** - * 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 TableController from './table'; -import ColumnDefinition from 'em-table/utils/column-definition'; -import TableDefinition from 'em-table/utils/table-definition'; - -export default TableController.extend({ - - queryParams: ["dagName", "dagID", "submitter", "status", "appID", "callerID"], - dagName: "", - dagID: "", - submitter: "", - status: "", - appID: "", - callerID: "", - - // Because pageNo is a query param added by table controller, and in the current design - // we don't want page to be a query param as only the first page will be loaded first. - pageNum: 1, - - breadcrumbs: [], - - moreAvailable: false, - loadingMore: false, - - headerComponentNames: ['dags-page-search', 'table-controls', 'dags-pagination-ui'], - - _definition: TableDefinition.create(), - // Using computed, as observer won't fire if the property is not used - definition: Ember.computed("dagName", "dagID", "submitter", "status", - "appID", "callerID", "pageNum", "moreAvailable", "loadingMore", function () { - - var definition = this.get("_definition"); - - definition.setProperties({ - dagName: this.get("dagName"), - dagID: this.get("dagID"), - submitter: this.get("submitter"), - status: this.get("status"), - appID: this.get("appID"), - callerID: this.get("callerID"), - - pageNum: this.get("pageNum"), - - moreAvailable: this.get("moreAvailable"), - loadingMore: this.get("loadingMore") - }); - - return definition; - }), - - columns: ColumnDefinition.make([{ - id: 'name', - headerTitle: 'Dag Name', - contentPath: 'name', - cellComponentName: 'em-table-linked-cell', - getCellContent: function (row) { - return { - routeName: "dag", - model: row.get("entityID"), - text: row.get("name") - }; - } - },{ - id: 'entityID', - headerTitle: 'Id', - contentPath: 'entityID' - },{ - id: 'submitter', - headerTitle: 'Submitter', - contentPath: 'submitter' - },{ - id: 'status', - headerTitle: 'Status', - contentPath: 'status', - cellComponentName: 'em-table-status-cell', - observePath: true - },{ - id: 'progress', - headerTitle: 'Progress', - contentPath: 'progress', - cellComponentName: 'em-table-progress-cell', - observePath: true - },{ - id: 'startTime', - headerTitle: 'Start Time', - contentPath: 'startTime', - cellComponentName: 'date-formatter', - },{ - id: 'endTime', - headerTitle: 'End Time', - contentPath: 'endTime', - cellComponentName: 'date-formatter', - },{ - id: 'duration', - headerTitle: 'Duration', - contentPath: 'duration', - cellDefinition: { - type: 'duration' - } - },{ - id: 'appID', - headerTitle: 'Application Id', - contentPath: 'appID', - cellComponentName: 'em-table-linked-cell', - getCellContent: function (row) { - return { - routeName: "app", - model: row.get("appID"), - text: row.get("appID") - }; - } - },{ - id: 'queue', - headerTitle: 'Queue', - contentPath: 'queue' - },{ - id: 'callerID', - headerTitle: 'Caller ID', - contentPath: 'callerID' - },{ - id: 'callerContext', - headerTitle: 'Caller Context', - contentPath: 'callerContext' - },{ - id: 'logs', - headerTitle: 'Logs', - contentPath: 'containerLogs', - cellComponentName: "em-table-linked-cell", - cellDefinition: { - target: "_blank" - } - }]), - - getCounterColumns: function () { - return this._super().concat(this.get('env.app.tables.defaultColumns.dagCounters')); - }, - - actions: { - search: function (properties) { - this.setProperties(properties); - }, - pageChanged: function (pageNum) { - this.set("pageNum", pageNum); - }, - } - -}); http://git-wip-us.apache.org/repos/asf/tez/blob/22e4fe19/tez-ui/src/main/webapp/app/controllers/home.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/controllers/home.js b/tez-ui/src/main/webapp/app/controllers/home.js new file mode 100644 index 0000000..fd2dad7 --- /dev/null +++ b/tez-ui/src/main/webapp/app/controllers/home.js @@ -0,0 +1,31 @@ +/** + * 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 AbstractController from './abstract'; + +export default AbstractController.extend({ + breadcrumbs: null, + + tabs: [{ + text: "All DAGs", + routeName: "home.index" + }, { + text: "Hive Queries", + routeName: "home.queries" + }] +}); http://git-wip-us.apache.org/repos/asf/tez/blob/22e4fe19/tez-ui/src/main/webapp/app/controllers/home/index.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/controllers/home/index.js b/tez-ui/src/main/webapp/app/controllers/home/index.js new file mode 100644 index 0000000..bf9dcde --- /dev/null +++ b/tez-ui/src/main/webapp/app/controllers/home/index.js @@ -0,0 +1,169 @@ +/** + * 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 TableController from '../table'; +import ColumnDefinition from 'em-table/utils/column-definition'; +import TableDefinition from 'em-table/utils/table-definition'; + +export default TableController.extend({ + + queryParams: ["dagName", "dagID", "submitter", "status", "appID", "callerID"], + dagName: "", + dagID: "", + submitter: "", + status: "", + appID: "", + callerID: "", + + // Because pageNo is a query param added by table controller, and in the current design + // we don't want page to be a query param as only the first page will be loaded first. + pageNum: 1, + + breadcrumbs: [{ + text: "All DAGs", + routeName: "home.index", + }], + + moreAvailable: false, + loadingMore: false, + + headerComponentNames: ['dags-page-search', 'table-controls', 'pagination-ui'], + + _definition: TableDefinition.create(), + // Using computed, as observer won't fire if the property is not used + definition: Ember.computed("dagName", "dagID", "submitter", "status", + "appID", "callerID", "pageNum", "moreAvailable", "loadingMore", function () { + + var definition = this.get("_definition"); + + definition.setProperties({ + dagName: this.get("dagName"), + dagID: this.get("dagID"), + submitter: this.get("submitter"), + status: this.get("status"), + appID: this.get("appID"), + callerID: this.get("callerID"), + + pageNum: this.get("pageNum"), + + moreAvailable: this.get("moreAvailable"), + loadingMore: this.get("loadingMore") + }); + + return definition; + }), + + columns: ColumnDefinition.make([{ + id: 'name', + headerTitle: 'Dag Name', + contentPath: 'name', + cellComponentName: 'em-table-linked-cell', + getCellContent: function (row) { + return { + routeName: "dag", + model: row.get("entityID"), + text: row.get("name") + }; + } + },{ + id: 'entityID', + headerTitle: 'Id', + contentPath: 'entityID' + },{ + id: 'submitter', + headerTitle: 'Submitter', + contentPath: 'submitter' + },{ + id: 'status', + headerTitle: 'Status', + contentPath: 'status', + cellComponentName: 'em-table-status-cell', + observePath: true + },{ + id: 'progress', + headerTitle: 'Progress', + contentPath: 'progress', + cellComponentName: 'em-table-progress-cell', + observePath: true + },{ + id: 'startTime', + headerTitle: 'Start Time', + contentPath: 'startTime', + cellComponentName: 'date-formatter', + },{ + id: 'endTime', + headerTitle: 'End Time', + contentPath: 'endTime', + cellComponentName: 'date-formatter', + },{ + id: 'duration', + headerTitle: 'Duration', + contentPath: 'duration', + cellDefinition: { + type: 'duration' + } + },{ + id: 'appID', + headerTitle: 'Application Id', + contentPath: 'appID', + cellComponentName: 'em-table-linked-cell', + getCellContent: function (row) { + return { + routeName: "app", + model: row.get("appID"), + text: row.get("appID") + }; + } + },{ + id: 'queue', + headerTitle: 'Queue', + contentPath: 'queue' + },{ + id: 'callerID', + headerTitle: 'Caller ID', + contentPath: 'callerID' + },{ + id: 'callerContext', + headerTitle: 'Caller Context', + contentPath: 'callerContext' + },{ + id: 'logs', + headerTitle: 'Logs', + contentPath: 'containerLogs', + cellComponentName: "em-table-linked-cell", + cellDefinition: { + target: "_blank" + } + }]), + + getCounterColumns: function () { + return this._super().concat(this.get('env.app.tables.defaultColumns.dagCounters')); + }, + + actions: { + search: function (properties) { + this.setProperties(properties); + }, + pageChanged: function (pageNum) { + this.set("pageNum", pageNum); + }, + } + +}); http://git-wip-us.apache.org/repos/asf/tez/blob/22e4fe19/tez-ui/src/main/webapp/app/controllers/home/queries.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/controllers/home/queries.js b/tez-ui/src/main/webapp/app/controllers/home/queries.js new file mode 100644 index 0000000..53d284c --- /dev/null +++ b/tez-ui/src/main/webapp/app/controllers/home/queries.js @@ -0,0 +1,191 @@ +/** + * 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 TableController from '../table'; +import ColumnDefinition from 'em-table/utils/column-definition'; +import TableDefinition from 'em-table/utils/table-definition'; + +export default TableController.extend({ + + queryParams: ["queryID", "user", "requestUser"], + queryID: "", + user: "", + requestUser: "", + + // Because pageNo is a query param added by table controller, and in the current design + // we don't want page to be a query param as only the first page will be loaded first. + pageNum: 1, + + breadcrumbs: [{ + text: "All Queries", + routeName: "home.queries", + }], + + moreAvailable: false, + loadingMore: false, + + headerComponentNames: ['queries-page-search', 'table-controls', 'pagination-ui'], + + _definition: TableDefinition.create(), + // Using computed, as observer won't fire if the property is not used + definition: Ember.computed("queryID", "user", "requestUser", + "pageNum", "moreAvailable", "loadingMore", function () { + + var definition = this.get("_definition"); + + definition.setProperties({ + queryID: this.get("queryID"), + user: this.get("user"), + requestUser: this.get("requestUser"), + + pageNum: this.get("pageNum"), + + moreAvailable: this.get("moreAvailable"), + loadingMore: this.get("loadingMore") + }); + + return definition; + }), + + columns: ColumnDefinition.make([{ + id: 'entityID', + headerTitle: 'Query ID', + contentPath: 'entityID', + cellComponentName: 'em-table-linked-cell', + getCellContent: function (row) { + return { + model: row.get("entityID"), + text: row.get("entityID") + }; + } + },{ + id: 'status', + headerTitle: 'Status', + contentPath: 'status', + cellComponentName: 'em-table-status-cell', + },{ + id: 'requestUser', + headerTitle: 'User', + contentPath: 'requestUser', + },{ + id: 'tablesRead', + headerTitle: 'Tables Read', + contentPath: 'tablesRead', + getCellContent: function (row) { + var tablesRead = row.get("tablesRead"); + if(tablesRead && tablesRead.length) { + return tablesRead.join(","); + } + } + },{ + id: 'tablesWritten', + headerTitle: 'Tables Written', + contentPath: 'tablesWritten', + getCellContent: function (row) { + var tablesWritten = row.get("tablesWritten"); + if(tablesWritten && tablesWritten.length) { + return tablesWritten.join(","); + } + } + },{ + id: 'queue', + headerTitle: 'Queue', + contentPath: 'queue', + },{ + id: 'hiveAddress', + headerTitle: 'Hive Server 2 Address', + contentPath: 'hiveAddress' + },{ + id: 'appID', + headerTitle: 'Application Id', + contentPath: 'dag.firstObject.appID', + cellComponentName: 'em-table-linked-cell', + getCellContent: function (row) { + return { + routeName: "app", + model: row.get("dag.firstObject.appID"), + text: row.get("dag.firstObject.appID") + }; + } + },{ + id: 'queryName', + headerTitle: 'Query Name', + contentPath: 'queryName' + },{ + id: 'dagName', + headerTitle: 'DAG', + contentPath: 'dag.firstObject.name', + cellComponentName: 'em-table-linked-cell', + getCellContent: function (row) { + return { + routeName: "dag", + model: row.get("dag.firstObject.entityID"), + text: row.get("dag.firstObject.name") + }; + } + },{ + id: 'instanceType', + headerTitle: 'Client Type', + contentPath: 'instanceType' + },{ + id: 'sessionID', + headerTitle: 'Session ID', + contentPath: 'sessionID', + },{ + id: 'clientAddress', + headerTitle: 'Client Address', + contentPath: 'clientAddress', + },{ + id: 'threadName', + headerTitle: 'Thread Name', + contentPath: 'threadName', + },{ + id: 'startTime', + headerTitle: 'Start Time', + contentPath: 'startTime', + cellComponentName: 'date-formatter', + },{ + id: 'endTime', + headerTitle: 'End Time', + contentPath: 'endTime', + cellComponentName: 'date-formatter', + },{ + id: 'duration', + headerTitle: 'Duration', + contentPath: 'duration', + cellDefinition: { + type: 'duration' + } + }]), + + getCounterColumns: function () { + return []; + }, + + actions: { + search: function (properties) { + this.setProperties(properties); + }, + pageChanged: function (pageNum) { + this.set("pageNum", pageNum); + }, + } + +}); http://git-wip-us.apache.org/repos/asf/tez/blob/22e4fe19/tez-ui/src/main/webapp/app/entities/entity.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/entities/entity.js b/tez-ui/src/main/webapp/app/entities/entity.js index 462a148..36cbd8c 100644 --- a/tez-ui/src/main/webapp/app/entities/entity.js +++ b/tez-ui/src/main/webapp/app/entities/entity.js @@ -55,7 +55,7 @@ var Entity = Ember.Object.extend(NameMixin, { var need = { name: name, type: name, - idKey: needOptions, + idKey: "", loadType: "", // Possible values lazy, demand silent: false, @@ -66,8 +66,6 @@ var Entity = Ember.Object.extend(NameMixin, { overrides = {}; if(typeof needOptions === 'object') { - Ember.assert(`idKey not defined for need '${name}'!`, needOptions.idKey); - if(MoreObject.isFunction(needOptions.urlParams)) { overrides.urlParams = needOptions.urlParams.call(needOptions, parentModel); } @@ -75,8 +73,18 @@ var Entity = Ember.Object.extend(NameMixin, { overrides.queryParams = needOptions.queryParams.call(needOptions, parentModel); } + overrides.idKey = needOptions.idKey; + overrides = Ember.Object.create({}, needOptions, overrides); } + else if(typeof needOptions === 'string') { + overrides.idKey = needOptions; + } + + if(typeof overrides.idKey === 'string') { + overrides.withID = true; + overrides.id = parentModel.get(overrides.idKey); + } if(queryParams) { overrides.queryParams = Ember.$.extend({}, overrides.queryParams, queryParams); @@ -101,13 +109,23 @@ var Entity = Ember.Object.extend(NameMixin, { index = index || 0; type = types[index]; - needLoader = loader.queryRecord( - type, - parentModel.get(needOptions.idKey), - options, - needOptions.queryParams, - needOptions.urlParams - ); + if(needOptions.withID) { + needLoader = loader.queryRecord( + type, + needOptions.id, + options, + needOptions.queryParams, + needOptions.urlParams + ); + } + else { + needLoader = loader.query( + type, + needOptions.queryParams, + options, + needOptions.urlParams + ); + } needLoader = needLoader.then(function (model) { parentModel.set(needOptions.name, model); http://git-wip-us.apache.org/repos/asf/tez/blob/22e4fe19/tez-ui/src/main/webapp/app/models/hive-query.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/models/hive-query.js b/tez-ui/src/main/webapp/app/models/hive-query.js index d4e6719..3cb5063 100644 --- a/tez-ui/src/main/webapp/app/models/hive-query.js +++ b/tez-ui/src/main/webapp/app/models/hive-query.js @@ -16,10 +16,58 @@ * limitations under the License. */ +import Ember from 'ember'; import DS from 'ember-data'; import AbstractModel from './abstract'; export default AbstractModel.extend({ + + needs: { + dag: { + type: "dag", + silent: true, + queryParams: function (model) { + return { + callerId: model.get("entityID") + }; + }, + } + }, + + queryName: DS.attr('string'), + queryText: DS.attr("string"), + + dag: DS.attr('object'), + + sessionID: DS.attr('string'), + operationID: DS.attr('string'), + + instanceType: DS.attr('string'), + executionMode: DS.attr('string'), // Would be ideally TEZ + + domain: DS.attr('string'), + threadName: DS.attr('string'), + queue: DS.attr('string'), + version: DS.attr('string'), + + hiveAddress: DS.attr('string'), + clientAddress: DS.attr('string'), + + user: DS.attr('string'), + requestUser: DS.attr('string'), + + tablesRead: DS.attr('object'), + tablesWritten: DS.attr('object'), + + status: DS.attr('string'), + + startTime: DS.attr("number"), + endTime: DS.attr("number"), + duration: Ember.computed("startTime", "endTime", function () { + var duration = this.get("endTime") - this.get("startTime"); + return duration > 0 ? duration : null; + }), + }); http://git-wip-us.apache.org/repos/asf/tez/blob/22e4fe19/tez-ui/src/main/webapp/app/router.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/router.js b/tez-ui/src/main/webapp/app/router.js index 7f18ae6..0bbf842 100644 --- a/tez-ui/src/main/webapp/app/router.js +++ b/tez-ui/src/main/webapp/app/router.js @@ -24,7 +24,9 @@ const Router = Ember.Router.extend({ }); Router.map(function() { - this.route('dags', { path: '/' }); + this.route('home', {path: '/'}, function() { + this.route('queries'); + }); this.route('dag', {path: '/dag/:dag_id'}, function() { this.route('vertices'); this.route('tasks'); @@ -53,8 +55,6 @@ Router.map(function() { this.route('dags'); this.route('configs'); }); - this.route('multi-am-pollster'); - this.route('single-am-pollster'); }); export default Router; http://git-wip-us.apache.org/repos/asf/tez/blob/22e4fe19/tez-ui/src/main/webapp/app/routes/dags.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/routes/dags.js b/tez-ui/src/main/webapp/app/routes/dags.js deleted file mode 100644 index dae27b2..0000000 --- a/tez-ui/src/main/webapp/app/routes/dags.js +++ /dev/null @@ -1,172 +0,0 @@ -/** - * 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 AbstractRoute from './abstract'; - -const REFRESH = {refreshModel: true}; - -export default AbstractRoute.extend({ - title: "All DAGs", - - queryParams: { - dagName: REFRESH, - dagID: REFRESH, - submitter: REFRESH, - status: REFRESH, - appID: REFRESH, - callerID: REFRESH, - - rowCount: REFRESH - }, - - loaderQueryParams: { - dagName: "dagName", - dagID: "dagID", - user: "submitter", - status: "status", - appID: "appID", - callerID: "callerID", - - limit: "rowCount", - }, - - loaderNamespace: "dags", - - fromId: null, - - setupController: function (controller, model) { - this._super(controller, model); - Ember.run.later(this, "startCrumbBubble"); - }, - - // Client side filtering to ensure that records are relevant after status correction - filterRecords: function (records, query) { - query = { - name: query.dagName, - entityID: query.dagID, - submitter: query.submitter, - status: query.status, - appID: query.appID, - callerID: query.callerID - }; - - return records.filter(function (record) { - for(var propName in query) { - if(query[propName] && query[propName] !== record.get(propName)) { - return false; - } - } - return true; - }); - }, - - load: function (value, query/*, options*/) { - var loader, - that = this, - limit = this.get("controller.rowCount") || query.limit; - - if(query.dagID) { - that.set("loadedRecords", []); - loader = this.get("loader").queryRecord('dag', query.dagID, {reload: true}).then(function (record) { - return [record]; - },function () { - return []; - }); - } - else { - query = Ember.$.extend({}, query, { - limit: limit + 1 - }); - loader = this.get("loader").query('dag', query, {reload: true}); - } - - return loader.then(function (records) { - - if(records.get("length") > limit) { - let lastRecord = records.popObject(); - that.set("controller.moreAvailable", true); - that.set("fromId", lastRecord.get("entityID")); - } - else { - that.set("controller.moreAvailable", false); - } - - records = that.filterRecords(records, query); - records.forEach(function (record) { - if(record.get("status") === "RUNNING") { - that.get("loader").loadNeed(record, "am", {reload: true}).catch(function () { - record.set("am", null); - }); - } - }); - return records; - }); - }, - - loadNewPage: function () { - var query = this.get("currentQuery"), - that = this; - - query = Ember.$.extend({}, query, { - fromId: this.get("fromId") - }); - - this.set("controller.loadingMore", true); - return this.load(null, query).then(function (data) { - if(that.get("controller.loadingMore")) { - that.set("controller.loadingMore", false); - that.get("loadedValue").pushObjects(data); - return data; - } - }); - }, - - actions: { - setLoadTime: function (time) { - this.set("controller.loadTime", time); - }, - loadPage: function (page) { - var that = this; - if(this.get("controller.moreAvailable") && !this.get("controller.loadingMore")) { - this.send("resetTooltip"); - this.loadNewPage().then(function (data) { - if(data) { - that.set("controller.pageNum", page); - } - return data; - }); - } - }, - reload: function () { - this.set("controller.loadingMore", false); - this.set("controller.pageNum", 1); - this._super(); - }, - willTransition: function () { - var loader = this.get("loader"); - loader.unloadAll("dag"); - loader.unloadAll("ahs-app"); - - this.set("controller.pageNum", 1); - - this._super(); - }, - } -}); http://git-wip-us.apache.org/repos/asf/tez/blob/22e4fe19/tez-ui/src/main/webapp/app/routes/home.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/routes/home.js b/tez-ui/src/main/webapp/app/routes/home.js new file mode 100644 index 0000000..e685121 --- /dev/null +++ b/tez-ui/src/main/webapp/app/routes/home.js @@ -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. + */ + +import AbstractRoute from './abstract'; + +export default AbstractRoute.extend({ + title: "Home", + + actions: { + setLoadTime: function (time) { + this.set("controller.loadTime", time); + } + } +}); http://git-wip-us.apache.org/repos/asf/tez/blob/22e4fe19/tez-ui/src/main/webapp/app/routes/home/index.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/routes/home/index.js b/tez-ui/src/main/webapp/app/routes/home/index.js new file mode 100644 index 0000000..dedbb92 --- /dev/null +++ b/tez-ui/src/main/webapp/app/routes/home/index.js @@ -0,0 +1,103 @@ +/** + * 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 ServerSideOpsRoute from '../server-side-ops'; + +const REFRESH = {refreshModel: true}; + +export default ServerSideOpsRoute.extend({ + title: "All DAGs", + + queryParams: { + dagName: REFRESH, + dagID: REFRESH, + submitter: REFRESH, + status: REFRESH, + appID: REFRESH, + callerID: REFRESH, + + rowCount: REFRESH + }, + + loaderQueryParams: { + dagName: "dagName", + id: "dagID", + user: "submitter", + status: "status", + appID: "appID", + callerID: "callerID", + + limit: "rowCount", + }, + + entityType: "dag", + loaderNamespace: "dags", + + setupController: function (controller, model) { + this._super(controller, model); + Ember.run.later(this, "startCrumbBubble"); + }, + + // Client side filtering to ensure that records are relevant after status correction + filterRecords: function (records, query) { + query = { + name: query.dagName, + entityID: query.id, + submitter: query.submitter, + status: query.status, + appID: query.appID, + callerID: query.callerID + }; + + return records.filter(function (record) { + for(var propName in query) { + if(query[propName] && query[propName] !== record.get(propName)) { + return false; + } + } + return true; + }); + }, + + load: function (value, query, options) { + var loader = this._super(value, query, options), + that = this; + return loader.then(function (records) { + records = that.filterRecords(records, query); + records.forEach(function (record) { + if(record.get("status") === "RUNNING") { + that.get("loader").loadNeed(record, "am", {reload: true}).catch(function () { + record.set("am", null); + }); + } + }); + return records; + }); + }, + + actions: { + willTransition: function () { + var loader = this.get("loader"); + loader.unloadAll("dag"); + loader.unloadAll("ahs-app"); + this._super(); + }, + } +}); http://git-wip-us.apache.org/repos/asf/tez/blob/22e4fe19/tez-ui/src/main/webapp/app/routes/home/queries.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/routes/home/queries.js b/tez-ui/src/main/webapp/app/routes/home/queries.js new file mode 100644 index 0000000..983ba58 --- /dev/null +++ b/tez-ui/src/main/webapp/app/routes/home/queries.js @@ -0,0 +1,66 @@ +/** + * 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 ServerSideOpsRoute from '../server-side-ops'; + +const REFRESH = {refreshModel: true}; + +export default ServerSideOpsRoute.extend({ + title: "Hive Queries", + + queryParams: { + queryID: REFRESH, + user: REFRESH, + requestUser: REFRESH, + + rowCount: REFRESH + }, + + loaderQueryParams: { + id: "queryID", + requestuser: "requestUser", + user: "user", + + limit: "rowCount", + }, + + entityType: "hive-query", + loaderNamespace: "queries", + + fromId: null, + + load: function (value, query, options) { + query.executionMode = "TEZ"; + return this._super(value, query, options); + }, + + setupController: function (controller, model) { + this._super(controller, model); + Ember.run.later(this, "startCrumbBubble"); + }, + + actions: { + willTransition: function () { + var loader = this.get("loader"); + loader.unloadAll("hive-query"); + this._super(); + }, + } +}); http://git-wip-us.apache.org/repos/asf/tez/blob/22e4fe19/tez-ui/src/main/webapp/app/routes/server-side-ops.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/routes/server-side-ops.js b/tez-ui/src/main/webapp/app/routes/server-side-ops.js new file mode 100644 index 0000000..85b4d03 --- /dev/null +++ b/tez-ui/src/main/webapp/app/routes/server-side-ops.js @@ -0,0 +1,107 @@ +/** + * 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 AbstractRoute from './abstract'; + +export default AbstractRoute.extend({ + + entityType: '', + fromId: null, + + load: function (value, query/*, options*/) { + var loader, + that = this, + limit = this.get("controller.rowCount") || query.limit, + entityType = this.get('entityType'); + + if(query.id) { + that.set("loadedRecords", []); + loader = this.get("loader").queryRecord(entityType, query.id, { + reload: true + }).then(function (record) { + return [record]; + },function () { + return []; + }); + } + else { + query = Ember.$.extend({}, query, { + limit: limit + 1 + }); + loader = this.get("loader").query(entityType, query, {reload: true}); + } + + return loader.then(function (records) { + if(records.get("length") > limit) { + let lastRecord = records.popObject(); + that.set("controller.moreAvailable", true); + that.set("fromId", lastRecord.get("entityID")); + } + else { + that.set("controller.moreAvailable", false); + that.set("fromId", null); + } + return records; + }); + }, + + loadNewPage: function () { + var query = this.get("currentQuery"), + that = this; + + query = Ember.$.extend({}, query, { + fromId: this.get("fromId") + }); + + this.set("controller.loadingMore", true); + return this.load(null, query).then(function (data) { + if(that.get("controller.loadingMore")) { + that.set("controller.loadingMore", false); + that.get("loadedValue").pushObjects(data); + return data; + } + }); + }, + + actions: { + loadPage: function (page) { + var that = this; + if(this.get("controller.moreAvailable") && !this.get("controller.loadingMore")) { + this.send("resetTooltip"); + this.loadNewPage().then(function (data) { + if(data) { + that.set("controller.pageNum", page); + } + return data; + }); + } + }, + reload: function () { + this.set("controller.loadingMore", false); + this.set("controller.pageNum", 1); + this._super(); + }, + willTransition: function () { + this.set("controller.pageNum", 1); + this._super(); + }, + } + +}); http://git-wip-us.apache.org/repos/asf/tez/blob/22e4fe19/tez-ui/src/main/webapp/app/serializers/hive-query.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/serializers/hive-query.js b/tez-ui/src/main/webapp/app/serializers/hive-query.js index b40bab8..69f44bc 100644 --- a/tez-ui/src/main/webapp/app/serializers/hive-query.js +++ b/tez-ui/src/main/webapp/app/serializers/hive-query.js @@ -20,9 +20,63 @@ import Ember from 'ember'; import TimelineSerializer from './timeline'; +function getEndTime(source) { + var time = Ember.get(source, 'otherinfo.endTime'), + event = source.events; + + if(!time && event) { + event = event.findBy('eventtype', 'QUERY_COMPLETED'); + if(event) { + time = event.timestamp; + } + } + + return time; +} + +function getStatus(source) { + var status = Ember.get(source, 'otherinfo.STATUS'); + + switch(status) { + case true: + return "SUCCEEDED"; + case false: + return "FAILED"; + default: + return "RUNNING"; + } +} + export default TimelineSerializer.extend({ maps: { - queryText: 'queryText', + queryName: 'primaryfilters.queryname.0', + + queryText: 'otherinfo.QUERY.queryText', + + sessionID: 'otherinfo.INVOKER_INFO', + operationID: 'primaryfilters.operationid.0', + + instanceType: 'otherinfo.HIVE_INSTANCE_TYPE', + executionMode: 'primaryfilters.executionmode.0', + + domain: 'domain', + threadName: 'otherinfo.THREAD_NAME', + queue: 'primaryfilters.queue.0', + version: 'otherinfo.VERSION', + + hiveAddress: 'otherinfo.HIVE_ADDRESS', + clientAddress: 'otherinfo.CLIENT_IP_ADDRESS', + + user: 'primaryfilters.user.0', + requestUser: 'primaryfilters.requestuser.0', + + tablesRead: 'primaryfilters.tablesread', + tablesWritten: 'primaryfilters.tableswritten', + + status: getStatus, + + startTime: 'starttime', + endTime: getEndTime, }, extractAttributes: function (modelClass, resourceHash) { @@ -30,12 +84,13 @@ export default TimelineSerializer.extend({ query = Ember.get(resourceHash, "data.otherinfo.QUERY"); if(query) { - let queryObj = {}; try{ - queryObj = JSON.parse(query); + data.otherinfo.QUERY = JSON.parse(query); }catch(e){} + } - data.queryText = Ember.get(queryObj, "queryText"); + if(!data.otherinfo.CLIENT_IP_ADDRESS) { + data.otherinfo.CLIENT_IP_ADDRESS = data.otherinfo.HIVE_ADDRESS; } return this._super(modelClass, resourceHash); http://git-wip-us.apache.org/repos/asf/tez/blob/22e4fe19/tez-ui/src/main/webapp/app/styles/app.less ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/styles/app.less b/tez-ui/src/main/webapp/app/styles/app.less index b4a4c47..85b02bd 100644 --- a/tez-ui/src/main/webapp/app/styles/app.less +++ b/tez-ui/src/main/webapp/app/styles/app.less @@ -33,6 +33,7 @@ // Components @import "tab-n-refresh"; @import "dags-page-search"; +@import "queries-page-search"; @import "table-controls"; @import "error-bar"; @import "caller-info"; http://git-wip-us.apache.org/repos/asf/tez/blob/22e4fe19/tez-ui/src/main/webapp/app/styles/queries-page-search.less ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/styles/queries-page-search.less b/tez-ui/src/main/webapp/app/styles/queries-page-search.less new file mode 100644 index 0000000..a22535c --- /dev/null +++ b/tez-ui/src/main/webapp/app/styles/queries-page-search.less @@ -0,0 +1,78 @@ +/** + * 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. + */ + +.queries-page-search { + text-align: justify; + + position: relative; + + width: 100%; + height: 65px; + + .form-group { + position: absolute; + left: 0px; + right: 35px; + } + + button { + position: absolute; + right: 0px; + top: 22px; + width: 30px; + height: 30px; + padding: 4px; + } + + .search-element { + display: inline-block; + width: 33.3%; + + vertical-align: top; + + padding-left: 3px; + + label { + margin-bottom: 2px; + } + } +} + +.all-queries-table { + .pagination-ui, .table-controls { + margin-top: -5px; + margin-bottom: 5px; + } +} + +@media screen and (min-width: 800px) { + .queries-page-search{ + float: left; + width: 50%; + + .form-group { + margin-bottom: 0px; + } + } + + .all-queries-table { + .pagination-ui, .table-controls { + margin-top: 21px; + } + } +} http://git-wip-us.apache.org/repos/asf/tez/blob/22e4fe19/tez-ui/src/main/webapp/app/templates/components/dags-pagination-ui.hbs ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/templates/components/dags-pagination-ui.hbs b/tez-ui/src/main/webapp/app/templates/components/dags-pagination-ui.hbs deleted file mode 100644 index 6f8730c..0000000 --- a/tez-ui/src/main/webapp/app/templates/components/dags-pagination-ui.hbs +++ /dev/null @@ -1,48 +0,0 @@ -{{! - * 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. -}} - -<ul class="page-list"> - {{#if showFirst}} - <li title="Go to first page" class="clickable" {{action 'changePage' 1}}> - First - </li> - {{/if}} - {{#each _possiblePages as |page|}} - <li class="{{if page.isCurrent 'is-current' 'clickable'}}" {{action 'changePage' page.pageNum}}> - {{#if page.isLoadPage}} - {{#if tableDefinition.loadingMore}} - <i class="fa fa-spinner fa-spin" aria-hidden="true"></i> - {{else}} - {{page.pageNum}} - {{/if}} - {{else}} - {{page.pageNum}} - {{/if}} - </li> - {{/each}} -</ul> - -<div class='row-select'> - <select title="Select rows to display" class="form-control" onchange={{action "rowSelected" value="target.value"}}> - {{#each rowCountOptions as |option|}} - <option value={{option.value}} selected={{option.selected}}> - {{option.value}} Rows - </option> - {{/each}} - </select> -</div> http://git-wip-us.apache.org/repos/asf/tez/blob/22e4fe19/tez-ui/src/main/webapp/app/templates/components/pagination-ui.hbs ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/templates/components/pagination-ui.hbs b/tez-ui/src/main/webapp/app/templates/components/pagination-ui.hbs new file mode 100644 index 0000000..6f8730c --- /dev/null +++ b/tez-ui/src/main/webapp/app/templates/components/pagination-ui.hbs @@ -0,0 +1,48 @@ +{{! + * 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. +}} + +<ul class="page-list"> + {{#if showFirst}} + <li title="Go to first page" class="clickable" {{action 'changePage' 1}}> + First + </li> + {{/if}} + {{#each _possiblePages as |page|}} + <li class="{{if page.isCurrent 'is-current' 'clickable'}}" {{action 'changePage' page.pageNum}}> + {{#if page.isLoadPage}} + {{#if tableDefinition.loadingMore}} + <i class="fa fa-spinner fa-spin" aria-hidden="true"></i> + {{else}} + {{page.pageNum}} + {{/if}} + {{else}} + {{page.pageNum}} + {{/if}} + </li> + {{/each}} +</ul> + +<div class='row-select'> + <select title="Select rows to display" class="form-control" onchange={{action "rowSelected" value="target.value"}}> + {{#each rowCountOptions as |option|}} + <option value={{option.value}} selected={{option.selected}}> + {{option.value}} Rows + </option> + {{/each}} + </select> +</div> http://git-wip-us.apache.org/repos/asf/tez/blob/22e4fe19/tez-ui/src/main/webapp/app/templates/components/queries-page-search.hbs ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/templates/components/queries-page-search.hbs b/tez-ui/src/main/webapp/app/templates/components/queries-page-search.hbs new file mode 100644 index 0000000..05762b2 --- /dev/null +++ b/tez-ui/src/main/webapp/app/templates/components/queries-page-search.hbs @@ -0,0 +1,48 @@ +{{! + * 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="form-group"> + <div class="search-element"> + <label for="pwd">Query ID:</label> + {{input value=queryID + type="text" + class="form-control input-sm" + placeholder="Search..." + enter="search" + }} + </div><div class="search-element"> + <label for="pwd">User:</label> + {{input value=user + type="text" + class="form-control input-sm" + placeholder="Search..." + enter="search" + }} + </div><div class="search-element"> + <label for="pwd">Request User:</label> + {{input value=requestUser + type="text" + class="form-control input-sm" + placeholder="Search..." + enter="search" + }} + </div> +</div> +<button type="button" class="btn btn-success" {{action 'search'}}> + <i class="fa fa-search" aria-hidden="true"></i> +</button> http://git-wip-us.apache.org/repos/asf/tez/blob/22e4fe19/tez-ui/src/main/webapp/app/templates/dags.hbs ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/templates/dags.hbs b/tez-ui/src/main/webapp/app/templates/dags.hbs deleted file mode 100644 index d2e35de..0000000 --- a/tez-ui/src/main/webapp/app/templates/dags.hbs +++ /dev/null @@ -1,42 +0,0 @@ -{{! - * 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. -}} - -{{tab-n-refresh tabs=tabs autoRefreshVisible=false loadTime=loadTime}} - -{{#if loaded}} - {{em-table - columns=visibleColumns - rows=model - rowCount=rowCount - - classNames="all-dags-table" - - headerComponentNames=headerComponentNames - - definition=definition - enableSort=false - - rowAction="rowCountChanged" - - search="search" - loadPage="loadPage" - reload="reload" - }} -{{else}} - {{partial "loading"}} -{{/if}} http://git-wip-us.apache.org/repos/asf/tez/blob/22e4fe19/tez-ui/src/main/webapp/app/templates/home.hbs ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/templates/home.hbs b/tez-ui/src/main/webapp/app/templates/home.hbs new file mode 100644 index 0000000..e1459c3 --- /dev/null +++ b/tez-ui/src/main/webapp/app/templates/home.hbs @@ -0,0 +1,20 @@ +{{! + * 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. +}} + +{{tab-n-refresh tabs=tabs autoRefreshVisible=false loadTime=loadTime}} +{{outlet}} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tez/blob/22e4fe19/tez-ui/src/main/webapp/app/templates/home/index.hbs ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/templates/home/index.hbs b/tez-ui/src/main/webapp/app/templates/home/index.hbs new file mode 100644 index 0000000..bf4319c --- /dev/null +++ b/tez-ui/src/main/webapp/app/templates/home/index.hbs @@ -0,0 +1,40 @@ +{{! + * 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. +}} + +{{#if loaded}} + {{em-table + columns=visibleColumns + rows=model + rowCount=rowCount + + classNames="all-dags-table" + + headerComponentNames=headerComponentNames + + definition=definition + enableSort=false + + rowAction="rowCountChanged" + + search="search" + loadPage="loadPage" + reload="reload" + }} +{{else}} + {{partial "loading"}} +{{/if}} http://git-wip-us.apache.org/repos/asf/tez/blob/22e4fe19/tez-ui/src/main/webapp/app/templates/home/queries.hbs ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/templates/home/queries.hbs b/tez-ui/src/main/webapp/app/templates/home/queries.hbs new file mode 100644 index 0000000..22e60e3 --- /dev/null +++ b/tez-ui/src/main/webapp/app/templates/home/queries.hbs @@ -0,0 +1,40 @@ +{{! + * 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. +}} + +{{#if loaded}} + {{em-table + columns=visibleColumns + rows=model + rowCount=rowCount + + classNames="all-queries-table" + + headerComponentNames=headerComponentNames + + definition=definition + enableSort=false + + rowAction="rowCountChanged" + + search="search" + loadPage="loadPage" + reload="reload" + }} +{{else}} + {{partial "loading"}} +{{/if}} http://git-wip-us.apache.org/repos/asf/tez/blob/22e4fe19/tez-ui/src/main/webapp/tests/integration/components/dags-pagination-ui-test.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/tests/integration/components/dags-pagination-ui-test.js b/tez-ui/src/main/webapp/tests/integration/components/dags-pagination-ui-test.js deleted file mode 100644 index 90c040f..0000000 --- a/tez-ui/src/main/webapp/tests/integration/components/dags-pagination-ui-test.js +++ /dev/null @@ -1,158 +0,0 @@ -/** - * 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 { moduleForComponent, test } from 'ember-qunit'; -import hbs from 'htmlbars-inline-precompile'; - -import wait from 'ember-test-helpers/wait'; - -import Ember from 'ember'; - -moduleForComponent('dags-pagination-ui', 'Integration | Component | dags pagination ui', { - integration: true -}); - -test('Basic creation test', function(assert) { - this.set("rowCountOptions", { - rowCountOptions: [1, 2] - }); - - this.render(hbs`{{dags-pagination-ui rowCountOptions=rowCountOptions}}`); - - assert.equal(this.$('select').length, 1); - - assert.equal(this.$('.page-list').length, 1); - assert.equal(this.$('li').length, 0); - - // Template block usage:" + EOL + - this.render(hbs` - {{#dags-pagination-ui rowCountOptions=rowCountOptions}} - template block text - {{/dags-pagination-ui}} - `); - - assert.equal(this.$('select').length, 1); -}); - -test('Page list test', function(assert) { - this.set("tableDefinition", { - pageNum: 5, - rowCount: 5, - - loadingMore: false, - moreAvailable: true, - - rowCountOptions: [] - }); - this.set("processor", { - totalPages: 10, - processedRows: { - length: 10 - } - }); - - this.render(hbs`{{dags-pagination-ui tableDefinition=tableDefinition dataProcessor=processor}}`); - - return wait().then(() => { - assert.equal(this.$('li').length, 4); - assert.equal(this.$('li').eq(0).text().trim(), "First"); - assert.equal(this.$('li').eq(1).text().trim(), "4"); - assert.equal(this.$('li').eq(2).text().trim(), "5"); - assert.equal(this.$('li').eq(3).text().trim(), "6"); - }); -}); - -test('Page list - moreAvailable false test', function(assert) { - this.set("tableDefinition", { - pageNum: 5, - rowCount: 5, - - loadingMore: false, - moreAvailable: false, - - rowCountOptions: [] - }); - this.set("processor", { - totalPages: 5, - processedRows: { - length: 10 - } - }); - - this.render(hbs`{{dags-pagination-ui tableDefinition=tableDefinition dataProcessor=processor}}`); - - return wait().then(() => { - assert.equal(this.$('li').length, 4); - assert.equal(this.$('li').eq(1).text().trim(), "3"); - assert.equal(this.$('li').eq(2).text().trim(), "4"); - assert.equal(this.$('li').eq(3).text().trim(), "5"); - }); -}); - -test('Page list - moreAvailable true test', function(assert) { - this.set("tableDefinition", { - pageNum: 5, - rowCount: 5, - - loadingMore: false, - moreAvailable: true, - - rowCountOptions: [] - }); - this.set("processor", { - totalPages: 5, - processedRows: { - length: 10 - } - }); - - this.render(hbs`{{dags-pagination-ui tableDefinition=tableDefinition dataProcessor=processor}}`); - - return wait().then(() => { - assert.equal(this.$('li').length, 4); - assert.equal(this.$('li').eq(1).text().trim(), "4"); - assert.equal(this.$('li').eq(2).text().trim(), "5"); - assert.equal(this.$('li').eq(3).text().trim(), "6"); - }); -}); - -test('No data test', function(assert) { - var customRowCount = 2, - definition = { - rowCount: customRowCount, - loadingMore: false, - moreAvailable: true, - - rowCountOptions: [] - }, - processor; - - Ember.run(function () { - processor = { - tableDefinition: definition, - rows: Ember.A() - }; - }); - - this.set('definition', definition); - this.set('processor', processor); - this.render(hbs`{{dags-pagination-ui tableDefinition=definition dataProcessor=processor}}`); - - var paginationItems = this.$('li'); - assert.equal(paginationItems.length, 0); -}); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tez/blob/22e4fe19/tez-ui/src/main/webapp/tests/integration/components/pagination-ui-test.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/tests/integration/components/pagination-ui-test.js b/tez-ui/src/main/webapp/tests/integration/components/pagination-ui-test.js new file mode 100644 index 0000000..296de2f --- /dev/null +++ b/tez-ui/src/main/webapp/tests/integration/components/pagination-ui-test.js @@ -0,0 +1,158 @@ +/** + * 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 { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; + +import wait from 'ember-test-helpers/wait'; + +import Ember from 'ember'; + +moduleForComponent('pagination-ui', 'Integration | Component | pagination ui', { + integration: true +}); + +test('Basic creation test', function(assert) { + this.set("rowCountOptions", { + rowCountOptions: [1, 2] + }); + + this.render(hbs`{{pagination-ui rowCountOptions=rowCountOptions}}`); + + assert.equal(this.$('select').length, 1); + + assert.equal(this.$('.page-list').length, 1); + assert.equal(this.$('li').length, 0); + + // Template block usage:" + EOL + + this.render(hbs` + {{#pagination-ui rowCountOptions=rowCountOptions}} + template block text + {{/pagination-ui}} + `); + + assert.equal(this.$('select').length, 1); +}); + +test('Page list test', function(assert) { + this.set("tableDefinition", { + pageNum: 5, + rowCount: 5, + + loadingMore: false, + moreAvailable: true, + + rowCountOptions: [] + }); + this.set("processor", { + totalPages: 10, + processedRows: { + length: 10 + } + }); + + this.render(hbs`{{pagination-ui tableDefinition=tableDefinition dataProcessor=processor}}`); + + return wait().then(() => { + assert.equal(this.$('li').length, 4); + assert.equal(this.$('li').eq(0).text().trim(), "First"); + assert.equal(this.$('li').eq(1).text().trim(), "4"); + assert.equal(this.$('li').eq(2).text().trim(), "5"); + assert.equal(this.$('li').eq(3).text().trim(), "6"); + }); +}); + +test('Page list - moreAvailable false test', function(assert) { + this.set("tableDefinition", { + pageNum: 5, + rowCount: 5, + + loadingMore: false, + moreAvailable: false, + + rowCountOptions: [] + }); + this.set("processor", { + totalPages: 5, + processedRows: { + length: 10 + } + }); + + this.render(hbs`{{pagination-ui tableDefinition=tableDefinition dataProcessor=processor}}`); + + return wait().then(() => { + assert.equal(this.$('li').length, 4); + assert.equal(this.$('li').eq(1).text().trim(), "3"); + assert.equal(this.$('li').eq(2).text().trim(), "4"); + assert.equal(this.$('li').eq(3).text().trim(), "5"); + }); +}); + +test('Page list - moreAvailable true test', function(assert) { + this.set("tableDefinition", { + pageNum: 5, + rowCount: 5, + + loadingMore: false, + moreAvailable: true, + + rowCountOptions: [] + }); + this.set("processor", { + totalPages: 5, + processedRows: { + length: 10 + } + }); + + this.render(hbs`{{pagination-ui tableDefinition=tableDefinition dataProcessor=processor}}`); + + return wait().then(() => { + assert.equal(this.$('li').length, 4); + assert.equal(this.$('li').eq(1).text().trim(), "4"); + assert.equal(this.$('li').eq(2).text().trim(), "5"); + assert.equal(this.$('li').eq(3).text().trim(), "6"); + }); +}); + +test('No data test', function(assert) { + var customRowCount = 2, + definition = { + rowCount: customRowCount, + loadingMore: false, + moreAvailable: true, + + rowCountOptions: [] + }, + processor; + + Ember.run(function () { + processor = { + tableDefinition: definition, + rows: Ember.A() + }; + }); + + this.set('definition', definition); + this.set('processor', processor); + this.render(hbs`{{pagination-ui tableDefinition=definition dataProcessor=processor}}`); + + var paginationItems = this.$('li'); + assert.equal(paginationItems.length, 0); +}); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tez/blob/22e4fe19/tez-ui/src/main/webapp/tests/integration/components/queries-page-search-test.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/tests/integration/components/queries-page-search-test.js b/tez-ui/src/main/webapp/tests/integration/components/queries-page-search-test.js new file mode 100644 index 0000000..700608c --- /dev/null +++ b/tez-ui/src/main/webapp/tests/integration/components/queries-page-search-test.js @@ -0,0 +1,61 @@ +/** + * 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 hbs from 'htmlbars-inline-precompile'; +import { moduleForComponent, test } from 'ember-qunit'; +import wait from 'ember-test-helpers/wait'; + +moduleForComponent('queries-page-search', 'Integration | Component | queries page search', { + integration: true +}); + +test('Basic creation test', function(assert) { + this.render(hbs`{{queries-page-search}}`); + assert.equal(this.$("input").length, 3); + + // Template block usage:" + EOL + + this.render(hbs` + {{#queries-page-search}} + template block text + {{/queries-page-search}} + `); + assert.equal(this.$("input").length, 3); +}); + +test('tableDefinition test', function(assert) { + var testQueryID = "query_1", + testUser = "user", + testRequestUser = "RequestUser"; + + this.set("tableDefinition", Ember.Object.create({ + queryID: testQueryID, + user: testUser, + requestUser: testRequestUser + })); + + this.render(hbs`{{queries-page-search tableDefinition=tableDefinition}}`); + + return wait().then(() => { + assert.equal(this.$('input').length, 3); + assert.equal(this.$('input').eq(0).val(), testQueryID); + assert.equal(this.$('input').eq(1).val(), testUser); + assert.equal(this.$('input').eq(2).val(), testRequestUser); + }); +}); http://git-wip-us.apache.org/repos/asf/tez/blob/22e4fe19/tez-ui/src/main/webapp/tests/unit/adapters/timeline-test.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/tests/unit/adapters/timeline-test.js b/tez-ui/src/main/webapp/tests/unit/adapters/timeline-test.js index c398a05..ebc53f1 100644 --- a/tez-ui/src/main/webapp/tests/unit/adapters/timeline-test.js +++ b/tez-ui/src/main/webapp/tests/unit/adapters/timeline-test.js @@ -35,6 +35,11 @@ test('Basic creation test', function(assert) { assert.equal(adapter.serverName, "timeline"); }); +test('filters test', function(assert) { + let filters = this.subject().filters; + assert.equal(Object.keys(filters).length, 13); +}); + test('stringifyFilters test', function(assert) { let adapter = this.subject(); http://git-wip-us.apache.org/repos/asf/tez/blob/22e4fe19/tez-ui/src/main/webapp/tests/unit/controllers/application-test.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/tests/unit/controllers/application-test.js b/tez-ui/src/main/webapp/tests/unit/controllers/application-test.js index 6fe69df..02742d7 100644 --- a/tez-ui/src/main/webapp/tests/unit/controllers/application-test.js +++ b/tez-ui/src/main/webapp/tests/unit/controllers/application-test.js @@ -32,14 +32,18 @@ test('Basic creation test', function(assert) { test('prefixedBreadcrumbs test', function(assert) { let controller = this.subject(), prefixedBreadcrumbs, - testText = "foo"; + testText = "foo", + testRouteName = "RouteName"; controller.breadcrumbs = [{ - text: testText + text: testText, + routeName: testRouteName }]; prefixedBreadcrumbs = controller.get("prefixedBreadcrumbs"); assert.equal(prefixedBreadcrumbs.length, 2); - assert.equal(prefixedBreadcrumbs[0].text, "All DAGs"); + assert.equal(prefixedBreadcrumbs[0].text, "Home"); + assert.equal(prefixedBreadcrumbs[0].routeName, "application"); assert.equal(prefixedBreadcrumbs[1].text, testText); + assert.equal(prefixedBreadcrumbs[1].routeName, testRouteName); }); http://git-wip-us.apache.org/repos/asf/tez/blob/22e4fe19/tez-ui/src/main/webapp/tests/unit/controllers/dags-test.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/tests/unit/controllers/dags-test.js b/tez-ui/src/main/webapp/tests/unit/controllers/dags-test.js deleted file mode 100644 index f244305..0000000 --- a/tez-ui/src/main/webapp/tests/unit/controllers/dags-test.js +++ /dev/null @@ -1,52 +0,0 @@ -/** - * 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 { moduleFor, test } from 'ember-qunit'; - -moduleFor('controller:dags', 'Unit | Controller | dags', { - // Specify the other units that are required for this test. - // needs: ['controller:foo'] -}); - -test('Basic creation test', function(assert) { - assert.expect(2 + 3 + 1 + 3 + 1 + 1); - - let controller = this.subject({ - initVisibleColumns: Ember.K, - beforeSort: {bind: Ember.K}, - send: function (name, query) { - assert.equal(name, "setBreadcrumbs"); - assert.ok(query); - } - }); - - assert.ok(controller); - assert.ok(controller.columns); - assert.ok(controller.getCounterColumns); - - assert.ok(controller.pageNum); - - assert.ok(controller.queryParams); - assert.ok(controller.headerComponentNames); - assert.ok(controller.definition); - - assert.ok(controller.actions.search); - assert.ok(controller.actions.pageChanged); -});
