http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/Gruntfile.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/Gruntfile.js b/tez-ui/src/main/webapp/Gruntfile.js deleted file mode 100644 index dc92bb2..0000000 --- a/tez-ui/src/main/webapp/Gruntfile.js +++ /dev/null @@ -1,482 +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. - */ -// Generated on 2014-06-24 using generator-ember 0.8.4 -'use strict'; -var LIVERELOAD_PORT = 35729; -var lrSnippet = require('connect-livereload')({port: LIVERELOAD_PORT}); -var mountFolder = function (connect, dir) { - return connect.static(require('path').resolve(dir)); -}; - -// # Globbing -// for performance reasons we're only matching one level down: -// 'test/spec/{,*/}*.js' -// use this if you want to match all subfolders: -// 'test/spec/**/*.js' - -module.exports = function (grunt) { - // show elapsed time at the end - require('time-grunt')(grunt); - // load all grunt tasks - require('load-grunt-tasks')(grunt); - - // configurable paths - var yeomanConfig = { - app: 'app', - dist: 'dist' - }; - - grunt.initConfig({ - yeoman: yeomanConfig, - watch: { - emberTemplates: { - files: '<%= yeoman.app %>/templates/**/*.hbs', - tasks: ['emberTemplates'] - }, - neuter: { - files: ['<%= yeoman.app %>/scripts/{,*/,*/*/}*.js'], - tasks: ['neuter'] - }, - less: { - files: '<%= yeoman.app %>/styles/**/*.less', - tasks: ['less:development'] - }, - livereload: { - options: { - livereload: LIVERELOAD_PORT - }, - files: [ - '.tmp/scripts/**/*.js', - '<%= yeoman.app %>/*.html', - '{.tmp,<%= yeoman.app %>}/styles/{,*/}*.css', - '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}' - ] - }, - css: { - files: '<%= yeoman.app %>/styles/*.css', - tasks: ['copy:development'] - } - }, - connect: { - options: { - port: 9001, - // change this to '0.0.0.0' to access the server from outside - hostname: 'localhost' - }, - livereload: { - options: { - middleware: function (connect) { - return [ - lrSnippet, - mountFolder(connect, '.tmp'), - mountFolder(connect, yeomanConfig.app) - ]; - } - } - }, - test: { - options: { - middleware: function (connect) { - return [ - mountFolder(connect, 'test'), - mountFolder(connect, '.tmp') - ]; - } - } - }, - dist: { - options: { - middleware: function (connect) { - return [ - mountFolder(connect, yeomanConfig.dist) - ]; - } - } - } - }, - open: { - server: { - path: 'http://localhost:<%= connect.options.port %>' - } - }, - clean: { - dist: { - files: [ - { - dot: true, - src: [ - '.tmp', - '<%= yeoman.dist %>/*', - '!<%= yeoman.dist %>/.git*' - ] - } - ] - }, - server: '.tmp' - }, - jshint: { - options: { - jshintrc: '.jshintrc', - reporter: require('jshint-stylish') - }, - all: [ - 'Gruntfile.js', - '<%= yeoman.app %>/scripts/{,*/}*.js', - '!<%= yeoman.app %>/scripts/vendor/*', - 'test/spec/{,*/}*.js' - ] - }, - mocha: { - all: { - options: { - run: true, - urls: ['http://localhost:<%= connect.options.port %>/index.html'] - } - } - }, - // not used since Uglify task does concat, - // but still available if needed - /*concat: { - dist: {} - },*/ - // not enabled since usemin task does concat and uglify - // check index.html to edit your build targets - // enable this task if you prefer defining your build targets here - /*uglify: { - dist: {} - },*/ - rev: { - dist: { - files: { - src: [ - '<%= yeoman.dist %>/scripts/app.js', - '<%= yeoman.dist %>/styles/{,*/}*.css', - '<%= yeoman.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp}', - '<%= yeoman.dist %>/styles/fonts/*' - ] - } - } - }, - useminPrepare: { - html: '.tmp/index.html', - options: { - dest: '<%= yeoman.dist %>' - } - }, - usemin: { - html: ['<%= yeoman.dist %>/{,*/}*.html'], - css: ['<%= yeoman.dist %>/styles/{,*/}*.css'], - options: { - dirs: ['<%= yeoman.dist %>'] - } - }, - svgmin: { - dist: { - files: [ - { - expand: true, - cwd: '<%= yeoman.app %>/images', - src: '{,*/}*.svg', - dest: '<%= yeoman.dist %>/images' - } - ] - } - }, - cssmin: { - dist: { - files: { - '<%= yeoman.dist %>/styles/main.css': [ - '.tmp/styles/{,*/}*.css', - '<%= yeoman.app %>/styles/{,*/}*.css', - '<%= yeoman.app %>/bower_components/ember-table/dist/ember-table.css', - '<%= yeoman.app %>/bower_components/font-awesome/css/font-awesome.css', - '<%= yeoman.app %>/bower_components/jquery-ui/themes/smoothness/jquery-ui.css', - '<%= yeoman.app %>/bower_components/codemirror/lib/codemirror.css' - ] - } - } - }, - htmlmin: { - dist: { - options: { - /*removeCommentsFromCDATA: true, - // https://github.com/yeoman/grunt-usemin/issues/44 - //collapseWhitespace: true, - collapseBooleanAttributes: true, - removeAttributeQuotes: true, - removeRedundantAttributes: true, - useShortDoctype: true, - removeEmptyAttributes: true, - removeOptionalTags: true*/ - }, - files: [ - { - expand: true, - cwd: '<%= yeoman.app %>', - src: '*.html', - dest: '<%= yeoman.dist %>' - } - ] - } - }, - replace: { - app: { - options: { - variables: { - ember: 'bower_components/ember/ember.js', - ember_data: 'bower_components/ember-data/ember-data.js' - } - }, - files: [ - {src: '<%= yeoman.app %>/index.html', dest: '.tmp/index.html'} - ] - }, - dist: { - options: { - variables: { - ember: 'bower_components/ember/ember.prod.js', - ember_data: 'bower_components/ember-data/ember-data.prod.js' - } - }, - files: [ - {src: '<%= yeoman.app %>/index.html', dest: '.tmp/index.html'} - ] - } - }, - // Put files not handled in other tasks here - copy: { - dist: { - files: [ - { - expand: true, - dot: true, - cwd: '<%= yeoman.app %>', - dest: '<%= yeoman.dist %>', - src: [ - '*.{ico,txt}', - '.htaccess', - 'img/*', - 'styles/fonts/*', - 'scripts/assets/**/*' - ] - }, - { - src: '<%= yeoman.app %>/scripts/configs.js', - dest: '<%= yeoman.dist %>/scripts/configs.js' - }, - { - expand: true, - flatten: true, - cwd: '<%= yeoman.app %>', - dest: '<%= yeoman.dist %>/scripts/zip.js', - src: [ - 'bower_components/zip.js/WebContent/z-worker.js', - 'bower_components/zip.js/WebContent/inflate.js', - 'bower_components/zip.js/WebContent/deflate.js', - ] - }, - { - expand: true, - flatten: true, - src: '<%= yeoman.app %>/bower_components/jquery-ui/themes/smoothness/images/*', - dest: '<%= yeoman.dist %>/styles/images/' - }, - { - expand: true, - flatten: true, - src: '<%= yeoman.app %>/bower_components/font-awesome/fonts/*', - dest: '<%= yeoman.dist %>/fonts/' - } - ] - }, - development: { - files: [ - { - expand: true, - dot: true, - cwd: '<%= yeoman.app %>', - dest: '.tmp', - src: [ - '*.{ico,txt}', - '.htaccess', - 'img/*', - 'styles/*.css', - 'styles/fonts/*', - 'scripts/assets/**/*' - ] - }, - { - src: '<%= yeoman.app %>/scripts/configs.js', - dest: '<%= yeoman.dist %>/scripts/configs.js' - }, - { - expand: true, - flatten: true, - src: '<%= yeoman.app %>/bower_components/jquery-ui/themes/smoothness/images/*', - dest: '.tmp/styles/images/' - }, - { - expand: true, - flatten: true, - src: '<%= yeoman.app %>/bower_components/font-awesome/fonts/*', - dest: '.tmp/fonts/' - }, - { - expand: true, - flatten: true, - cwd: '<%= yeoman.app %>', - dest: '.tmp/scripts/zip.js', - src: [ - 'bower_components/zip.js/WebContent/z-worker.js', - 'bower_components/zip.js/WebContent/inflate.js', - 'bower_components/zip.js/WebContent/deflate.js', - ] - }, - { - expand: true, - flatten: false, - cwd: '<%= yeoman.app %>', - src: 'bower_components/**', - dest: '.tmp/' - } - ] - } - }, - concurrent: { - server: [ - 'emberTemplates' - ], - test: [ - 'emberTemplates' - ], - dist: [ - 'emberTemplates', - 'svgmin', - 'htmlmin' - ] - }, - emberTemplates: { - options: { - templateName: function (sourceFile) { - var templatePath = yeomanConfig.app + '/templates/'; - return sourceFile.replace(templatePath, ''); - } - }, - dist: { - files: { - '.tmp/scripts/compiled-templates.js': '<%= yeoman.app %>/templates/**/*.hbs' - } - }, - development: { - files: { - '.tmp/scripts/compiled-templates.js': '<%= yeoman.app %>/templates/**/*.hbs' - } - } - }, - - less: { - development: { - options: { - paths: ["<%= yeoman.app %>/styles"], - sourceMap: true, - }, - files: [{ - expand: true, - cwd: "<%= yeoman.app %>/styles", - src: ['styles/*.less', '**/*.less'], - dest: ".tmp/styles", - ext: ".css" - }] - }, - production: { - options: { - paths: ["<%= yeoman.app %>/styles"], - cleancss: true - }, - files: { - ".tmp/styles/styles.css": "<%= yeoman.app %>/styles/**/*.less" - } - } - }, - - neuter: { - app: { - options: { - filepathTransform: function (filepath) { - return yeomanConfig.app + '/' + filepath; - } - }, - src: '<%= yeoman.app %>/scripts/app.js', - dest: '.tmp/scripts/combined-scripts.js' - } - } - }); - - grunt.registerTask('server', function (target) { - grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.'); - grunt.task.run(['serve:' + target]); - }); - - grunt.registerTask('serve', function (target) { - if (target === 'dist') { - return grunt.task.run(['build', 'open', 'connect:dist:keepalive']); - } - - grunt.task.run([ - 'clean:server', - 'replace:app', - 'concurrent:server', - 'neuter:app', - 'less:development', - 'connect:livereload', - 'open', - 'copy:development', - 'watch' - ]); - }); - - grunt.registerTask('test', [ - 'clean:server', - 'replace:app', - 'concurrent:test', - 'connect:test', - 'neuter:app', - 'mocha' - ]); - - grunt.registerTask('build', [ - 'clean:dist', - 'replace:app', - 'useminPrepare', - 'concurrent:dist', - 'neuter:app', - 'less:production', - 'concat', - 'cssmin', - //'uglify', - 'copy:dist', - //'rev', - 'usemin' - ]); - - grunt.registerTask('default', [ - 'jshint', - 'test', - 'build' - ]); -};
http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/README.md ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/README.md b/tez-ui/src/main/webapp/README.md index 85b7fb2..997752c 100644 --- a/tez-ui/src/main/webapp/README.md +++ b/tez-ui/src/main/webapp/README.md @@ -1,21 +1,57 @@ <!-- - Licensed 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 + 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 + 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. See accompanying LICENSE file. + 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. --> -Tez UI -========= +# Tez-ui -The Tez UI is an ember based web application that provides visualization of Tez applications -running on the Apache Hadoop YARN framework. +The Tez UI is an ember based web-app that provides visualization of Tez applications running on the Apache Hadoop YARN framework. -For more information on Tez and the Tez UI - the [tez homepage](http://tez.apache.org/ "Apache Tez Homepage"). +For more information on Tez and the Tez UI - Check the [Tez homepage](http://tez.apache.org/ "Apache Tez Homepage"). + +## Configurations + +* By default timeline is expected at localhost:8188 & RM at localhost:8088 +* You can point the UI to custom locations by setting the environment variables in `src/main/webapp/config/configs.env` + +## Development + +All the following commands must be run inside `src/main/webapp`. + +### Prerequisites + +You will need the following things properly installed on your computer. + +* Install [Node.js](http://nodejs.org/) (with NPM) +* Install [Bower](http://bower.io/) +* Install all dependencies by running `npm install` & `bower install` + +### Running UI + +* `npm start` +* Visit your app at [http://localhost:4200](http://localhost:4200). + +### Running Tests + +* `npm test` + +### Building + +* `npm run build` (production) +* Files would be stored in "dist/" + +### Adding new routes (pages), controllers, components etc. + +* Use ember-cli blueprint generator - [Ember CLI](http://ember-cli.com/extending/#generators-and-blueprints) http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/WEB-INF/wro.xml ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/WEB-INF/wro.xml b/tez-ui/src/main/webapp/WEB-INF/wro.xml new file mode 100644 index 0000000..2709c6f --- /dev/null +++ b/tez-ui/src/main/webapp/WEB-INF/wro.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<groups xmlns="http://www.isdc.ro/wro"> + <group name='vendor'> + <js>/vendor.js</js> + </group> + <group name='tez-ui'> + <js>/tez-ui.js</js> + </group> +</groups> http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/adapters/abstract.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/adapters/abstract.js b/tez-ui/src/main/webapp/app/adapters/abstract.js new file mode 100644 index 0000000..121d4ee --- /dev/null +++ b/tez-ui/src/main/webapp/app/adapters/abstract.js @@ -0,0 +1,70 @@ +/** + * 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 LoaderAdapter from './loader'; + +export default LoaderAdapter.extend({ + serverName: null, //Must be set by inheriting classes + + host: Ember.computed("serverName", function () { + var serverName = this.get("serverName"); + return this.get(`hosts.${serverName}`); + }), + namespace: Ember.computed("serverName", function () { + var serverName = this.get("serverName"); + return this.get(`env.app.namespaces.webService.${serverName}`); + }), + pathTypeHash: Ember.computed("serverName", function () { + var serverName = this.get("serverName"); + return this.get(`env.app.paths.${serverName}`); + }), + + ajaxOptions: function(url, method, options) { + options = options || {}; + options.crossDomain = true; + options.xhrFields = { + withCredentials: true + }; + options.targetServer = this.get('serverName'); + return this._super(url, method, options); + }, + + pathForType: function(type) { + var serverName = this.get("serverName"), + path = this.get("pathTypeHash")[type]; + 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/13132ec7/tez-ui/src/main/webapp/app/adapters/ahs-app.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/adapters/ahs-app.js b/tez-ui/src/main/webapp/app/adapters/ahs-app.js new file mode 100644 index 0000000..0e7556a --- /dev/null +++ b/tez-ui/src/main/webapp/app/adapters/ahs-app.js @@ -0,0 +1,27 @@ +/** + * 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 TimelineAdapter from './timeline'; + +export default TimelineAdapter.extend({ + namespace: Ember.computed.alias("env.app.namespaces.webService.appHistory"), + pathForType: function() { + return "apps"; + }, +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/adapters/am.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/adapters/am.js b/tez-ui/src/main/webapp/app/adapters/am.js new file mode 100644 index 0000000..c4cb75d --- /dev/null +++ b/tez-ui/src/main/webapp/app/adapters/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 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/13132ec7/tez-ui/src/main/webapp/app/adapters/app-rm.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/adapters/app-rm.js b/tez-ui/src/main/webapp/app/adapters/app-rm.js new file mode 100644 index 0000000..b61e391 --- /dev/null +++ b/tez-ui/src/main/webapp/app/adapters/app-rm.js @@ -0,0 +1,22 @@ +/** + * 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 RMAdapter from './rm'; + +export default RMAdapter.extend({ +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/adapters/app.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/adapters/app.js b/tez-ui/src/main/webapp/app/adapters/app.js new file mode 100644 index 0000000..b47e05f --- /dev/null +++ b/tez-ui/src/main/webapp/app/adapters/app.js @@ -0,0 +1,22 @@ +/** + * 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 TimelineAdapter from './timeline'; + +export default TimelineAdapter.extend({ +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/adapters/attempt-am.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/adapters/attempt-am.js b/tez-ui/src/main/webapp/app/adapters/attempt-am.js new file mode 100644 index 0000000..39cd2a4 --- /dev/null +++ b/tez-ui/src/main/webapp/app/adapters/attempt-am.js @@ -0,0 +1,22 @@ +/** + * 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 AMAdapter from './am'; + +export default AMAdapter.extend({ +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/adapters/attempt.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/adapters/attempt.js b/tez-ui/src/main/webapp/app/adapters/attempt.js new file mode 100644 index 0000000..b47e05f --- /dev/null +++ b/tez-ui/src/main/webapp/app/adapters/attempt.js @@ -0,0 +1,22 @@ +/** + * 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 TimelineAdapter from './timeline'; + +export default TimelineAdapter.extend({ +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/adapters/dag-am.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/adapters/dag-am.js b/tez-ui/src/main/webapp/app/adapters/dag-am.js new file mode 100644 index 0000000..39cd2a4 --- /dev/null +++ b/tez-ui/src/main/webapp/app/adapters/dag-am.js @@ -0,0 +1,22 @@ +/** + * 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 AMAdapter from './am'; + +export default AMAdapter.extend({ +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/adapters/dag.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/adapters/dag.js b/tez-ui/src/main/webapp/app/adapters/dag.js new file mode 100644 index 0000000..b47e05f --- /dev/null +++ b/tez-ui/src/main/webapp/app/adapters/dag.js @@ -0,0 +1,22 @@ +/** + * 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 TimelineAdapter from './timeline'; + +export default TimelineAdapter.extend({ +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/adapters/loader.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/adapters/loader.js b/tez-ui/src/main/webapp/app/adapters/loader.js new file mode 100644 index 0000000..f63bd07 --- /dev/null +++ b/tez-ui/src/main/webapp/app/adapters/loader.js @@ -0,0 +1,58 @@ +/*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 DS from 'ember-data'; + +var MoreString = more.String; + +export default DS.RESTAdapter.extend({ + _isLoader: true, + + buildURL: function(modelName, id, snapshot, requestType, query, params) { + var url = this._super(modelName, id, snapshot, requestType, query); + return params ? MoreString.fmt(url, params) : url; + }, + + _loaderAjax: function (url, queryParams, nameSpace) { + if (this.sortQueryParams && queryParams) { + queryParams = this.sortQueryParams(queryParams); + } + + // Inject nameSpace + return this.ajax(url, 'GET', { data: queryParams }).then(function (data) { + return { + nameSpace: nameSpace, + data: data + }; + }); + }, + + queryRecord: function(store, type, query) { + var queryParams = query.params, + url = this.buildURL(type.modelName, query.id, null, null, queryParams, query.urlParams); + return this._loaderAjax(url, queryParams, query.nameSpace); + }, + + query: function (store, type, query/*, recordArray*/) { + var queryParams = query.params, + url = this.buildURL(type.modelName, null, null, 'query', queryParams, query.urlParams); + return this._loaderAjax(url, queryParams, query.nameSpace); + } + +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/adapters/rm.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/adapters/rm.js b/tez-ui/src/main/webapp/app/adapters/rm.js new file mode 100644 index 0000000..252affb --- /dev/null +++ b/tez-ui/src/main/webapp/app/adapters/rm.js @@ -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. + */ + +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/13132ec7/tez-ui/src/main/webapp/app/adapters/task-am.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/adapters/task-am.js b/tez-ui/src/main/webapp/app/adapters/task-am.js new file mode 100644 index 0000000..39cd2a4 --- /dev/null +++ b/tez-ui/src/main/webapp/app/adapters/task-am.js @@ -0,0 +1,22 @@ +/** + * 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 AMAdapter from './am'; + +export default AMAdapter.extend({ +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/adapters/task.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/adapters/task.js b/tez-ui/src/main/webapp/app/adapters/task.js new file mode 100644 index 0000000..b47e05f --- /dev/null +++ b/tez-ui/src/main/webapp/app/adapters/task.js @@ -0,0 +1,22 @@ +/** + * 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 TimelineAdapter from './timeline'; + +export default TimelineAdapter.extend({ +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/adapters/timeline.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/adapters/timeline.js b/tez-ui/src/main/webapp/app/adapters/timeline.js new file mode 100644 index 0000000..1a341f7 --- /dev/null +++ b/tez-ui/src/main/webapp/app/adapters/timeline.js @@ -0,0 +1,106 @@ +/*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 AbstractAdapter from './abstract'; + +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', + vertexID: 'TEZ_VERTEX_ID', + taskID: 'TEZ_TASK_ID', + attemptID: 'TEZ_TASK_ATTEMPT_ID', + hiveQueryID: 'HIVE_QUERY_ID', + appID: 'applicationId', + + dagName: 'dagName', + user: "user", + status: "status", + callerID: "callerId" + }, + + stringifyFilters: function (filters) { + var filterStrs = []; + + MoreObject.forEach(filters, function (key, value) { + filterStrs.push(`${key}:${value}`); + }); + + return filterStrs.join(","); + }, + + normalizeQuery: function(query) { + var primaryFilter = null, // Primary must have just one single filter + secondaryFilters = {}, + normalQuery = {}, + filterStr; + + MoreObject.forEach(query, function (key, value) { + var filter = this.get(`filters.${key}`); + + if(filter) { + if(!primaryFilter) { + primaryFilter = {}; + primaryFilter[filter] = value; + } + else { + secondaryFilters[filter] = value; + } + } + else { + normalQuery[key] = value; + } + }, this); + + // primaryFilter + if(primaryFilter) { + filterStr = this.stringifyFilters(primaryFilter); + } + if(filterStr) { + normalQuery.primaryFilter = filterStr; + } + + // secondaryFilters + filterStr = this.stringifyFilters(secondaryFilters); + if(filterStr) { + normalQuery.secondaryFilter = filterStr; + } + + // Limit + normalQuery.limit = normalQuery.limit || this.get("env.app.rowLoadLimit"); + + return normalQuery; + }, + + query: function (store, type, query/*, recordArray*/) { + var queryParams = query.params, + url = this.buildURL(type.modelName, null, null, 'query', queryParams, query.urlParams); + + if(query) { + queryParams = this.normalizeQuery(queryParams); + } + + return this._loaderAjax(url, queryParams, query.nameSpace); + } +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/adapters/vertex-am.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/adapters/vertex-am.js b/tez-ui/src/main/webapp/app/adapters/vertex-am.js new file mode 100644 index 0000000..39cd2a4 --- /dev/null +++ b/tez-ui/src/main/webapp/app/adapters/vertex-am.js @@ -0,0 +1,22 @@ +/** + * 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 AMAdapter from './am'; + +export default AMAdapter.extend({ +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/adapters/vertex.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/adapters/vertex.js b/tez-ui/src/main/webapp/app/adapters/vertex.js new file mode 100644 index 0000000..b47e05f --- /dev/null +++ b/tez-ui/src/main/webapp/app/adapters/vertex.js @@ -0,0 +1,22 @@ +/** + * 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 TimelineAdapter from './timeline'; + +export default TimelineAdapter.extend({ +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/app.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/app.js b/tez-ui/src/main/webapp/app/app.js new file mode 100644 index 0000000..fb4695c --- /dev/null +++ b/tez-ui/src/main/webapp/app/app.js @@ -0,0 +1,36 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Ember from 'ember'; +import Resolver from 'ember-resolver'; +import loadInitializers from 'ember/load-initializers'; +import config from './config/environment'; + +let App; + +Ember.MODEL_FACTORY_INJECTIONS = true; + +App = Ember.Application.extend({ + modulePrefix: config.modulePrefix, + podModulePrefix: config.podModulePrefix, + Resolver +}); + +loadInitializers(App, config.modulePrefix); + +export default App; http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/components/caller-info.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/components/caller-info.js b/tez-ui/src/main/webapp/app/components/caller-info.js new file mode 100644 index 0000000..ece33ac --- /dev/null +++ b/tez-ui/src/main/webapp/app/components/caller-info.js @@ -0,0 +1,78 @@ +/*global CodeMirror*/ +/** + * 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. + */ + +// Must be convert into an ember addon + +import Ember from 'ember'; + +export default Ember.Component.extend({ + + type: null, + info: null, + + codeMirror: null, + + classNames: ['caller-info'], + + mode: Ember.computed("type", function () { + switch(this.get("type")) { + case 'Hive': + return 'text/x-hive'; + case 'Pig': + return 'text/x-pig'; + default: + return 'text/x-sql'; + } + }), + + _init: Ember.on('didInsertElement', function() { + var element = Ember.$(this.get('element')).find('textarea')[0], + codeMirror = CodeMirror.fromTextArea(element, { + theme: 'default', + indentUnit: 2, + smartIndent: true, + tabSize: 4, + electricChars: true, + lineWrapping: true, + lineNumbers: true, + readOnly: true, + autofocus: false, + dragDrop: false, + }); + + this.set('codeMirror', codeMirror); + + this._modeChanged(); + this._infoChanged(); + }), + + _modeChanged: Ember.observer("mode", function() { + this.get('codeMirror').setOption("mode", this.get("mode")); + }), + + _infoChanged: Ember.observer("info", function() { + var codeMirror = this.get('codeMirror'), + info = this.get('info') || ''; + + if (this.get('codeMirror').getValue() !== info) { + codeMirror.setValue(info); + } + }) + +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/components/column-selector.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/components/column-selector.js b/tez-ui/src/main/webapp/app/components/column-selector.js new file mode 100644 index 0000000..8f9ac13 --- /dev/null +++ b/tez-ui/src/main/webapp/app/components/column-selector.js @@ -0,0 +1,104 @@ +/** + * 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 isIOCounter from '../utils/misc'; + +export default Ember.Component.extend({ + + classNames: ['column-selector'], + + searchText: "", + selectAll: false, + + content: null, + + options: Ember.computed("content.columns", "content.visibleColumnIDs", function () { + var group, + highlight = false, + visibleColumnIDs = this.get('content.visibleColumnIDs') || {}; + + return this.get('content.columns').map(function (definition) { + var css = ''; + + highlight = highlight ^ (Ember.get(definition, "counterGroupName") !== group); + group = Ember.get(definition, "counterGroupName"); + + if(highlight) { + css += ' highlight'; + } + if(group && isIOCounter(group)) { + css += ' per-io'; + } + + return Ember.Object.create({ + id: Ember.get(definition, "id"), + displayText: Ember.get(definition, "headerTitle"), + css: css, + selected: visibleColumnIDs[Ember.get(definition, "id")] + }); + }); + }), + + filteredOptions: Ember.computed("options", "searchText", function () { + var options = this.get('options'), + searchText = this.get('searchText'); + + if (!searchText) { + return options; + } + + return options.filter(function (option) { + return option.get('displayText').match(searchText); + }); + }), + + selectedColumnIDs: Ember.computed("options", function () { + var columnIds = {}; + this.get('options').forEach(function (option) { + columnIds[option.get("id")] = option.get('selected'); + }); + + return columnIds; + }), + + _selectObserver: Ember.observer('[email protected]', function () { + var selectedCount = 0; + this.get('filteredOptions').forEach(function (option) { + if(Ember.get(option, 'selected')) { + selectedCount++; + } + }); + this.set('selectAll', selectedCount > 0 && selectedCount === this.get('filteredOptions.length')); + }), + + actions: { + selectAll: function (checked) { + this.get('filteredOptions').forEach(function (option) { + Ember.set(option, 'selected', checked); + }); + }, + closeModal: function () { + this.get("targetObject").send("closeModal"); + }, + ok: function () { + this.get("targetObject").send("columnsSelected", this.get("selectedColumnIDs")); + } + } +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/components/dags-page-search.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/components/dags-page-search.js b/tez-ui/src/main/webapp/app/components/dags-page-search.js new file mode 100644 index 0000000..f1cc71b --- /dev/null +++ b/tez-ui/src/main/webapp/app/components/dags-page-search.js @@ -0,0 +1,53 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Ember from 'ember'; + +export default Ember.Component.extend({ + classNames: ['dags-page-search'], + + dagName: Ember.computed.oneWay("tableDefinition.dagName"), + dagID: Ember.computed.oneWay("tableDefinition.dagID"), + submitter: Ember.computed.oneWay("tableDefinition.submitter"), + status: Ember.computed.oneWay("tableDefinition.status"), + appID: Ember.computed.oneWay("tableDefinition.appID"), + callerID: Ember.computed.oneWay("tableDefinition.callerID"), + + sendSearch: function () { + this.get('parentView').sendAction('search', { + dagName: this.get("dagName"), + dagID: this.get("dagID"), + submitter: this.get("submitter"), + status: this.get("status"), + appID: this.get("appID"), + callerID: this.get("callerID"), + }); + }, + + actions: { + statusChanged: function (value) { + this.set("status", value); + }, + statusKeyPress: function () { + this.sendSearch(); + }, + search: function () { + this.sendSearch(); + } + } +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/components/dags-pagination-ui.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/components/dags-pagination-ui.js b/tez-ui/src/main/webapp/app/components/dags-pagination-ui.js new file mode 100644 index 0000000..8d88b45 --- /dev/null +++ b/tez-ui/src/main/webapp/app/components/dags-pagination-ui.js @@ -0,0 +1,106 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Ember from 'ember'; + +export default Ember.Component.extend({ + tableDefinition: null, + dataProcessor: null, + + classNames: ['pagination-ui'], + isVisible: Ember.computed.alias('tableDefinition.enablePagination'), + + atFirst: Ember.computed('tableDefinition.pageNum', function () { + return this.get('tableDefinition.pageNum') === 1; + }), + + rowCountOptions: Ember.computed('tableDefinition.rowCountOptions', 'tableDefinition.rowCount', function () { + var options = this.get('tableDefinition.rowCountOptions'), + rowCount = this.get('tableDefinition.rowCount'); + + return options.map(function (option) { + return { + value: option, + selected: option === rowCount + }; + }); + }), + + _possiblePages: Ember.computed('tableDefinition.pageNum', + 'tableDefinition.moreAvailable', + 'dataProcessor.totalPages', function () { + var pageNum = this.get('tableDefinition.pageNum'), + totalPages = this.get('dataProcessor.totalPages'), + possiblePages = [], + startPage = 1, + endPage = totalPages, + delta = 0; + + if(this.get('tableDefinition.moreAvailable')) { + totalPages++; + } + + if(totalPages > 1) { + startPage = pageNum - 1; + endPage = pageNum + 1; + + if(startPage < 1) { + delta = 1 - startPage; + } + else if(endPage > totalPages) { + delta = totalPages - endPage; + } + + startPage += delta; + endPage += delta; + } + + startPage = Math.max(startPage, 1); + endPage = Math.min(endPage, totalPages); + + while(startPage <= endPage) { + possiblePages.push({ + isCurrent: startPage === pageNum, + isLoadPage: startPage === totalPages, + pageNum: startPage++, + }); + } + + return possiblePages; + }), + + actions: { + rowSelected: function (value) { + value = parseInt(value); + if(this.get('tableDefinition.rowCount') !== value) { + this.get('parentView').send('rowChanged', value); + } + }, + changePage: function (value) { + if(value === 1) { + this.get('parentView').sendAction('reload'); + } + else if(this.get('dataProcessor.totalPages') < value) { + this.get('parentView').sendAction('loadPage', value); + } + else { + this.get('parentView').send('pageChanged', value); + } + }, + } +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/components/date-formatter.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/components/date-formatter.js b/tez-ui/src/main/webapp/app/components/date-formatter.js new file mode 100644 index 0000000..da21383 --- /dev/null +++ b/tez-ui/src/main/webapp/app/components/date-formatter.js @@ -0,0 +1,30 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Ember from 'ember'; + +export default Ember.Component.extend({ + + classNames: ["date-formatter"], + + content: null, + + env: Ember.inject.service('env'), + timeZone: Ember.computed.oneWay('env.app.timeZone'), + +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/components/em-swimlane-blocking-event.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/components/em-swimlane-blocking-event.js b/tez-ui/src/main/webapp/app/components/em-swimlane-blocking-event.js new file mode 100644 index 0000000..a487699 --- /dev/null +++ b/tez-ui/src/main/webapp/app/components/em-swimlane-blocking-event.js @@ -0,0 +1,75 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Ember from 'ember'; + +export default Ember.Component.extend({ + + process: null, + blocking: null, + + processor: null, + + classNames: ["em-swimlane-blocking-event"], + + blockingEvent: Ember.computed("process.blockingEventName", + "[email protected]", function () { + var events = this.get("process.events"), + blockingEventName = this.get("process.blockingEventName"); + + return events.find(function (event) { + return event.name === blockingEventName; + }); + }), + + didInsertElement: Ember.observer("blockingEvent.time", "processor.timeWindow", function () { + var blockTime = this.get("blockingEvent.time"), + blockerEventHeight; + + if(blockTime && this.get("blocking.endEvent.time") >= blockTime) { + blockerEventHeight = (this.get("blocking.index") - this.get("process.index")) * 30; + + Ember.run.later(this, function () { + this.$().css({ + "left": this.get("processor").timeToPositionPercent(blockTime) + "%" + }); + this.$(".event-line").css({ + "height": `${blockerEventHeight}px`, + "border-color": this.get("process").getColor() + }); + }); + } + }), + + sendMouseAction: function (name, mouseEvent) { + this.sendAction(name, "blocking-event", this.get("process"), { + mouseEvent: mouseEvent, + blocking: this.get("blocking"), + blockingEvent: this.get("blockingEvent") + }); + }, + + mouseEnter: function (mouseEvent) { + this.sendMouseAction("showTooltip", mouseEvent); + }, + + mouseLeave: function (mouseEvent) { + this.sendMouseAction("hideTooltip", mouseEvent); + }, + +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/components/em-swimlane-consolidated-process.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/components/em-swimlane-consolidated-process.js b/tez-ui/src/main/webapp/app/components/em-swimlane-consolidated-process.js new file mode 100644 index 0000000..67186dd --- /dev/null +++ b/tez-ui/src/main/webapp/app/components/em-swimlane-consolidated-process.js @@ -0,0 +1,89 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Ember from 'ember'; + +export default Ember.Component.extend({ + + process: null, + processor: null, + focusedProcess: null, + + classNames: ["em-swimlane-consolidated-process"], + classNameBindings: ['focused'], + + focused: Ember.computed("process", "focusedProcess", function () { + return this.get("process") === this.get("focusedProcess"); + }), + + fromPos: Ember.computed("process.consolidateStartTime", "processor.timeWindow", function () { + var time = this.get("process.consolidateStartTime"); + if(time) { + return this.get("processor").timeToPositionPercent(time); + } + }), + + toPos: Ember.computed("process.consolidateEndTime", "processor.timeWindow", function () { + var time = this.get("process.consolidateEndTime"); + if(time) { + return this.get("processor").timeToPositionPercent(time); + } + }), + + didInsertElement: Ember.observer("fromPos", "toPos", function () { + var fromPos = this.get("fromPos"), + toPos = this.get("toPos"), + thisElement = this.$(); + + if(fromPos && toPos) { + thisElement.show(); + thisElement.css({ + left: fromPos + "%", + right: (100 - toPos) + "%", + "background-color": this.get("process").getConsolidateColor(), + "z-index": parseInt(toPos - fromPos) + }); + } + else { + thisElement.hide(); + } + }), + + sendMouseAction: function (name, mouseEvent) { + var fromPos = this.get("fromPos") || 0, + toPos = this.get("toPos") || 0; + + this.sendAction(name, "consolidated-process", this.get("process"), { + mouseEvent: mouseEvent, + contribution: parseInt(toPos - fromPos) + }); + }, + + mouseEnter: function (mouseEvent) { + this.sendMouseAction("showTooltip", mouseEvent); + }, + + mouseLeave: function (mouseEvent) { + this.sendMouseAction("hideTooltip", mouseEvent); + }, + + mouseUp: function (mouseEvent) { + this.sendMouseAction("click", mouseEvent); + } + +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/components/em-swimlane-event-bar.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/components/em-swimlane-event-bar.js b/tez-ui/src/main/webapp/app/components/em-swimlane-event-bar.js new file mode 100644 index 0000000..224489b --- /dev/null +++ b/tez-ui/src/main/webapp/app/components/em-swimlane-event-bar.js @@ -0,0 +1,91 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Ember from 'ember'; + +export default Ember.Component.extend({ + + bar: null, + barIndex: 0, + + process: null, + processor: null, + + classNames: ["em-swimlane-event-bar"], + + fromEvent: Ember.computed("[email protected]", "bar.fromEvent", function () { + var events = this.get("process.events"), + fromEventName = this.get("bar.fromEvent"); + return events.find(function (event) { + return event.name === fromEventName; + }); + }), + toEvent: Ember.computed("[email protected]", "bar.toEvent", function () { + var events = this.get("process.events"), + toEventName = this.get("bar.toEvent"); + return events.find(function (event) { + return event.name === toEventName; + }); + }), + + didInsertElement: Ember.observer("fromEvent.time", "toEvent.time", + "barIndex", "processor.timeWindow", function () { + + var processor = this.get("processor"), + fromEventPos = processor.timeToPositionPercent(this.get("fromEvent.time")), + toEventPos = processor.timeToPositionPercent(this.get("toEvent.time")), + color = this.get("bar.color") || this.get("process").getBarColor(this.get("barIndex")); + + if(fromEventPos && toEventPos) { + Ember.run.later(this, function () { + this.$().show(); + this.$(".event-bar").css({ + left: fromEventPos + "%", + right: (100 - toEventPos) + "%", + "background-color": color, + "border-color": this.get("process").getColor() + }); + }); + } + else { + this.$().hide(); + } + }), + + sendMouseAction: function (name, mouseEvent) { + this.sendAction(name, "event-bar", this.get("process"), { + mouseEvent: mouseEvent, + bar: this.get("bar"), + fromEvent: this.get("fromEvent"), + toEvent: this.get("toEvent") + }); + }, + + mouseEnter: function (mouseEvent) { + this.sendMouseAction("showTooltip", mouseEvent); + }, + + mouseLeave: function (mouseEvent) { + this.sendMouseAction("hideTooltip", mouseEvent); + }, + + mouseUp: function (mouseEvent) { + this.sendMouseAction("click", mouseEvent); + } + +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/components/em-swimlane-event.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/components/em-swimlane-event.js b/tez-ui/src/main/webapp/app/components/em-swimlane-event.js new file mode 100644 index 0000000..4eef7f0 --- /dev/null +++ b/tez-ui/src/main/webapp/app/components/em-swimlane-event.js @@ -0,0 +1,62 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Ember from 'ember'; + +export default Ember.Component.extend({ + + process: null, + event: null, + + processor: null, + + classNames: ["em-swimlane-event"], + + didInsertElement: Ember.observer("event.time", "processor.timeWindow", function () { + var color = this.get("process").getColor(); + + this.$(".event-line").css("border-color", color); + this.$(".event-bubble").css("border-color", color); + + Ember.run.later(this, function () { + this.$().css({ + "left": this.get("processor").timeToPositionPercent(this.get("event.time")) + "%" + }); + }); + }), + + sendMouseAction: function (name, mouseEvent) { + this.sendAction(name, "event", this.get("process"), { + mouseEvent: mouseEvent, + events: [this.get("event")] + }); + }, + + mouseEnter: function (mouseEvent) { + this.sendMouseAction("showTooltip", mouseEvent); + }, + + mouseLeave: function (mouseEvent) { + this.sendMouseAction("hideTooltip", mouseEvent); + }, + + mouseUp: function (mouseEvent) { + this.sendMouseAction("click", mouseEvent); + } + +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/components/em-swimlane-process-line.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/components/em-swimlane-process-line.js b/tez-ui/src/main/webapp/app/components/em-swimlane-process-line.js new file mode 100644 index 0000000..2d6e2b6 --- /dev/null +++ b/tez-ui/src/main/webapp/app/components/em-swimlane-process-line.js @@ -0,0 +1,60 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Ember from 'ember'; + +export default Ember.Component.extend({ + + process: null, + processor: null, + + didInsertElement: Ember.observer("process.startEvent.time", + "process.endEvent.time", "processor.timeWindow", function () { + var processor = this.get("processor"), + startPos = processor.timeToPositionPercent(this.get("process.startEvent.time")), + endPos = processor.timeToPositionPercent(this.get("process.endEvent.time")); + + Ember.run.later(this, function () { + this.$(".process-line").css({ + left: startPos + "%", + right: (100 - endPos) + "%", + "background-color": this.get("process").getColor() + }); + }); + }), + + sendMouseAction: function (name, mouseEvent) { + this.sendAction(name, "process-line", this.get("process"), { + mouseEvent: mouseEvent, + }); + }, + + mouseEnter: function (mouseEvent) { + this.sendMouseAction("showTooltip", mouseEvent); + }, + + mouseLeave: function (mouseEvent) { + this.sendMouseAction("hideTooltip", mouseEvent); + }, + + mouseUp: function (mouseEvent) { + this.sendMouseAction("click", mouseEvent); + } + + +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/components/em-swimlane-process-name.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/components/em-swimlane-process-name.js b/tez-ui/src/main/webapp/app/components/em-swimlane-process-name.js new file mode 100644 index 0000000..eea897d --- /dev/null +++ b/tez-ui/src/main/webapp/app/components/em-swimlane-process-name.js @@ -0,0 +1,45 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Ember from 'ember'; + +export default Ember.Component.extend({ + + process: null, + + classNames: ["em-swimlane-process-name"], + + sendMouseAction: function (name, mouseEvent) { + this.sendAction(name, "process-name", this.get("process"), { + mouseEvent: mouseEvent, + }); + }, + + mouseEnter: function (mouseEvent) { + this.sendMouseAction("showTooltip", mouseEvent); + }, + + mouseLeave: function (mouseEvent) { + this.sendMouseAction("hideTooltip", mouseEvent); + }, + + mouseUp: function (mouseEvent) { + this.sendMouseAction("click", mouseEvent); + } + +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/components/em-swimlane-process-visual.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/components/em-swimlane-process-visual.js b/tez-ui/src/main/webapp/app/components/em-swimlane-process-visual.js new file mode 100644 index 0000000..aa555cd --- /dev/null +++ b/tez-ui/src/main/webapp/app/components/em-swimlane-process-visual.js @@ -0,0 +1,66 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Ember from 'ember'; + +const BUBBLE_DIA = 10; // Same as that in css + +export default Ember.Component.extend({ + + process: null, + processor: null, + focusedProcess: null, + + classNames: ["em-swimlane-process-visual"], + + actions: { + showTooltip: function(type, process, options) { + + if(type === "event") { + let clientX = options.mouseEvent.clientX, + events = process.get("events"), + eventsUnderMouse = []; + + this.$(".em-swimlane-event").each(function (index) { + var offsetLeft = Ember.$(this).offset().left; + + if(clientX >= offsetLeft - BUBBLE_DIA && clientX <= offsetLeft + BUBBLE_DIA) { + eventsUnderMouse.push(events[index]); + } + }); + + if(events.length) { + eventsUnderMouse.sort(function (eventA, eventB) { + return eventA.time - eventB.time; + }); + options.events = eventsUnderMouse; + } + } + + this.sendAction("showTooltip", type, process, options); + }, + + hideTooltip: function(type, process, options) { + this.sendAction("hideTooltip", type, process, options); + }, + click: function (type, process, options) { + this.sendAction("click", type, process, options); + } + } + +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/components/em-swimlane-ruler.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/components/em-swimlane-ruler.js b/tez-ui/src/main/webapp/app/components/em-swimlane-ruler.js new file mode 100644 index 0000000..4d1b933 --- /dev/null +++ b/tez-ui/src/main/webapp/app/components/em-swimlane-ruler.js @@ -0,0 +1,98 @@ +/** + * 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 moment from 'moment'; + +const DEFAULT_MARK_COUNT = 10; + +export default Ember.Component.extend({ + + zoom: null, + processor: null, + scroll: 0, + + classNames: ["em-swimlane-ruler"], + + markDef: Ember.computed("processor.timeWindow", "zoom", function () { + var markCount = parseInt(DEFAULT_MARK_COUNT * this.get("zoom") / 100), + timeWindow = this.get("processor.timeWindow"), + duration = moment.duration(parseInt(timeWindow / markCount)), + + markUnit = "Milliseconds", + markBaseValue = 0, + markWindow = 0, + styleWidth = 0; + + if(markBaseValue = duration.years()) { + markUnit = "Years"; + } + else if(markBaseValue = duration.months()) { + markUnit = "Months"; + } + else if(markBaseValue = duration.days()) { + markUnit = "Days"; + } + else if(markBaseValue = duration.hours()) { + markUnit = "Hours"; + } + else if(markBaseValue = duration.minutes()) { + markUnit = "Minutes"; + } + else if(markBaseValue = duration.seconds()) { + markUnit = "Seconds"; + } + else { + markBaseValue = duration.milliseconds(); + } + + if(markBaseValue > 10) { + markBaseValue = Math.floor(markBaseValue / 10) * 10; + } + + markWindow = moment.duration(markBaseValue, markUnit.toLowerCase()).asMilliseconds(); + styleWidth = markWindow / timeWindow * 100; + + return { + unit: markUnit, + baseValue: markBaseValue, + style: Ember.String.htmlSafe(`width: ${styleWidth}%;`), + count: parseInt(100 / styleWidth * 1.1) + }; + }), + + unitTextStyle: Ember.computed("scroll", function () { + var scroll = this.get("scroll"); + return Ember.String.htmlSafe(`left: ${scroll}px;`); + }), + + marks: Ember.computed("processor.timeWindow", "markDef", function () { + var def = this.get("markDef"), + baseValue = def.baseValue, + marks = []; + + for(var i=0, count = def.count; i < count; i++) { + marks.push({ + duration: parseInt(baseValue * i) + }); + } + + return marks; + }) + +}); http://git-wip-us.apache.org/repos/asf/tez/blob/13132ec7/tez-ui/src/main/webapp/app/components/em-swimlane-vertex-name.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/components/em-swimlane-vertex-name.js b/tez-ui/src/main/webapp/app/components/em-swimlane-vertex-name.js new file mode 100644 index 0000000..36a7bbc --- /dev/null +++ b/tez-ui/src/main/webapp/app/components/em-swimlane-vertex-name.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'; + +const MAX_TEXT_LENGTH = 10; + +export default Ember.Component.extend({ + + process: null, + + classNames: ["em-swimlane-vertex-name"], + + sendMouseAction: function (name, mouseEvent) { + this.sendAction(name, "process-name", this.get("process"), { + mouseEvent: mouseEvent, + }); + }, + + progressText: Ember.computed("process.vertex.finalStatus", "process.vertex.progress", function () { + if(this.get("process.vertex.finalStatus") === "RUNNING") { + let progress = this.get("process.vertex.progress"); + if(!isNaN(progress)) { + let percent = parseInt(progress * 100); + return `${percent}%`; + } + } + }), + + useEllipsis: Ember.computed("process.name", "progressText", function () { + var name = this.get("process.name") || "", + progressLength = this.get("progressText.length"); + progressLength = progressLength ? progressLength + 1 : 0; + return name.length + progressLength - 1 > MAX_TEXT_LENGTH; + }), + + processName: Ember.computed("process.name", "progressText", function () { + var name = this.get("process.name") || "", + progressLength = this.get("progressText.length"); + progressLength = progressLength ? progressLength + 1 : 0; + return name.substr(Math.max(name.length - MAX_TEXT_LENGTH - progressLength, 0)); + }), + + mouseEnter: function (mouseEvent) { + this.sendMouseAction("showTooltip", mouseEvent); + }, + + mouseLeave: function (mouseEvent) { + this.sendMouseAction("hideTooltip", mouseEvent); + }, + + mouseUp: function (mouseEvent) { + this.sendMouseAction("click", mouseEvent); + } + +});
