Repository: tez Updated Branches: refs/heads/TEZ-2980 61965f194 -> 231c4d157
TEZ-3069. Tez UI 2: Make error bar fully functional (sree) Project: http://git-wip-us.apache.org/repos/asf/tez/repo Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/231c4d15 Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/231c4d15 Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/231c4d15 Branch: refs/heads/TEZ-2980 Commit: 231c4d157eeb77363716d9b32ec6cc048a712abb Parents: 61965f1 Author: Sreenath Somarajapuram <s...@apache.org> Authored: Sat Jan 30 19:55:25 2016 +0530 Committer: Sreenath Somarajapuram <s...@apache.org> Committed: Sat Jan 30 19:55:25 2016 +0530 ---------------------------------------------------------------------- TEZ-2980-CHANGES.txt | 1 + .../src/main/webapp/app/adapters/abstract.js | 15 +++ tez-ui2/src/main/webapp/app/adapters/am.js | 1 + tez-ui2/src/main/webapp/app/adapters/rm.js | 1 + .../src/main/webapp/app/adapters/timeline.js | 1 + .../src/main/webapp/app/components/error-bar.js | 109 +++++++++++++++++++ .../main/webapp/app/controllers/application.js | 2 + tez-ui2/src/main/webapp/app/entities/entity.js | 2 + tez-ui2/src/main/webapp/app/routes/abstract.js | 12 +- .../src/main/webapp/app/routes/am-pollster.js | 6 +- tez-ui2/src/main/webapp/app/routes/app.js | 3 +- .../src/main/webapp/app/routes/application.js | 2 +- tez-ui2/src/main/webapp/app/routes/attempt.js | 3 +- tez-ui2/src/main/webapp/app/routes/dag.js | 3 +- .../main/webapp/app/routes/dag/index/index.js | 5 + tez-ui2/src/main/webapp/app/routes/pollster.js | 18 +-- tez-ui2/src/main/webapp/app/routes/task.js | 3 +- tez-ui2/src/main/webapp/app/routes/vertex.js | 3 +- tez-ui2/src/main/webapp/app/styles/app.less | 8 +- .../src/main/webapp/app/styles/error-bar.less | 102 +++++++++++++++++ .../main/webapp/app/templates/application.hbs | 3 +- .../app/templates/components/error-bar.hbs | 31 ++++++ .../integration/components/error-bar-test.js | 43 ++++++++ .../webapp/tests/unit/entities/entity-test.js | 3 + .../webapp/tests/unit/routes/abstract-test.js | 6 +- 25 files changed, 362 insertions(+), 24 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tez/blob/231c4d15/TEZ-2980-CHANGES.txt ---------------------------------------------------------------------- diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt index fc99577..0457cb0 100644 --- a/TEZ-2980-CHANGES.txt +++ b/TEZ-2980-CHANGES.txt @@ -28,3 +28,4 @@ ALL CHANGES: TEZ-3070. Tez UI 2: Jenkins build is failing TEZ-3060. Tez UI 2: Activate auto-refresh TEZ-3061. Tez UI 2: Display in-progress vertex table in DAG details + TEZ-3069. Tez UI 2: Make error bar fully functional http://git-wip-us.apache.org/repos/asf/tez/blob/231c4d15/tez-ui2/src/main/webapp/app/adapters/abstract.js ---------------------------------------------------------------------- diff --git a/tez-ui2/src/main/webapp/app/adapters/abstract.js b/tez-ui2/src/main/webapp/app/adapters/abstract.js index 6cb701b..121d4ee 100644 --- a/tez-ui2/src/main/webapp/app/adapters/abstract.js +++ b/tez-ui2/src/main/webapp/app/adapters/abstract.js @@ -52,4 +52,19 @@ export default LoaderAdapter.extend({ Ember.assert(`Path not found for type:${type} to server:${serverName}`, path); return path; }, + + normalizeErrorResponse: function(status, headers, payload) { + var response; + + if(payload && payload.exception && !payload.errors) { + payload = `${payload.exception}\n${payload.message}\n${payload.javaClassName}`; + response = this._super(status, headers, payload); + } + else { + response = this._super(status, headers, payload); + Ember.set(response, '0.title', this.get("outOfReachMessage")); + } + + return response; + } }); http://git-wip-us.apache.org/repos/asf/tez/blob/231c4d15/tez-ui2/src/main/webapp/app/adapters/am.js ---------------------------------------------------------------------- diff --git a/tez-ui2/src/main/webapp/app/adapters/am.js b/tez-ui2/src/main/webapp/app/adapters/am.js index 85f3d27..c4cb75d 100644 --- a/tez-ui2/src/main/webapp/app/adapters/am.js +++ b/tez-ui2/src/main/webapp/app/adapters/am.js @@ -20,6 +20,7 @@ import AbstractAdapter from './abstract'; export default AbstractAdapter.extend({ serverName: "am", + outOfReachMessage: "Application Master (AM) is out of reach. Either it's down, or CORS is not enabled for YARN ResourceManager.", queryRecord: function(store, type, query) { return this.query(store, type, query); http://git-wip-us.apache.org/repos/asf/tez/blob/231c4d15/tez-ui2/src/main/webapp/app/adapters/rm.js ---------------------------------------------------------------------- diff --git a/tez-ui2/src/main/webapp/app/adapters/rm.js b/tez-ui2/src/main/webapp/app/adapters/rm.js index b87c77d..252affb 100644 --- a/tez-ui2/src/main/webapp/app/adapters/rm.js +++ b/tez-ui2/src/main/webapp/app/adapters/rm.js @@ -20,6 +20,7 @@ import AbstractAdapter from './abstract'; export default AbstractAdapter.extend({ serverName: "rm", + outOfReachMessage: "Resource Manager (RM) is out of reach. Either it's down, or CORS is not enabled.", // Any rm specific adapter changes must be added here }); http://git-wip-us.apache.org/repos/asf/tez/blob/231c4d15/tez-ui2/src/main/webapp/app/adapters/timeline.js ---------------------------------------------------------------------- diff --git a/tez-ui2/src/main/webapp/app/adapters/timeline.js b/tez-ui2/src/main/webapp/app/adapters/timeline.js index 93e83cb..82faed8 100644 --- a/tez-ui2/src/main/webapp/app/adapters/timeline.js +++ b/tez-ui2/src/main/webapp/app/adapters/timeline.js @@ -24,6 +24,7 @@ var MoreObject = more.Object; export default AbstractAdapter.extend({ serverName: "timeline", + outOfReachMessage: "Timeline server (ATS) is out of reach. Either it's down, or CORS is not enabled.", filters: { dagID: 'TEZ_DAG_ID', http://git-wip-us.apache.org/repos/asf/tez/blob/231c4d15/tez-ui2/src/main/webapp/app/components/error-bar.js ---------------------------------------------------------------------- diff --git a/tez-ui2/src/main/webapp/app/components/error-bar.js b/tez-ui2/src/main/webapp/app/components/error-bar.js new file mode 100644 index 0000000..1086010 --- /dev/null +++ b/tez-ui2/src/main/webapp/app/components/error-bar.js @@ -0,0 +1,109 @@ +/** + * 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'; + +const DISPLAY_TIME = 30 * 1000; + +export default Ember.Component.extend({ + + error: null, + + visible: false, + detailsAvailable: false, + + classNames: ['error-bar'], + classNameBindings: ['visible', 'detailsAvailable'], + + code: null, + message: null, + details: null, + stack: null, + + showDetails: false, + + displayTimerId: 0, + + _errorObserver: Ember.observer("error", function () { + var error = this.get("error"), + + code = Ember.get(error, "errors.0.status"), + title = Ember.get(error, "errors.0.title"), + message = error.message || "Error", + details = Ember.get(error, "errors.0.detail") || "", + stack = error.stack, + lineEndIndex = Math.min(message.indexOf('\n'), message.indexOf('<br')); + + if(code === "0") { + code = ""; + } + + if(title) { + message += ". " + title; + } + + if(lineEndIndex > 0) { + if(details) { + details = "\n" + details; + } + details = message.substr(lineEndIndex) + details; + message = message.substr(0, lineEndIndex); + } + + if(details) { + details += "\n"; + } + + if(error) { + this.setProperties({ + code: code, + message: message, + details: details, + stack: stack, + + detailsAvailable: !!(details || stack), + visible: true + }); + + this.clearTimer(); + this.set("displayTimerId", setTimeout(this.close.bind(this), DISPLAY_TIME)); + } + else { + this.close(); + } + }), + + clearTimer: function () { + clearTimeout(this.get("displayTimerId")); + }, + close: function () { + this.set("visible", false); + this.clearTimer(); + }, + + actions: { + toggleDetailsDisplay: function () { + this.toggleProperty("showDetails"); + this.clearTimer(); + }, + close: function () { + this.close(); + } + } + +}); http://git-wip-us.apache.org/repos/asf/tez/blob/231c4d15/tez-ui2/src/main/webapp/app/controllers/application.js ---------------------------------------------------------------------- diff --git a/tez-ui2/src/main/webapp/app/controllers/application.js b/tez-ui2/src/main/webapp/app/controllers/application.js index 24db40a..4911a16 100644 --- a/tez-ui2/src/main/webapp/app/controllers/application.js +++ b/tez-ui2/src/main/webapp/app/controllers/application.js @@ -25,6 +25,8 @@ const BREADCRUMB_PREFIX = [{ export default Ember.Controller.extend({ breadcrumbs: null, + appError: null, + prefixedBreadcrumbs: Ember.computed("breadcrumbs", function () { var prefix = BREADCRUMB_PREFIX, breadcrumbs = this.get('breadcrumbs'); http://git-wip-us.apache.org/repos/asf/tez/blob/231c4d15/tez-ui2/src/main/webapp/app/entities/entity.js ---------------------------------------------------------------------- diff --git a/tez-ui2/src/main/webapp/app/entities/entity.js b/tez-ui2/src/main/webapp/app/entities/entity.js index 8a10dee..6f98097 100644 --- a/tez-ui2/src/main/webapp/app/entities/entity.js +++ b/tez-ui2/src/main/webapp/app/entities/entity.js @@ -98,11 +98,13 @@ var Entity = Ember.Object.extend(NameMixin, { ); needLoader.then(function (model) { + parentModel.refreshLoadTime(); parentModel.set(needOptions.name, model); }); if(needOptions.silent) { needLoader = needLoader.catch(function () { + parentModel.refreshLoadTime(); parentModel.set(needOptions.name, null); }); } http://git-wip-us.apache.org/repos/asf/tez/blob/231c4d15/tez-ui2/src/main/webapp/app/routes/abstract.js ---------------------------------------------------------------------- diff --git a/tez-ui2/src/main/webapp/app/routes/abstract.js b/tez-ui2/src/main/webapp/app/routes/abstract.js index 923ac96..39b8314 100644 --- a/tez-ui2/src/main/webapp/app/routes/abstract.js +++ b/tez-ui2/src/main/webapp/app/routes/abstract.js @@ -98,7 +98,8 @@ export default Ember.Route.extend(NameMixin, { then(this.checkAndCall.bind(this, promiseId, "beforeLoad", query, options)). then(this.checkAndCall.bind(this, promiseId, "load", query, options)). then(this.checkAndCall.bind(this, promiseId, "afterLoad", query, options)). - then(this.checkAndCall.bind(this, promiseId, "setValue", query, options)); + then(this.checkAndCall.bind(this, promiseId, "setValue", query, options)). + catch(this.onLoadFailure.bind(this)); }, setLoading: function (/*query, options*/) { @@ -124,6 +125,15 @@ export default Ember.Route.extend(NameMixin, { return value; }, + onLoadFailure: function (error) { + if(error instanceof UnlinkedPromise) { + Ember.Logger.warn("Slow down, you are refreshing too fast!"); + } + else { + this.send("error", error); + throw(error); + } + }, getLoadTime: function (value) { if(value instanceof DS.RecordArray) { http://git-wip-us.apache.org/repos/asf/tez/blob/231c4d15/tez-ui2/src/main/webapp/app/routes/am-pollster.js ---------------------------------------------------------------------- diff --git a/tez-ui2/src/main/webapp/app/routes/am-pollster.js b/tez-ui2/src/main/webapp/app/routes/am-pollster.js index 5907a91..6752ffd 100644 --- a/tez-ui2/src/main/webapp/app/routes/am-pollster.js +++ b/tez-ui2/src/main/webapp/app/routes/am-pollster.js @@ -17,6 +17,8 @@ * limitations under the License. */ +import Ember from 'ember'; + import PollsterRoute from './pollster'; var MoreObject = more.Object; @@ -45,13 +47,11 @@ export default PollsterRoute.extend({ that.reload(); } else { - error.message = "Application Master (AM) is out of reach. Either it's down, or CORS is not enabled for YARN ResourceManager."; that.send("error", error); } }, function (error) { - error.message = "Resource Manager (RM) is out of reach. Either it's down, or CORS is not enabled."; that.send("error", error); - that.reload(); + Ember.run.later(that, "reload", this.get("polling.interval") * 3); }); }, http://git-wip-us.apache.org/repos/asf/tez/blob/231c4d15/tez-ui2/src/main/webapp/app/routes/app.js ---------------------------------------------------------------------- diff --git a/tez-ui2/src/main/webapp/app/routes/app.js b/tez-ui2/src/main/webapp/app/routes/app.js index a60025e..395a9be 100644 --- a/tez-ui2/src/main/webapp/app/routes/app.js +++ b/tez-ui2/src/main/webapp/app/routes/app.js @@ -26,7 +26,8 @@ export default AbstractRoute.extend({ }, model: function (params) { - return this.get("loader").queryRecord('app', "tez_" + this.queryFromParams(params).id); + return this.get("loader").queryRecord('app', "tez_" + this.queryFromParams(params).id). + catch(this.onLoadFailure.bind(this)); }, actions: { http://git-wip-us.apache.org/repos/asf/tez/blob/231c4d15/tez-ui2/src/main/webapp/app/routes/application.js ---------------------------------------------------------------------- diff --git a/tez-ui2/src/main/webapp/app/routes/application.js b/tez-ui2/src/main/webapp/app/routes/application.js index 121eda2..41ea3fb 100644 --- a/tez-ui2/src/main/webapp/app/routes/application.js +++ b/tez-ui2/src/main/webapp/app/routes/application.js @@ -38,7 +38,7 @@ export default Ember.Route.extend({ }, error: function (error) { - // Display error bar + this.set("controller.appError", error); Ember.Logger.error(error); }, http://git-wip-us.apache.org/repos/asf/tez/blob/231c4d15/tez-ui2/src/main/webapp/app/routes/attempt.js ---------------------------------------------------------------------- diff --git a/tez-ui2/src/main/webapp/app/routes/attempt.js b/tez-ui2/src/main/webapp/app/routes/attempt.js index 4a1ac20..3d0224f 100644 --- a/tez-ui2/src/main/webapp/app/routes/attempt.js +++ b/tez-ui2/src/main/webapp/app/routes/attempt.js @@ -26,7 +26,8 @@ export default AbstractRoute.extend({ }, model: function (params) { - return this.get("loader").queryRecord('attempt', this.queryFromParams(params).id); + return this.get("loader").queryRecord('attempt', this.queryFromParams(params).id). + catch(this.onLoadFailure.bind(this)); }, actions: { http://git-wip-us.apache.org/repos/asf/tez/blob/231c4d15/tez-ui2/src/main/webapp/app/routes/dag.js ---------------------------------------------------------------------- diff --git a/tez-ui2/src/main/webapp/app/routes/dag.js b/tez-ui2/src/main/webapp/app/routes/dag.js index 51e6ed9..13f1bc0 100644 --- a/tez-ui2/src/main/webapp/app/routes/dag.js +++ b/tez-ui2/src/main/webapp/app/routes/dag.js @@ -26,7 +26,8 @@ export default AbstractRoute.extend({ }, model: function (params) { - return this.get("loader").queryRecord('dag', this.queryFromParams(params).id); + return this.get("loader").queryRecord('dag', this.queryFromParams(params).id). + catch(this.onLoadFailure.bind(this)); }, actions: { http://git-wip-us.apache.org/repos/asf/tez/blob/231c4d15/tez-ui2/src/main/webapp/app/routes/dag/index/index.js ---------------------------------------------------------------------- diff --git a/tez-ui2/src/main/webapp/app/routes/dag/index/index.js b/tez-ui2/src/main/webapp/app/routes/dag/index/index.js index 15d485f..72d8686 100644 --- a/tez-ui2/src/main/webapp/app/routes/dag/index/index.js +++ b/tez-ui2/src/main/webapp/app/routes/dag/index/index.js @@ -44,8 +44,13 @@ export default MultiAmPollsterRoute.extend({ } }), + updateLoadTime: function (value) { + return value; + }, + actions: { reload: function () { + this._super(); return true; }, willTransition: function () { http://git-wip-us.apache.org/repos/asf/tez/blob/231c4d15/tez-ui2/src/main/webapp/app/routes/pollster.js ---------------------------------------------------------------------- diff --git a/tez-ui2/src/main/webapp/app/routes/pollster.js b/tez-ui2/src/main/webapp/app/routes/pollster.js index 5a7af16..7d62c39 100644 --- a/tez-ui2/src/main/webapp/app/routes/pollster.js +++ b/tez-ui2/src/main/webapp/app/routes/pollster.js @@ -25,19 +25,18 @@ export default AbstractRoute.extend({ polledRecords: null, // Must be implemented by inheriting classes - onRecordPoll: Ember.K, - onPollSuccess: Ember.K, - onPollFailure: Ember.K, + onRecordPoll: function (val) {return val;}, + onPollSuccess: function (val) {return val;}, + onPollFailure: function (err) {throw(err);}, pollData: function () { var polledRecords = this.get("polledRecords"); if(!this.get("isLoading") && polledRecords) { polledRecords = polledRecords.map(this.onRecordPoll.bind(this)); - return Ember.RSVP.all(polledRecords).then( - this.onPollSuccess.bind(this), - this.onPollFailure.bind(this) - ); + return Ember.RSVP.all(polledRecords). + then(this.updateLoadTime.bind(this)). + then(this.onPollSuccess.bind(this), this.onPollFailure.bind(this)); } return Ember.RSVP.reject(); }, @@ -46,6 +45,11 @@ export default AbstractRoute.extend({ return this.get("polledRecords") && this.get("loadedValue"); }), + updateLoadTime: function (value) { + this.send("setLoadTime", this.getLoadTime(value)); + return value; + }, + _canPollInit: Ember.on("init", function () { // This sets a flag that ensures that the _canPollObserver is called whenever // canPoll changes. By default observers on un-used computed properties http://git-wip-us.apache.org/repos/asf/tez/blob/231c4d15/tez-ui2/src/main/webapp/app/routes/task.js ---------------------------------------------------------------------- diff --git a/tez-ui2/src/main/webapp/app/routes/task.js b/tez-ui2/src/main/webapp/app/routes/task.js index 42d9715..54d29f1 100644 --- a/tez-ui2/src/main/webapp/app/routes/task.js +++ b/tez-ui2/src/main/webapp/app/routes/task.js @@ -26,7 +26,8 @@ export default AbstractRoute.extend({ }, model: function (params) { - return this.get("loader").queryRecord('task', this.queryFromParams(params).id); + return this.get("loader").queryRecord('task', this.queryFromParams(params).id). + catch(this.onLoadFailure.bind(this)); }, actions: { http://git-wip-us.apache.org/repos/asf/tez/blob/231c4d15/tez-ui2/src/main/webapp/app/routes/vertex.js ---------------------------------------------------------------------- diff --git a/tez-ui2/src/main/webapp/app/routes/vertex.js b/tez-ui2/src/main/webapp/app/routes/vertex.js index 5e8ed33..6e99fd1 100644 --- a/tez-ui2/src/main/webapp/app/routes/vertex.js +++ b/tez-ui2/src/main/webapp/app/routes/vertex.js @@ -26,7 +26,8 @@ export default AbstractRoute.extend({ }, model: function (params) { - return this.get("loader").queryRecord('vertex', this.queryFromParams(params).id); + return this.get("loader").queryRecord('vertex', this.queryFromParams(params).id). + catch(this.onLoadFailure.bind(this)); }, actions: { http://git-wip-us.apache.org/repos/asf/tez/blob/231c4d15/tez-ui2/src/main/webapp/app/styles/app.less ---------------------------------------------------------------------- diff --git a/tez-ui2/src/main/webapp/app/styles/app.less b/tez-ui2/src/main/webapp/app/styles/app.less index 758d1ab..cdeccd1 100644 --- a/tez-ui2/src/main/webapp/app/styles/app.less +++ b/tez-ui2/src/main/webapp/app/styles/app.less @@ -16,15 +16,19 @@ * limitations under the License. */ +// Prerequisites @import "colors"; @import "shared"; @import "tooltip"; +// Components @import "tab-n-refresh"; @import "dags-page-search"; +@import "table-controls"; +@import "column-selector"; +@import "error-bar"; +// Pages @import "page-layout"; @import "details-page"; -@import "table-controls"; -@import "column-selector"; http://git-wip-us.apache.org/repos/asf/tez/blob/231c4d15/tez-ui2/src/main/webapp/app/styles/error-bar.less ---------------------------------------------------------------------- diff --git a/tez-ui2/src/main/webapp/app/styles/error-bar.less b/tez-ui2/src/main/webapp/app/styles/error-bar.less new file mode 100644 index 0000000..dec2100 --- /dev/null +++ b/tez-ui2/src/main/webapp/app/styles/error-bar.less @@ -0,0 +1,102 @@ +/** + * 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. + */ + +.error-bar { + position: fixed; + z-index: 1000; + + padding: 9px 30px; + min-height: 50px; + width: 100%; + + bottom: -50px; + opacity: 0; + height: 50px; + + &.visible { + bottom: -10px; + opacity: 1; + height: auto; + } + + transition: all .2s cubic-bezier(0.175, 0.885, 0.320, 1.275); + transition-property: bottom, opacity, height; + -webkit-transition: all .2s cubic-bezier(0.175, 0.885, 0.320, 1.275); + -webkit-transition-property: bottom, opacity, height; + + border-top: 1px @border-lite solid; + background-color: #F5F5DC; + color: @text-red; + + .message, .details { + overflow: scroll; + max-height: 100px; + + text-align: left; + } + + .details { + display: none; + visibility: hidden; + + margin-bottom: 10px; + + border-top: 1px @border-lite solid; + + .force-scrollbar; + white-space: pre-line; + + &.visible { + display: block; + } + } + + .close-button, .show-details { + position: absolute; + top: 12px; + + color: @text-color; + opacity: .7; + + &:hover { + cursor: pointer; + opacity: 1; + } + } + + .close-button { + right: 30px; + } + + .show-details { + right: 45px; + visibility: hidden; + } + + &.details-available { + .message { + cursor: pointer; + } + .details { + visibility: visible; + } + .show-details { + visibility: visible; + } + } +} http://git-wip-us.apache.org/repos/asf/tez/blob/231c4d15/tez-ui2/src/main/webapp/app/templates/application.hbs ---------------------------------------------------------------------- diff --git a/tez-ui2/src/main/webapp/app/templates/application.hbs b/tez-ui2/src/main/webapp/app/templates/application.hbs index 16a0329..7bdc2b7 100644 --- a/tez-ui2/src/main/webapp/app/templates/application.hbs +++ b/tez-ui2/src/main/webapp/app/templates/application.hbs @@ -23,7 +23,6 @@ <div class="lr-margin content"> {{#link-to 'application' class="logo"}} <img src="assets/images/logo.png" width="70px"/> - <span>{{unbound App.env.version}}</span> {{/link-to}} <div class="breadcrumb-container"> @@ -64,3 +63,5 @@ </div> {{outlet "modal"}} + +{{error-bar error=appError}} http://git-wip-us.apache.org/repos/asf/tez/blob/231c4d15/tez-ui2/src/main/webapp/app/templates/components/error-bar.hbs ---------------------------------------------------------------------- diff --git a/tez-ui2/src/main/webapp/app/templates/components/error-bar.hbs b/tez-ui2/src/main/webapp/app/templates/components/error-bar.hbs new file mode 100644 index 0000000..a21bba0 --- /dev/null +++ b/tez-ui2/src/main/webapp/app/templates/components/error-bar.hbs @@ -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. +}} + +<div class="message" {{action "toggleDetailsDisplay"}}> + <i class="fa fa-exclamation-circle"></i> + {{#if code}} + <b>{{code}}</b> : + {{/if}} + {{message}} + <i class="show-details fa {{if showDetails 'fa-minus-circle' 'fa-plus-circle'}}"></i> +</div> +<div class="details {{if showDetails "visible"}}">{{{details}}}{{#if stack}}<b>Stack:</b> + {{stack}} + {{/if}} +</div> +<i class="close-button fa fa-arrow-circle-down" {{action "close"}}></i> http://git-wip-us.apache.org/repos/asf/tez/blob/231c4d15/tez-ui2/src/main/webapp/tests/integration/components/error-bar-test.js ---------------------------------------------------------------------- diff --git a/tez-ui2/src/main/webapp/tests/integration/components/error-bar-test.js b/tez-ui2/src/main/webapp/tests/integration/components/error-bar-test.js new file mode 100644 index 0000000..10c6c7d --- /dev/null +++ b/tez-ui2/src/main/webapp/tests/integration/components/error-bar-test.js @@ -0,0 +1,43 @@ +/** + * 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'; + +moduleForComponent('error-bar', 'Integration | Component | error bar', { + integration: true +}); + +test('Basic creation test', function(assert) { + + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.on('myAction', function(val) { ... });" + EOL + EOL + + + this.render(hbs`{{error-bar}}`); + + assert.equal(this.$().text().trim(), ''); + + // Template block usage:" + EOL + + this.render(hbs` + {{#error-bar}} + template block text + {{/error-bar}} + `); + + assert.equal(this.$().text().trim(), ''); +}); http://git-wip-us.apache.org/repos/asf/tez/blob/231c4d15/tez-ui2/src/main/webapp/tests/unit/entities/entity-test.js ---------------------------------------------------------------------- diff --git a/tez-ui2/src/main/webapp/tests/unit/entities/entity-test.js b/tez-ui2/src/main/webapp/tests/unit/entities/entity-test.js index fb0bd8a..9e2550d 100644 --- a/tez-ui2/src/main/webapp/tests/unit/entities/entity-test.js +++ b/tez-ui2/src/main/webapp/tests/unit/entities/entity-test.js @@ -78,6 +78,7 @@ test('loadAllNeeds basic test', function(assert) { let adapter = this.subject(), loader, testModel = Ember.Object.create({ + refreshLoadTime: Ember.K, needs: { app: "appID", foo: "fooID" @@ -115,6 +116,7 @@ test('loadAllNeeds silent=false test', function(assert) { let adapter = this.subject(), loader, testModel = Ember.Object.create({ + refreshLoadTime: Ember.K, needs: { app: { idKey: "appID", @@ -142,6 +144,7 @@ test('loadAllNeeds silent=true test', function(assert) { let adapter = this.subject(), loader, testModel = Ember.Object.create({ + refreshLoadTime: Ember.K, needs: { app: { idKey: "appID", http://git-wip-us.apache.org/repos/asf/tez/blob/231c4d15/tez-ui2/src/main/webapp/tests/unit/routes/abstract-test.js ---------------------------------------------------------------------- diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/abstract-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/abstract-test.js index 202e889..9ed3452 100644 --- a/tez-ui2/src/main/webapp/tests/unit/routes/abstract-test.js +++ b/tez-ui2/src/main/webapp/tests/unit/routes/abstract-test.js @@ -18,8 +18,6 @@ import Ember from 'ember'; -import UnlinkedPromise from '../../../errors/unlinked-promise'; - import { moduleFor, test } from 'ember-qunit'; moduleFor('route:abstract', 'Unit | Route | abstract', { @@ -174,8 +172,8 @@ test('loadData test - ID change check with exception throw', function(assert) { route.loadData().then(function () { assert.notOk("Shouldn't be called"); - }).catch(function (e) { - assert.ok(e instanceof UnlinkedPromise, "Exception thrown"); + }).catch(function () { + assert.ok(true, "Exception thrown"); }); });