Return-Path: X-Original-To: apmail-tez-commits-archive@minotaur.apache.org Delivered-To: apmail-tez-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 9D06319E7C for ; Tue, 26 Apr 2016 10:18:34 +0000 (UTC) Received: (qmail 57793 invoked by uid 500); 26 Apr 2016 10:18:34 -0000 Delivered-To: apmail-tez-commits-archive@tez.apache.org Received: (qmail 57707 invoked by uid 500); 26 Apr 2016 10:18:34 -0000 Mailing-List: contact commits-help@tez.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@tez.apache.org Delivered-To: mailing list commits@tez.apache.org Received: (qmail 56706 invoked by uid 99); 26 Apr 2016 10:18:33 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 26 Apr 2016 10:18:33 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 4946DEAB64; Tue, 26 Apr 2016 10:18:33 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: sree@apache.org To: commits@tez.apache.org Date: Tue, 26 Apr 2016 10:18:52 -0000 Message-Id: <4c1dcd9b79a4450a9c63067b0fb3ea93@git.apache.org> In-Reply-To: <92b5ef231f2f4a068a9eb7488e9ec3bd@git.apache.org> References: <92b5ef231f2f4a068a9eb7488e9ec3bd@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [21/31] tez git commit: TEZ-3227. Tez UI: Replace UI1 with UI2 (sree) http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/scripts/views/extra-table-buttons-view.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/scripts/views/extra-table-buttons-view.js b/tez-ui/src/main/webapp/app/scripts/views/extra-table-buttons-view.js deleted file mode 100644 index 422a755..0000000 --- a/tez-ui/src/main/webapp/app/scripts/views/extra-table-buttons-view.js +++ /dev/null @@ -1,23 +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. - */ - -App.ExtraTableButtonsView = Ember.View.extend({ - templateName: 'views/extra-table-buttons', - - classNames: ['extra-table-buttons'] -}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/scripts/views/multi-select-view.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/scripts/views/multi-select-view.js b/tez-ui/src/main/webapp/app/scripts/views/multi-select-view.js deleted file mode 100644 index ace7b94..0000000 --- a/tez-ui/src/main/webapp/app/scripts/views/multi-select-view.js +++ /dev/null @@ -1,72 +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. - */ - -App.MultiSelectView = Ember.View.extend({ - templateName: 'views/multi-select', - classNames: ['multi-select'], - - selectAll: false, - searchRegex: '', - - options: null, //Must be set by sub-classes or instances - - _validRegEx: function () { - var regExText = this.get('searchRegex'); - regExText = regExText.substr(regExText.indexOf(':') + 1); - try { - new RegExp(regExText, 'im'); - } - catch(e) { - return false; - } - return true; - }.property('searchRegex'), - - visibleOptions: function () { - var options = this.get('options'), - regExText = this.get('searchRegex'), - regEx; - - if (Em.isEmpty(regExText) || !this.get('_validRegEx')) { - return options; - } - - regEx = new RegExp(regExText, 'i'); - return options.filter(function (option) { - return regEx.test(option.get('displayText')); - }); - }.property('options', 'searchRegex'), - - _selectObserver: function () { - var selectedCount = 0; - this.get('visibleOptions').forEach(function (option) { - if(option.get('selected')) { - selectedCount++; - } - }); - this.set('selectAll', selectedCount > 0 && selectedCount == this.get('visibleOptions.length')); - }.observes('visibleOptions.@each.selected'), - - actions: { - selectAll: function (checked) { - this.get('visibleOptions').forEach(function (option) { - option.set('selected', checked); - }); - } - } -}); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/scripts/views/swimlane_view.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/scripts/views/swimlane_view.js b/tez-ui/src/main/webapp/app/scripts/views/swimlane_view.js deleted file mode 100644 index 51e8509..0000000 --- a/tez-ui/src/main/webapp/app/scripts/views/swimlane_view.js +++ /dev/null @@ -1,165 +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. - */ - -App.SwimlanesView = Ember.View.extend({ - - didInsertElement: function() { - var _tip; // Instance of tip.js - var task_attempts = this.get("content"); - var controller = this.get("controller"); - var timeBegin = d3.min(task_attempts, function (d) { return d.get('startTime') }); - var timeEnd = d3.max(task_attempts, function (d) { return d.get('endTime') }); - var containers = d3.set(task_attempts.map(function (d) {return d.get('containerId')})).values().sort(); - var laneLength = containers.length; - - var margin = {top: 20, right: 15, bottom: 15, left: 280}; - var width = 960 - margin.left - margin.right; - var height = 500 - margin.top - margin.bottom; - var laneHeight = 18; - var miniHeight = laneLength * laneHeight; - - //scales - var x = d3.scale.linear() - .range([0, width]) - .domain([timeBegin, timeEnd]); - - var y = d3.scale.ordinal() - .domain(containers) - .rangeRoundBands([0, miniHeight], .20); - - var xAxis = d3.svg.axis() - .scale(x) - .orient("bottom") - .tickSize(0) - .tickFormat(function(d) { return (d - timeBegin)/1000; }); - - var yAxis = d3.svg.axis() - .scale(y) - .tickSize(0) - .orient("left"); - - var svg = d3.select('.svg-container') - .append("svg") - .attr("width", width + margin.left + margin.right) - .attr("height", height + margin.top + margin.bottom) - .attr("class", "svg"); - _tip = App.DagViewComponent.tip; - _tip.init($('.tool-tip'), $(svg.node())); - - var mini = svg.append("g") - .attr("transform", "translate(" + margin.left + "," + margin.top + ")") - .attr("class", "mini"); - - mini.append("g") - .attr("class", "y axis") - .call(yAxis) - .selectAll("text") - .style("text-anchor", "end"); - - mini.append("g") - .attr("class", "x axis") - .attr("transform", "translate(0," + miniHeight + ")") - .call(xAxis) - .selectAll("text") - .style("text-anchor", "end") - .attr("transform", "rotate(-90)" ); - - // draw container rectangles - mini.append("g").selectAll("container") - .data(containers) - .enter().append("a").attr("xlink:href","file:///Users/jeagles/myember/") - .append("rect") - .attr("class", "container") - .attr("x", 0) - .attr("y", function(d) {return y(d);}) - .attr("width", width) - .attr("rx", 6) - .attr("height", y.rangeBand()); - - // draw task attempt rectangles - mini.append("g").selectAll("task_attempt") - .data(task_attempts) - .enter().append("rect") - .attr("class", function(d) {return "task_attempt";}) - .attr("x", function(d) {return x(d.get('startTime'));}) - .attr("y", function(d) {return y(d.get('containerId'));}) - .attr("width", function(d) {return x(d.get('endTime')) - x(d.get('startTime'));}) - .attr("rx", 6) - .attr("height", y.rangeBand()) - .on({ - mouseover: _onMouseOver, - mouseout: _tip.hide, - click: function (d) { controller.send('taskAttemptClicked', d.get('id'))} - }); - - /** - * Mouse over handler for all displayed SVG DOM elements. - * Later the implementation will be refactored and moved into the respective DataNode. - * d {DataNode} Contains data to be displayed - */ - function _onMouseOver(d) { - var event = d3.event, - node = event.target, - tooltipData = {}; // Will be populated with {title/text/kvList}. - - node = node.correspondingUseElement || node; - - switch(_getType(node)) { - case "task_attempt": - node = d3.event.target; - tooltipData = { - position: { - x: event.clientX, - y: event.clientY - }, - title: '%@'.fmt( - "Task Attempt" - ) - }; - tooltipData.kvList = { - "Id": d.get('id'), - "Task Id": d.get("taskID"), - "Vertex Id": d.get("vertexID"), - "DAG Id": d.get("dagID"), - "Start Time": App.Helpers.date.dateFormat(d.get("startTime")), - "End Time": App.Helpers.date.dateFormat(d.get("endTime")), - "Duration": App.Helpers.date.timingFormat(App.Helpers.date.duration(d.get("startTime"), d.get("endTime"))), - }; - break; - } - - _tip.show(node, tooltipData, event); - } - - function _getType(node) { - return $(node).attr('class'); - } - - /* - // TODO: task attempt labels - draw labels if they fit - mini.append("g").selectAll("task_attempt_label") - .data(task_attempts) - .enter().append("text") - .text(function(d) {return d.get('id');}) - .attr("x", function(d) {return x(d.get('startTime'));}) - .attr("y", function(d) {return y(d.get('containerId'));}) - .attr("dy", ".5ex"); - */ - - }, -}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/serializers/ahs-app.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/serializers/ahs-app.js b/tez-ui/src/main/webapp/app/serializers/ahs-app.js new file mode 100644 index 0000000..0c35d54 --- /dev/null +++ b/tez-ui/src/main/webapp/app/serializers/ahs-app.js @@ -0,0 +1,49 @@ +/** + * 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 LoaderSerializer from './loader'; + +export default LoaderSerializer.extend({ + primaryKey: 'appId', + + extractArrayPayload: function (payload) { + return payload.app; + }, + + maps: { + entityID: 'appId', + attemptID: function(source) { + // while an attempt is in progress the attempt id contains a '-' + return (Ember.get(source, 'currentAppAttemptId') || '').replace('-',''); + }, + + name: 'name', + queue: 'queue', + user: 'user', + type: 'type', + + status: 'appState', + finalStatus: 'finalAppStatus', + + startTime: 'startedTime', + endTime: 'finishedTime', + + diagnostics: 'otherinfo.diagnostics', + } +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/serializers/am.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/serializers/am.js b/tez-ui/src/main/webapp/app/serializers/am.js new file mode 100644 index 0000000..f9c5848 --- /dev/null +++ b/tez-ui/src/main/webapp/app/serializers/am.js @@ -0,0 +1,41 @@ +/** + * 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 LoaderSerializer from './loader'; + +export default LoaderSerializer.extend({ + primaryKey: 'id', + + payloadNamespace: null, // Must be set by inheriting classes + + extractSinglePayload: function (rawPayload) { + return rawPayload[this.get("payloadNamespace")][0]; + }, + extractArrayPayload: function(rawPayload) { + return rawPayload[this.get("payloadNamespace")]; + }, + + maps: { + entityID: 'id', + + status: 'status', + progress: 'progress', + + counterGroupsHash: 'counters' + } +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/serializers/app-rm.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/serializers/app-rm.js b/tez-ui/src/main/webapp/app/serializers/app-rm.js new file mode 100644 index 0000000..37166c3 --- /dev/null +++ b/tez-ui/src/main/webapp/app/serializers/app-rm.js @@ -0,0 +1,33 @@ +/** + * 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 RMSerializer from './rm'; + +export default RMSerializer.extend({ + + extractSinglePayload: function (rawPayload) { + return Ember.get(rawPayload, "app"); + }, + + extractArrayPayload: function(rawPayload) { + return Ember.get(rawPayload, "apps.app"); + }, + +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/serializers/app.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/serializers/app.js b/tez-ui/src/main/webapp/app/serializers/app.js new file mode 100644 index 0000000..0d05c6c --- /dev/null +++ b/tez-ui/src/main/webapp/app/serializers/app.js @@ -0,0 +1,32 @@ +/** + * 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 TimelineSerializer from './timeline'; + +export default TimelineSerializer.extend({ + maps: { + domain: 'domain', + user: 'otherinfo.user', + + buildTime: 'otherinfo.tezVersion.buildTime', + tezRevision: 'otherinfo.tezVersion.revision', + tezVersion: 'otherinfo.tezVersion.version', + + configs: 'otherinfo.config', + } +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/serializers/attempt-am.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/serializers/attempt-am.js b/tez-ui/src/main/webapp/app/serializers/attempt-am.js new file mode 100644 index 0000000..277a0d5 --- /dev/null +++ b/tez-ui/src/main/webapp/app/serializers/attempt-am.js @@ -0,0 +1,23 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import AMSerializer from './am'; + +export default AMSerializer.extend({ + payloadNamespace: "attempts" +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/serializers/attempt.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/serializers/attempt.js b/tez-ui/src/main/webapp/app/serializers/attempt.js new file mode 100644 index 0000000..09b82e6 --- /dev/null +++ b/tez-ui/src/main/webapp/app/serializers/attempt.js @@ -0,0 +1,44 @@ +/** + * 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 TimelineSerializer from './timeline'; + +function createLogURL(source) { + var logURL = Ember.get(source, 'otherinfo.inProgressLogsURL'), + attemptID = Ember.get(source, 'entity'), + yarnProtocol = this.get('env.app.yarnProtocol'); + + if(logURL) { + return `${yarnProtocol}://${logURL}/syslog_${attemptID}`; + } +} + +export default TimelineSerializer.extend({ + maps: { + taskID: 'primaryfilters.TEZ_TASK_ID.0', + vertexID: 'primaryfilters.TEZ_VERTEX_ID.0', + dagID: 'primaryfilters.TEZ_DAG_ID.0', + + containerID: 'otherinfo.containerId', + nodeID: 'otherinfo.nodeId', + + logURL: createLogURL + } +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/serializers/dag-am.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/serializers/dag-am.js b/tez-ui/src/main/webapp/app/serializers/dag-am.js new file mode 100644 index 0000000..510d6f1 --- /dev/null +++ b/tez-ui/src/main/webapp/app/serializers/dag-am.js @@ -0,0 +1,28 @@ +/** + * 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 AMSerializer from './am'; + +export default AMSerializer.extend({ + extractSinglePayload: function (rawPayload) { + return rawPayload.dag; + }, + extractArrayPayload: function(rawPayload) { + return rawPayload.dag; + }, +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/serializers/dag.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/serializers/dag.js b/tez-ui/src/main/webapp/app/serializers/dag.js new file mode 100644 index 0000000..b5cc42c --- /dev/null +++ b/tez-ui/src/main/webapp/app/serializers/dag.js @@ -0,0 +1,151 @@ +/*global more*/ +/** + * 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 TimelineSerializer from './timeline'; + +var MoreObject = more.Object; + +function getStatus(source) { + var status = Ember.get(source, 'otherinfo.status') || Ember.get(source, 'primaryfilters.status.0'), + event = source.events; + + if(!status && event) { + if(event.findBy('eventtype', 'DAG_STARTED')) { + status = 'RUNNING'; + } + } + + return status; +} + +function getStartTime(source) { + var time = Ember.get(source, 'otherinfo.startTime'), + event = source.events; + + if(!time && event) { + event = event.findBy('eventtype', 'DAG_STARTED'); + if(event) { + time = event.timestamp; + } + } + + return time; +} + +function getEndTime(source) { + var time = Ember.get(source, 'otherinfo.endTime'), + event = source.events; + + if(!time && event) { + event = event.findBy('eventtype', 'DAG_FINISHED'); + if(event) { + time = event.timestamp; + } + } + + return time; +} + +function getContainerLogs(source) { + var containerLogs = [], + otherinfo = Ember.get(source, 'otherinfo'); + + if(!otherinfo) { + return undefined; + } + + for (var key in otherinfo) { + if (key.indexOf('inProgressLogsURL_') === 0) { + let logs = Ember.get(source, 'otherinfo.' + key); + if (logs.indexOf('http') !== 0) { + logs = 'http://' + logs; + } + let attemptID = key.substring(18); + containerLogs.push({ + text : attemptID, + href: logs + }); + } + } + + return containerLogs; +} + +function getIdNameMap(source) { + var nameIdMap = Ember.get(source, 'otherinfo.vertexNameIdMapping'), + idNameMap = {}; + + if(nameIdMap) { + MoreObject.forEach(nameIdMap, function (name, id) { + idNameMap[id] = name; + }); + } + + return idNameMap; +} + +export default TimelineSerializer.extend({ + maps: { + name: 'primaryfilters.dagName.0', + + submitter: 'primaryfilters.user.0', + + atsStatus: getStatus, + // progress + + startTime: getStartTime, + endTime: getEndTime, + // duration + + vertices: 'otherinfo.dagPlan.vertices', + edges: 'otherinfo.dagPlan.edges', + vertexGroups: 'otherinfo.dagPlan.vertexGroups', + + // appID + domain: 'domain', + // queue + containerLogs: getContainerLogs, + + vertexIdNameMap: getIdNameMap, + + callerID: 'primaryfilters.callerId.0', + callerType: 'callerType', + callerInfo: 'callerInfo', + }, + + extractAttributes: function (modelClass, resourceHash) { + var data = resourceHash.data, + dagInfo = Ember.get(resourceHash, "data.otherinfo.dagPlan.dagInfo"); + + if(dagInfo) { + let infoObj = {}; + try{ + infoObj = JSON.parse(dagInfo); + }catch(e){} + + data.callerType = Ember.get(infoObj, "context"); + data.callerInfo = Ember.get(infoObj, "description") || Ember.get(dagInfo, "blob") || dagInfo; + } + + return this._super(modelClass, resourceHash); + }, + +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/serializers/loader.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/serializers/loader.js b/tez-ui/src/main/webapp/app/serializers/loader.js new file mode 100644 index 0000000..b227d83 --- /dev/null +++ b/tez-ui/src/main/webapp/app/serializers/loader.js @@ -0,0 +1,93 @@ +/*global more*/ +/** + * 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 DS from 'ember-data'; + +var MoreObject = more.Object; + +// TODO - Move to more js +function mapObject(hash, map, thisArg) { + var mappedObject = Ember.Object.create(); + MoreObject.forEach(map, function (key, value) { + if(MoreObject.isString(value)) { + mappedObject.set(key, Ember.get(hash, value)); + } + else if (MoreObject.isFunction(value)) { + mappedObject.set(key, value.call(thisArg, hash)); + } + else { + Ember.assert("Unknown mapping value"); + } + }); + return mappedObject; +} + +export default DS.JSONSerializer.extend({ + _isLoader: true, + + mergedProperties: ["maps"], + maps: null, + + extractId: function (modelClass, resourceHash) { + var id = this._super(modelClass, resourceHash.data), + nameSpace = resourceHash.nameSpace; + + if(nameSpace) { + return nameSpace + ":" + id; + } + return id; + }, + extractAttributes: function (modelClass, resourceHash) { + var maps = this.get('maps'), + data = resourceHash.data; + return this._super(modelClass, maps ? mapObject(data, maps, this) : data); + }, + extractRelationships: function (modelClass, resourceHash) { + return this._super(modelClass, resourceHash.data); + }, + + extractSinglePayload: function (payload) { + return payload; + }, + extractArrayPayload: function (payload) { + return payload; + }, + + normalizeSingleResponse: function (store, primaryModelClass, payload, id, requestType) { + payload.data = this.extractSinglePayload(payload.data); + return this._super(store, primaryModelClass, payload, id, requestType); + }, + + normalizeArrayResponse: function (store, primaryModelClass, payload, id, requestType) { + var nameSpace = payload.nameSpace; + + // convert into a _normalizeResponse friendly format + payload = this.extractArrayPayload(payload.data); + Ember.assert("Loader expects an array in return for a query", Array.isArray(payload)); + payload = payload.map(function (item) { + return { + nameSpace: nameSpace, + data: item + }; + }); + + return this._super(store, primaryModelClass, payload, id, requestType); + } +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/serializers/rm.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/serializers/rm.js b/tez-ui/src/main/webapp/app/serializers/rm.js new file mode 100644 index 0000000..fbb91c3 --- /dev/null +++ b/tez-ui/src/main/webapp/app/serializers/rm.js @@ -0,0 +1,28 @@ +/** + * 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 LoaderSerializer from './loader'; + +export default LoaderSerializer.extend({ + primaryKey: 'id', + + maps: { + entityID: 'id', + status: 'state', + } +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/serializers/task-am.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/serializers/task-am.js b/tez-ui/src/main/webapp/app/serializers/task-am.js new file mode 100644 index 0000000..129f5e0 --- /dev/null +++ b/tez-ui/src/main/webapp/app/serializers/task-am.js @@ -0,0 +1,23 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import AMSerializer from './am'; + +export default AMSerializer.extend({ + payloadNamespace: "tasks" +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/serializers/task.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/serializers/task.js b/tez-ui/src/main/webapp/app/serializers/task.js new file mode 100644 index 0000000..3c57be2 --- /dev/null +++ b/tez-ui/src/main/webapp/app/serializers/task.js @@ -0,0 +1,28 @@ +/** + * 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 TimelineSerializer from './timeline'; + +export default TimelineSerializer.extend({ + maps: { + vertexID: 'primaryfilters.TEZ_VERTEX_ID.0', + dagID: 'primaryfilters.TEZ_DAG_ID.0', + + failedTaskAttempts: 'otherinfo.numFailedTaskAttempts' + } +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/serializers/timeline.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/serializers/timeline.js b/tez-ui/src/main/webapp/app/serializers/timeline.js new file mode 100644 index 0000000..ba5614e --- /dev/null +++ b/tez-ui/src/main/webapp/app/serializers/timeline.js @@ -0,0 +1,54 @@ +/** + * 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 LoaderSerializer from './loader'; + +function getDiagnostics(source) { + var diagnostics = Ember.get(source, 'otherinfo.diagnostics') || ""; + + diagnostics = diagnostics.replace(/\t/g, "  "); + diagnostics = diagnostics.replace(/\[/g, "
» "); + diagnostics = diagnostics.replace(/\]/g, "
"); + + return diagnostics; +} + +export default LoaderSerializer.extend({ + primaryKey: 'entity', + + extractArrayPayload: function (payload) { + return payload.entities; + }, + + maps: { + entityID: 'entity', + + atsStatus: 'otherinfo.status', + + startTime: 'otherinfo.startTime', + endTime: 'otherinfo.endTime', + + diagnostics: getDiagnostics, + + events: 'events', + + _counterGroups: 'otherinfo.counters.counterGroups' + } +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/serializers/vertex-am.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/serializers/vertex-am.js b/tez-ui/src/main/webapp/app/serializers/vertex-am.js new file mode 100644 index 0000000..3cf7a7e --- /dev/null +++ b/tez-ui/src/main/webapp/app/serializers/vertex-am.js @@ -0,0 +1,36 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import AMSerializer from './am'; + +export default AMSerializer.extend({ + payloadNamespace: "vertices", + + maps: { + succeededTasks: "succeededTasks", + runningTasks: "runningTasks", + failedTaskAttempts: "failedTaskAttempts", + killedTaskAttempts: "killedTaskAttempts", + + initTime: "initTime", + startTime: "startTime", + endTime: "finishTime", + firstTaskStartTime: "firstTaskStartTime", + lastTaskFinishTime: "lastTaskFinishTime", + } +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/serializers/vertex.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/serializers/vertex.js b/tez-ui/src/main/webapp/app/serializers/vertex.js new file mode 100644 index 0000000..a3cb22f --- /dev/null +++ b/tez-ui/src/main/webapp/app/serializers/vertex.js @@ -0,0 +1,59 @@ +/** + * 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 TimelineSerializer from './timeline'; + +function getProcessorClass(source) { + var name = Ember.get(source, 'otherinfo.processorClassName') || ""; + return name.substr(name.lastIndexOf('.') + 1); +} + +export default TimelineSerializer.extend({ + maps: { + name: 'otherinfo.vertexName', + + _initTime: 'otherinfo.initTime', + _startTime: 'otherinfo.startTime', + _endTime: 'otherinfo.endTime', + _firstTaskStartTime: 'otherinfo.stats.firstTaskStartTime', + _lastTaskFinishTime: 'otherinfo.stats.lastTaskFinishTime', + + totalTasks: 'otherinfo.numTasks', + _failedTasks: 'otherinfo.numFailedTasks', + _succeededTasks: 'otherinfo.numSucceededTasks', + _killedTasks: 'otherinfo.numKilledTasks', + + _failedTaskAttempts: 'otherinfo.numFailedTaskAttempts', + _killedTaskAttempts: 'otherinfo.numKilledTaskAttempts', + + minDuration: 'otherinfo.stats.minTaskDuration', + maxDuration: 'otherinfo.stats.maxTaskDuration', + avgDuration: 'otherinfo.stats.avgTaskDuration', + + firstTasksToStart: 'otherinfo.stats.firstTasksToStart', + lastTasksToFinish: 'otherinfo.stats.lastTasksToFinish', + shortestDurationTasks: 'otherinfo.stats.shortestDurationTasks', + longestDurationTasks: 'otherinfo.stats.longestDurationTasks', + + processorClassName: getProcessorClass, + + dagID: 'primaryfilters.TEZ_DAG_ID.0', + } +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/services/env.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/services/env.js b/tez-ui/src/main/webapp/app/services/env.js new file mode 100644 index 0000000..23fff96 --- /dev/null +++ b/tez-ui/src/main/webapp/app/services/env.js @@ -0,0 +1,63 @@ +/*global more*/ +/** + * 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 environment from '../config/environment'; + +var MoreObject = more.Object; + +export default Ember.Service.extend({ + ENV: null, + + init: function () { + this.collateConfigs(); + }, + + collateConfigs: function () { + var collatedENV = { + APP: {} + }, + ENV = window.ENV; + + MoreObject.merge(collatedENV, environment); + + if(ENV) { + MoreObject.merge(collatedENV.APP, ENV); + } + + this.setComputedENVs(collatedENV); + + this.set("ENV", collatedENV); + }, + + setComputedENVs: function (env) { + var navigator = window.navigator; + env.isIE = navigator.userAgent.indexOf('MSIE') !== -1 || navigator.appVersion.indexOf('Trident/') > 0; + + if(!env.APP.yarnProtocol) { + let rmHost = Ember.get(env, "hosts.rm") || ""; + env.APP.yarnProtocol = rmHost.substr(0, rmHost.indexOf("://")) || window.location.protocol.slice(0, -1); + } + }, + + app: Ember.computed("ENV.APP", function () { + return this.get("ENV.APP"); + }) +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/services/hosts.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/services/hosts.js b/tez-ui/src/main/webapp/app/services/hosts.js new file mode 100644 index 0000000..c9e7d25 --- /dev/null +++ b/tez-ui/src/main/webapp/app/services/hosts.js @@ -0,0 +1,71 @@ +/** + * 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.Service.extend({ + + env: Ember.inject.service("env"), + + correctProtocol: function (url, localProto) { + var urlProto; + + localProto = localProto || window.location.protocol; + + if(url.match("://")) { + urlProto = url.substr(0, url.indexOf("//")); + } + + if(localProto === "file:") { + urlProto = urlProto || "http:"; + } + else { + urlProto = localProto; + } + + if(url.match("://")) { + url = url.substr(url.indexOf("://") + 3); + } + + return urlProto + "//" + url; + }, + + normalizeURL: function (url) { + url = this.correctProtocol(url); + + // Remove trailing slash + if(url && url.charAt(url.length - 1) === '/') { + url = url.slice(0, -1); + } + return url; + }, + + timeline: Ember.computed(function () { + return this.normalizeURL(this.get("env.app.hosts.timeline")); + }), + + rm: Ember.computed(function () { + return this.normalizeURL(this.get("env.app.hosts.rm")); + }), + + am: Ember.computed(function () { + var url = this.get("env.app.hosts.rmProxy") || this.get("env.app.hosts.rm"); + return this.normalizeURL(url); + }), + +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/services/loader.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/services/loader.js b/tez-ui/src/main/webapp/app/services/loader.js new file mode 100644 index 0000000..c72289a --- /dev/null +++ b/tez-ui/src/main/webapp/app/services/loader.js @@ -0,0 +1,151 @@ +/** + * 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.Service.extend({ + + nameSpace: '', + store: Ember.inject.service('store'), + cache: null, + + _setOptions: function (options) { + var nameSpace = options.nameSpace; + if(nameSpace) { + // We need to validate only if nameSpace is passed. Else it would be stored in the global space + Ember.assert(`Invalid nameSpace. Please pass a string instead of ${Ember.inspect(nameSpace)}`, typeof nameSpace === 'string'); + this.set("nameSpace", nameSpace); + } + }, + + init: function (options) { + this._super(); + this._setOptions(options || {}); + this.set("cache", Ember.Object.create()); + }, + + checkRequisite: function (type) { + var store = this.get("store"), + adapter = store.adapterFor(type), + serializer = store.serializerFor(type); + + Ember.assert( + `No loader adapter found for type ${type}. Either extend loader and create a custom adapter or extend ApplicationAdapter from loader.`, + adapter && adapter._isLoader + ); + Ember.assert( + `No loader serializer found for type ${type}. Either extend loader and create a custom serializer or extend ApplicationSerializer from loader.`, + serializer && serializer._isLoader + ); + }, + + lookup: function (type, name, options) { + name = Ember.String.dasherize(name); + return this.get("container").lookup(type + ":" + name, options); + }, + + entityFor: function (entityName) { + var entity = this.lookup("entitie", entityName); + if(!entity) { + entity = this.lookup("entitie", "entity", { singleton: false }); + entity.set("name", entityName); + } + return entity; + }, + + getCacheKey: function (type, query, id) { + var parts = [type]; + + if(id) { + parts.push(id); + } + if(query) { + parts.push(JSON.stringify(query)); + } + + return parts.join(":").replace(/\./g, ":"); + }, + + loadNeed: function (record, needName, options, queryParams, urlParams) { + var entity = this.entityFor(record.get("constructor.modelName")); + return entity.loadNeed(this, record, needName, options, queryParams, urlParams); + }, + + normalizeOptions: function (options) { + options = options || {}; + + if(!options.cache){ + options = Ember.$.extend({}, options); + options.cache = options.reload ? Ember.Object.create() : this.get("cache"); + } + + return options; + }, + + queryRecord: function(type, id, options, query, urlParams) { + var entity = this.entityFor(type), + cacheKey = this.getCacheKey(type, query, id), + record; + + this.checkRequisite(type); + + options = this.normalizeOptions(options); + + record = options.cache.get(cacheKey); + if(record) { + return record; + } + + record = entity.queryRecord(this, id, options, query, urlParams); + options.cache.set(cacheKey, record); + + return record; + }, + query: function(type, query, options, urlParams) { + var entity = this.entityFor(type), + cacheKey = this.getCacheKey(type, query), + records; + + this.checkRequisite(type); + + options = this.normalizeOptions(options); + + records = options.cache.get(cacheKey); + if(records) { + return records; + } + + records = entity.query(this, query, options, urlParams); + options.cache.set(cacheKey, records); + + return records; + }, + + unloadAll: function (type, skipID) { + var store = this.get("store"), + loaderNS = this.get("nameSpace"); + + store.peekAll(type).forEach(function (record) { + var id = record.get("id"); + + if(id.substr(0, id.indexOf(":")) === loaderNS && record.get("entityID") !== skipID) { + store.unloadRecord(record); + } + }); + }, +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/services/local-storage.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/services/local-storage.js b/tez-ui/src/main/webapp/app/services/local-storage.js new file mode 100644 index 0000000..d25ef9d --- /dev/null +++ b/tez-ui/src/main/webapp/app/services/local-storage.js @@ -0,0 +1,39 @@ +/** + * 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.Service.extend({ + getStoreKey: function (key) { + return "tez-ui:" + key; + }, + set: function (key, value) { + try { + localStorage.setItem(this.getStoreKey(key) , JSON.stringify(value)); + }catch(e){ + return e; + } + return value; + }, + get: function (key) { + try { + return JSON.parse(localStorage.getItem(this.getStoreKey(key))); + }catch(e){} + return undefined; + } +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/services/pollster.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/services/pollster.js b/tez-ui/src/main/webapp/app/services/pollster.js new file mode 100644 index 0000000..7e41fa1 --- /dev/null +++ b/tez-ui/src/main/webapp/app/services/pollster.js @@ -0,0 +1,110 @@ +/*global more*/ +/** + * 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 STATE_STORAGE_KEY = "pollingIsActive", + DEFAULT_LABEL = "default_label"; + +var MoreObject = more.Object; + +export default Ember.Service.extend({ + localStorage: Ember.inject.service("localStorage"), + env: Ember.inject.service("env"), + + interval: Ember.computed.oneWay("env.app.pollingInterval"), + + active: false, + isPolling: false, + scheduleID: null, + + polls: {}, + pollCount: 0, + + initState: Ember.on("init", function () { + var state = this.get("localStorage").get(STATE_STORAGE_KEY); + + if(state === undefined || state === null) { + state = true; + } + Ember.run.later(this, function () { + this.set("active", state); + }); + }), + stateObserver: Ember.observer("active", function () { + this.get("localStorage").set(STATE_STORAGE_KEY, this.get("active")); + this.callPoll(); + }), + + isReady: Ember.computed("active", "pollCount", function () { + return !!(this.get("active") && this.get("pollCount")); + }), + + callPoll: function () { + var that = this; + this.unSchedulePoll(); + if(this.get("isReady") && !this.get("isPolling")) { + var pollsPromises = []; + + this.set("isPolling", true); + + MoreObject.forEach(this.get("polls"), function (label, pollDef) { + pollsPromises.push(pollDef.callback.call(pollDef.context)); + }); + + Ember.RSVP.allSettled(pollsPromises).finally(function () { + that.set("isPolling", false); + that.schedulePoll(); + }); + } + }, + + schedulePoll: function () { + this.set("scheduleID", setTimeout(this.callPoll.bind(this), this.get("interval"))); + }, + unSchedulePoll: function () { + clearTimeout(this.get("scheduleID")); + }, + + setPoll: function (pollFunction, context, label) { + var polls = this.get("polls"), + pollCount; + + label = label || DEFAULT_LABEL; + polls[label] = { + context: context, + callback: pollFunction, + }; + this.set("pollCount", pollCount = Object.keys(polls).length); + + this.callPoll(); + }, + resetPoll: function (label) { + var polls = this.get("polls"), + pollCount; + + label = label || DEFAULT_LABEL; + delete polls[label]; + this.set("pollCount", pollCount = Object.keys(polls).length); + + if(!pollCount) { + this.unSchedulePoll(); + } + } +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/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 new file mode 100644 index 0000000..c881553 --- /dev/null +++ b/tez-ui/src/main/webapp/app/styles/app.less @@ -0,0 +1,52 @@ +/** + * 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 "bower_components/bootstrap/less/bootstrap"; +@import "bower_components/font-awesome/less/font-awesome"; + +@import "bower_components/snippet-ss/less/force"; +@import "bower_components/snippet-ss/less/effects"; +@import "bower_components/snippet-ss/less/no"; +@import "bower_components/snippet-ss/less/background"; + +// Prerequisites +@import "colors"; +@import "shared"; + +@import "tooltip"; + +// Components +@import "tab-n-refresh"; +@import "dags-page-search"; +@import "table-controls"; +@import "error-bar"; +@import "caller-info"; +@import "date-formatter"; +@import "em-swimlane"; +@import "em-tooltip"; +@import "em-swimlane-vertex-name"; +@import "em-table-status-cell"; + +// Modals +@import "column-selector"; +@import "zip-download-modal"; + +// Pages +@import "page-layout"; +@import "details-page"; +@import "swimlane-page"; http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/styles/caller-info.less ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/styles/caller-info.less b/tez-ui/src/main/webapp/app/styles/caller-info.less new file mode 100644 index 0000000..2dc78f1 --- /dev/null +++ b/tez-ui/src/main/webapp/app/styles/caller-info.less @@ -0,0 +1,26 @@ +/** + * 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. + */ + +.caller-info { + .panel-info { + overflow: hidden; + } + .CodeMirror { + height: auto; + } +} http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/styles/column-selector.less ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/styles/column-selector.less b/tez-ui/src/main/webapp/app/styles/column-selector.less new file mode 100644 index 0000000..747ed48 --- /dev/null +++ b/tez-ui/src/main/webapp/app/styles/column-selector.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. + */ + +.column-selector { + .message { + position: absolute; + font-size: 12px; + padding: 1px; + left: 15px; + } + + .highlight { + background-color: @bg-lite; + } + .per-io { + color: @text-green; + } + + .selection-list { + border-bottom: 1px solid @border-color; + + .options { + .force-scrollbar; + + max-height: 450px; + overflow: auto; + } + + .select-option, .filter-option { + border-top: 1px dotted @border-color; + padding: 5px 15px; + + .checkbox { + display: inline-block; + + margin-right: 10px; + float: left; + vertical-align: middle; + } + } + .filter-option { + border: none; + + .form-group { + display: inline-block; + + width: 100%; + margin: 0px; + } + + .select-all { + display: inline-block; + + height: 15px; + margin-top: 3px; + } + } + } +} +.form-actions { + padding: 10px; + text-align: right; +} http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/styles/dag-view.less ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/styles/dag-view.less b/tez-ui/src/main/webapp/app/styles/dag-view.less deleted file mode 100644 index 84422b5..0000000 --- a/tez-ui/src/main/webapp/app/styles/dag-view.less +++ /dev/null @@ -1,376 +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 "../bower_components/bootstrap/less/bootstrap"; -@import "../bower_components/font-awesome/less/font-awesome"; - -@import "app/styles/colors.less"; -@import "app/styles/shared.less"; - -// -- HTML styles --- -.dag-view-container { - .no-select; - .well; - - background-color: @bg-liter; - - position: relative; - - padding: 0px; - width:100%; - height: 100%; - - .svg-container { - width:100%; - overflow:hidden; - height: 100%; - - cursor: -moz-grab; - cursor: -webkit-grab; - cursor: grab; - - &.panning { - cursor: -moz-grabbing; - cursor: -webkit-grabbing; - cursor: grabbing; - } - - svg { - width: 100%; - height: 100%; - } - } - - .button-panel { - .no-select; - - position: absolute; - top: 10px; - right: 10px; - - // Toggle buttons - .tgl-orientation, .tgl-additionals, .config, .timeline, .fit-graph, .tgl-fullscreen { - .fa; - .fa-border; - font-size: 20px; - border-radius: 5px; - - cursor: pointer; - - border-color: @border-lite; - background-color: @bg-lite; - - &:hover { - color: @bg-lite; - background-color: @text-color; - } - } - .tgl-orientation { - .fa-icon(share-alt); - } - .tgl-additionals { - .fa-icon(circle); - - &.hide-additionals { - .fa-icon(circle-o); - } - } - .config { - .fa-icon(cog); - } - .timeline { - .fa-icon(clock-o); - } - .fit-graph { - .fa-icon(arrows-alt); - } - .tgl-fullscreen { - .fa-icon(expand); - } - - .seperator { - display: inline-block; - border-left: 1px dotted @text-color; - height: 13px; - } - } - - .fullscreen { - height: 100%; - margin: 0px; - .svg-container, svg { - height: 100%; - } - - .tgl-fullscreen { - .fa-icon(compress); - } - } - - &:-webkit-full-screen { - .fullscreen; - } - &:fullscreen { - .fullscreen; - } - &:-moz-full-screen { - .fullscreen; - } -} - -// -- SVG styles --- - -.grey-glow { - stroke: grey; -} - -.vertex-node-bg { - .grey-glow; -} - -.input-node-bg { - .grey-glow; -} - -.output-node-bg { - .grey-glow; -} - -.task-bubble-bg { - .grey-glow; -} - -.group-bubble-bg { - .grey-glow; -} - -.node { - cursor: pointer; - - text { - .no-select; - - pointer-events: none; - font: 11px sans-serif; - text-anchor: middle; - - // Ensure to manually change the transforms in graph-view.js for IE compatibility - -webkit-transform: translate(0px, 4px); // For safari - -moz-transform: translate(0px, 4px); - transform: translate(0px, 4px); - } -} - -.vertex { - text.title { - // Ensure to manually change the transforms in graph-view.js for IE compatibility - -webkit-transform: translate(0px, 3px); // For safari - transform: translate(0px, -1px); - } - - .task-bubble { - // Ensure to manually change the transforms in graph-view.js for IE compatibility - -webkit-transform: translate(38px, -15px); - transform: translate(38px, -15px); - text { - letter-spacing: -1px; - text-anchor: middle; - } - } - - .io-bubble { - // Ensure to manually change the transforms in graph-view.js for IE compatibility - -webkit-transform: translate(-38px, -15px); - transform: translate(-38px, -15px); - opacity: 0; - pointer-events: none; - - -moz-transition: opacity .5s ease-in-out; - -webkit-transition: opacity .5s ease-in-out; - transition: opacity .5s ease-in-out; - - text { - text-anchor: middle; - } - } - - .group-bubble { - // Ensure to manually change the transforms in graph-view.js for IE compatibility - -webkit-transform: translate(38px, 15px); - transform: translate(38px, 15px); - } - - .status-bar { - pointer-events: none; - - .status { - -webkit-transform: translate(-35px, 2px); - transform: translate(-35px, 2px); - font: 8px Helvetica; - text-align: center; - - .msg-container { - border-radius: 5px; - padding: 2px 3px 0px 1px; - background-color: rgba(255, 255, 255, 0.3); - - .task-status { - -webkit-animation: none !important; - font-size: 11px; - margin-top: 3px; - background-color: rgba(255, 255, 255, 0.8); - border-radius: 6px; - vertical-align: -1px; - - width: 8px; - height: 7px; - - &.running { - font-size: 11px; - - width: 9px; - height: 7px - } - } - } - } - } -} - -.hide-io { - .vertex { - .io-bubble { - opacity: 1; - pointer-events: auto; - } - } -} - -.link { - fill: none; - stroke: #ccc; - stroke-width: 3px; - - cursor: default; - - &.broadcast { - stroke: #ccbb8f; - } -} - -// -- Tooltip style --- -.tool-tip { - .no-select; - - position: fixed; - pointer-events: none; - display: none; - - max-width: 820px; - - .sub { - font-size: 10px; - } - - .bubble { - margin-left: -11px; // Border radious + arrow margin-left - - position: relative; - padding: 10px; - - font-family: helvetica; - background: rgba(0, 0, 0, 0.8); - color: #fff; - border-radius: 5px; - - .tip-title { - text-align: center; - font-size: 1.1em; - } - .tip-text { - border-top: 1px solid rgba(255, 255, 255, 0.4); - text-align: center; - margin-bottom: -1px; - } - .tip-list { - table { - table-layout:fixed; - - border-top: 1px solid rgba(255, 255, 255, 0.4); - - td { - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - max-width: 400px; - } - td:nth-child(1) { - padding-right: 10px; - } - td:nth-child(2) { - text-align: right; - padding-left: 10px; - border-left: 1px solid rgba(255, 255, 255, 0.4); - } - } - } - } - - &.show { - display: inline-block; - } - - &.below:after, &.above:before { - display: inline; - box-sizing: border-box; - - font-size: 12px; - line-height: 9px; - - color: rgba(0, 0, 0, 0.8); - margin-left: -6px; // Half of font size - } - - &.above { - margin-top: 10px; - .bubble { - margin-top: -5px; - } - - &:before { - content: "\25B2"; - } - } - - &.below { - margin-top: -12px; - .bubble { - margin-bottom: -7px; - } - - &:after { - content: "\25BC"; - } - } -} - -.dag-view-legend { - margin-top: -20px; - font-size: .7em; - text-align: right; -} http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/styles/dags-page-search.less ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/styles/dags-page-search.less b/tez-ui/src/main/webapp/app/styles/dags-page-search.less new file mode 100644 index 0000000..d38ce09 --- /dev/null +++ b/tez-ui/src/main/webapp/app/styles/dags-page-search.less @@ -0,0 +1,85 @@ +/** + * 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. + */ + +.dags-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: 16.66%; + + padding-left: 3px; + + label { + margin-bottom: 2px; + } + + select { + top: -1px; + position: relative; + } + } + + .dag-name { + padding-left: 0px; + } +} + +.all-dags-table { + .pagination-ui, .table-controls { + margin-top: -5px; + margin-bottom: 5px; + } +} + +@media screen and (min-width: 1300px) { + .dags-page-search{ + float: left; + width: 70%; + + .form-group { + margin-bottom: 0px; + } + } + + .all-dags-table { + .pagination-ui, .table-controls { + margin-top: 21px; + } + } +} http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/styles/date-formatter.less ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/styles/date-formatter.less b/tez-ui/src/main/webapp/app/styles/date-formatter.less new file mode 100644 index 0000000..a817bec --- /dev/null +++ b/tez-ui/src/main/webapp/app/styles/date-formatter.less @@ -0,0 +1,21 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +.date-formatter { + display: inline; +} http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/styles/details-page.less ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/styles/details-page.less b/tez-ui/src/main/webapp/app/styles/details-page.less new file mode 100644 index 0000000..75d5e11 --- /dev/null +++ b/tez-ui/src/main/webapp/app/styles/details-page.less @@ -0,0 +1,58 @@ +/** + * 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. + */ + +.detail-list { + display: inline-block; + vertical-align: top; + + margin: 0 10px 10px 0; + + table-layout: fixed; + + .progress { + margin-bottom: 0px; + } + + tr { + margin: 0px 0px 0px 15px; + overflow: hidden; + } + + thead { + background-color: @bg-lite; + font-weight: bold; + } + + td { + padding: 0px 20px 0px 0px; + white-space: nowrap; + + .ember-view { + display: inline; + } + } + + td:first-child { + width:120px; + } + + th, td { + border: 1px solid @border-lite; + padding: 5px; + } +} http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/styles/em-swimlane-vertex-name.less ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/styles/em-swimlane-vertex-name.less b/tez-ui/src/main/webapp/app/styles/em-swimlane-vertex-name.less new file mode 100644 index 0000000..249a8f1 --- /dev/null +++ b/tez-ui/src/main/webapp/app/styles/em-swimlane-vertex-name.less @@ -0,0 +1,65 @@ +/** + * 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. + */ + +.em-swimlane-vertex-name { + + cursor: pointer; + + direction: rtl; + text-align: right; + + padding: 5px 5px 0px 0px; + white-space: nowrap; + + height: 30px; + + .name-text { + display: inline-block; + vertical-align: baseline; + + &.ellipsis:after { + content:"\2026"; + margin-right: -4px; + } + } + + .em-table-status-cell { + display: inline-block; + vertical-align: text-top; + + direction: ltr; + + .status { + display: inline-block; + + padding: 2px; + + width: 16px; + height: 16px; + overflow: hidden; + border-radius: 10px; + } + + .status-icon { + display: inline-block; + width: 12px; + margin-top: 2px; + } + } + +} http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/styles/em-swimlane.less ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/styles/em-swimlane.less b/tez-ui/src/main/webapp/app/styles/em-swimlane.less new file mode 100644 index 0000000..77ea646 --- /dev/null +++ b/tez-ui/src/main/webapp/app/styles/em-swimlane.less @@ -0,0 +1,246 @@ +/** + * 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. + */ + +@process-height: 30px; +@event-anim-duration: .2s; + +.em-swimlane { + position: relative; + + margin: 5px 0px 40px 0px; + + .process-names { + width: 100px; + border-right: 1px solid @border-color; + + .consolidated-view-label { + margin-top: 20px; + padding-bottom: 10px; + } + } + .process-visuals { + .force-scrollbar; + + position: absolute; + left: 100px; + right: 0px; + top: 0px; + overflow: auto; + + .consolidated-view { + position: relative; + margin: 20px 10px 2px 10px; + height: 20px; + border: 1px solid @border-color; + border-radius: 2px; + } + } + + .em-swimlane-ruler { + margin: 9px 10px 5px 10px; + + .ruler-line { + margin: 0px -10px 0px -10px; + border-top: 1px solid @border-color; + } + + .unit-text { + display: inline-block; + position: relative; + transition: left .5sec ease-out; + } + + .mark-container { + overflow: hidden; + font-size: 0; + overflow: hidden; + white-space: nowrap; + + .ruler-mark { + display: inline-block; + border-left: 1px solid @border-color; + + margin-right: -1px; + margin-bottom: -2px; + + font-size: 12px; + + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + + .sub-marks { + display: block; + padding: 0px; + + margin-bottom: -8px; + + li { + vertical-align: top; + display: inline-block; + width: 10%; + height: 5px; + border-left: 1px solid @border-lite; + + &:first-child { + border-left: none; + } + + &:nth-child(2n) { + height: 8px; + } + &:nth-child(6) { + height: 12px; + } + } + } + } + } + + } +} + +.em-swimlane-consolidated-process { + position: absolute; + cursor: pointer; + + top: 0px; + bottom: 0px; + border: 1px solid white; + + transition: top .2s; + &.focused { + top: -10px; + border-top-left-radius: 5px; + border-top-right-radius: 5px; + } +} + +.em-swimlane-process-name { + text-align: right; + padding-right: 5px; + padding-top: 5px; + + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + + height: 30px; +} + +.em-swimlane-process-visual { + position: relative; + height: 30px; + + // Gives a mouse sensitive margin to the left and right, + // so that event lines appear with a padding + border-left: 10px solid transparent; + border-right: 10px solid transparent; + + .process-line, .event-bar, .event-bubble { + cursor: pointer; + } + .base-line { + position: relative; + height: 1px; + margin: 0px -10px; + top: unit(unit(@process-height) * 0.5, get-unit(@process-height)); + border-top: 1px dotted @border-color; + } + + .process-line, .event-bar, .em-swimlane-event, .em-swimlane-blocking-event { + position: absolute; + } + + .process-line { + top: unit(unit(@process-height) * 0.5 - 1, get-unit(@process-height)); + height: 3px; + + left: 0%; + right: 100%; + transition: left @event-anim-duration ease-out, right @event-anim-duration ease-out; + } + + .event-bar { + top: unit((unit(@process-height) * 0.5) - 10, get-unit(@process-height)); + height: 20px; + background-color: @border-lite; + border-radius: 2px; + border: 1px solid; + margin-right: -1px; + + left: 0%; + right: 100%; + transition: left @event-anim-duration ease-out, right @event-anim-duration ease-out; + } + + .em-swimlane-event { + top: unit(unit(@process-height) * 0.5, get-unit(@process-height)); + + left: 0%; + transition: left @event-anim-duration ease-out; + + .event-line { + position: absolute; + top: -9px; + height: 18px; + border-left: 1px solid; + } + + .event-bubble { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + + -webkit-transition: top .2s, right .2s, bottom .2s, left .2s, border-width .2s; /* Safari */ + transition: top .2s, right .2s, bottom .2s, left .2s, border-width .2s; + transition-timing-function: cubic-bezier(1.44); + + border-radius: 7px; + border: 0px solid; + background-color: white; + } + } + + .em-swimlane-blocking-event { + top: unit(unit(@process-height) * 0.5, get-unit(@process-height)); + + left: 0%; + height: 0; + transition: left @event-anim-duration ease-out, height @event-anim-duration ease-out; + + .event-line { + position: absolute; + top: 0px; + border-left: 1px solid; + } + } + + &:hover { + .event-bubble { + top: -7px; + right: -8px; + bottom: -8px; + left: -7px; + + border: 2px solid; + } + } +} http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/styles/em-table-status-cell.less ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/styles/em-table-status-cell.less b/tez-ui/src/main/webapp/app/styles/em-table-status-cell.less new file mode 100644 index 0000000..4586da7 --- /dev/null +++ b/tez-ui/src/main/webapp/app/styles/em-table-status-cell.less @@ -0,0 +1,99 @@ +/** + * 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. + */ + +.fa-icon(@name) { + @content: "fa-var-@{name}"; + &:before {content: @@content} +} + +.em-table-status-cell { + overflow: visible !important; + + .status { + .label; + .label-default; + } + .status-icon { + .fa; + .fa-icon(exclamation); + } + + .status-new, .status-inited { + .status-icon { + .fa-icon(plus); + } + } + + .status-initializing, .status-scheduled, .status-start-wait { + .label-primary; + .status-icon { + .fa-icon(history); + } + } + + .status-running { + .diagonal-stripes-bg; + .animate; + .label-info; + .status-icon { + .fa-icon(spinner); + } + } + + .status-committing { + .label-info; + .status-icon { + .fa-icon(save); + } + } + + .status-finished, .status-succeeded, .status-succeeded-with-failures { + .label-success; + .status-icon { + .fa-icon(check); + } + } + .status-succeeded-with-failures { + .label-warning; + } + + .status-terminating { + .label-warning; + .status-icon { + .fa-icon(exclamation-triangle); + } + } + + .status-failed, .status-fail-in-progress { + .label-warning; + .status-icon { + .fa-icon(exclamation); + } + } + + .status-kill-wait, .status-kill-in-progress, .status-killed, .status-error { + .label-warning; + .status-icon { + .fa-icon(ban); + } + } + .status-killed, .status-error { + .label-danger; + } + +} http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/styles/em-tooltip.less ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/styles/em-tooltip.less b/tez-ui/src/main/webapp/app/styles/em-tooltip.less new file mode 100644 index 0000000..3f7ed87 --- /dev/null +++ b/tez-ui/src/main/webapp/app/styles/em-tooltip.less @@ -0,0 +1,119 @@ +/** + * 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. + */ + +.em-tooltip { + .no-select; + .no-mouse; + + z-index: 9007199254740991; + + position: fixed; + width: 820px; //2 * (td width + padding) + + top: 10px; + left: 20px; + + .bubble-container { + margin-bottom: 5px; + + .bubble { + display: inline-block; + max-width: 820px; + margin-left: -11px; // Border radius + arrow margin-left + + position: relative; + padding: 10px; + + font-family: helvetica; + background: rgba(0, 0, 0, 0.8); + color: #fff; + border-radius: 5px; + + .tip-title, .tip-desc, .tip-props { + border-top: 1px solid rgba(255, 255, 255, 0.4); + text-align: center; + + padding: 0px 2px; + + &:first-child { + border-top: none; + } + } + + .tip-title { + font-size: 1.1em; + } + + .tip-props { + table { + display: inline; + table-layout:fixed; + + td { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + max-width: 400px; + + text-align: right; + } + td:nth-child(1) { + padding-right: 10px; + text-align: left; + } + td:nth-child(2) { + text-align: right; + padding-left: 10px; + border-left: 1px solid rgba(255, 255, 255, 0.4); + } + } + } + } + } + + &.below:after, &.above:before { + display: block; + box-sizing: border-box; + + font-size: 12px; + line-height: 9px; + + color: rgba(0, 0, 0, 0.8); + margin-left: -6px; // Half of font size + } + + &.above { + margin-top: 20px; + + &:before { + margin-bottom: -2px; + content: "\25B2"; + } + } + + &.below { + .bubble-container { + margin-top: 5px; + margin-bottom: 0px; + } + + &:after { + content: "\25BC"; + } + } +}