Repository: tez Updated Branches: refs/heads/master e84c1aa7a -> 3a45508b9
TEZ-1946. Tez UI: add source & sink views, add counters to vertices/all task views (Sreenath Somarajapuram via rbalamohan) Project: http://git-wip-us.apache.org/repos/asf/tez/repo Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/3a45508b Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/3a45508b Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/3a45508b Branch: refs/heads/master Commit: 3a45508b92f4863a9b53a329d8522b9900e397f0 Parents: e84c1aa Author: Rajesh Balamohan <[email protected]> Authored: Thu Jan 29 18:07:11 2015 +0530 Committer: Rajesh Balamohan <[email protected]> Committed: Thu Jan 29 18:07:11 2015 +0530 ---------------------------------------------------------------------- CHANGES.txt | 1 + tez-ui/src/main/webapp/app/scripts/app.js | 9 + tez-ui/src/main/webapp/app/scripts/configs.js | 15 +- .../app/scripts/controllers/dag_vertices.js | 27 +- .../vertex-additionals-controller.js | 108 ++++++++ .../scripts/controllers/vertex_controller.js | 2 +- .../main/webapp/app/scripts/default-configs.js | 275 ++++++++++++++++--- .../main/webapp/app/scripts/helpers/dialogs.js | 2 +- .../src/main/webapp/app/scripts/helpers/misc.js | 19 +- .../app/scripts/models/TimelineRestAdapter.js | 68 ++++- .../src/main/webapp/app/scripts/models/dag.js | 14 +- tez-ui/src/main/webapp/app/scripts/router.js | 31 ++- tez-ui/src/main/webapp/app/styles/colors.less | 36 +++ tez-ui/src/main/webapp/app/styles/main.less | 30 +- tez-ui/src/main/webapp/app/styles/shared.less | 42 +++ .../webapp/app/templates/common/configs.hbs | 29 +- .../main/webapp/app/templates/input/configs.hbs | 42 +++ .../webapp/app/templates/output/configs.hbs | 39 +++ .../webapp/app/templates/partials/configs.hbs | 27 ++ .../webapp/app/templates/vertex/additionals.hbs | 45 +++ .../main/webapp/app/templates/vertex/inputs.hbs | 36 --- 21 files changed, 733 insertions(+), 164 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index 9e64a0b..cae1af9 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -54,6 +54,7 @@ Release 0.6.1: Unreleased INCOMPATIBLE CHANGES ALL CHANGES: + TEZ-1946. Tez UI: add source & sink views, add counters to vertices/all task views. TEZ-1987. Tez UI non-standalone mode uses invalid protocol. TEZ-1983. Tez UI swimlane task attempt link is broken http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/scripts/app.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/scripts/app.js b/tez-ui/src/main/webapp/app/scripts/app.js index fe2ea4d..5beb815 100644 --- a/tez-ui/src/main/webapp/app/scripts/app.js +++ b/tez-ui/src/main/webapp/app/scripts/app.js @@ -31,6 +31,11 @@ var App = window.App = Em.Application.createWithMixins(Bootstrap, { env: { isStandalone: true // Can ne set false in the wrapper initializer + }, + + setConfigs: function (configs) { + App.Helpers.misc.merge(App.Configs, configs); + App.advanceReadiness(); } }); App.deferReadiness(); @@ -72,6 +77,9 @@ App.ready = function () { if(vertexData && vertexData.additionalInputs) { data.inputs = vertexData.additionalInputs; } + if(vertexData && vertexData.additionalOutputs) { + data.outputs = vertexData.additionalOutputs; + } } return data; }); @@ -115,4 +123,5 @@ require('scripts/models/**/*'); require('scripts/controllers/**/*'); require('scripts/components/*'); +require('scripts/components/dag-view/*'); require('scripts/adapters/*'); http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/scripts/configs.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/scripts/configs.js b/tez-ui/src/main/webapp/app/scripts/configs.js index d07965d..b0397d8 100644 --- a/tez-ui/src/main/webapp/app/scripts/configs.js +++ b/tez-ui/src/main/webapp/app/scripts/configs.js @@ -16,7 +16,7 @@ * limitations under the License. */ -$.extend(true, App.Configs, { +App.setConfigs({ /* Environment configurations */ envDefaults: { @@ -39,10 +39,11 @@ $.extend(true, App.Configs, { * as columns edit the following 'tables' object. Counters must be added as configuration objects * of the following format. * { - * counterId: '<Counter ID>', - * groupId: '<Group ID>', - * headerText: '<Display text>' + * counterName: '<Counter ID>', + * counterGroupName: '<Group ID>', * } + * + * Note: Till 0.6.0 the properties were counterId and groupId, their use is deprecated now. */ tables: { /* @@ -51,9 +52,8 @@ $.extend(true, App.Configs, { entity: { dag: [ // { // Following is a sample configuration object. - // counterId: 'FILE_BYTES_READ', - // groupId: 'org.apache.tez.common.counters.FileSystemCounter', - // headerText: 'File Bytes Read' + // counterName: 'FILE_BYTES_READ', + // counterGroupName: 'org.apache.tez.common.counters.FileSystemCounter', // } ], vertex: [], @@ -69,4 +69,3 @@ $.extend(true, App.Configs, { }); -App.advanceReadiness(); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/scripts/controllers/dag_vertices.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/scripts/controllers/dag_vertices.js b/tez-ui/src/main/webapp/app/scripts/controllers/dag_vertices.js index 8e3a2d4..c50280e 100644 --- a/tez-ui/src/main/webapp/app/scripts/controllers/dag_vertices.js +++ b/tez-ui/src/main/webapp/app/scripts/controllers/dag_vertices.js @@ -127,23 +127,28 @@ App.DagVerticesController = Em.ObjectController.extend(App.PaginatedContentMixin }, { id: 'configurations', - headerCellName: 'Input Configurations', + headerCellName: 'Source/Sink Configs', tableCellViewClass: Em.Table.TableCell.extend({ template: Em.Handlebars.compile( - " {{#if view.cellContent.inputId}}\ - {{#if view.cellContent.showConfigs}}\ - {{#link-to 'vertexInput.configs' view.cellContent.vertexId view.cellContent.inputId class='ember-table-content'}}View configurations{{/link-to}}\ - {{else}}\ - {{#link-to 'vertex.inputs' view.cellContent.vertexId class='ember-table-content'}}View Inputs{{/link-to}}\ - {{/if}}\ + " {{#if view.cellContent.linkToAdditionals}}\ + {{#link-to 'vertex.additionals' view.cellContent.vertexId class='ember-table-content'}}View sources & sinks{{/link-to}}\ + {{else}}{{#if view.cellContent.inputId}}\ + {{#link-to 'input.configs' view.cellContent.vertexId view.cellContent.inputId class='ember-table-content'}}View source configs{{/link-to}}\ + {{else}}{{#if view.cellContent.outputId}}\ + {{#link-to 'output.configs' view.cellContent.vertexId view.cellContent.outputId class='ember-table-content'}}View sink configs{{/link-to}}\ {{else}}\ - <span class='ember-table-content'>No Inputs</span>\ - {{/if}}") + <span class='ember-table-content'>No source or sink</span>\ + {{/if}}{{/if}}{{/if}}") }), getCellContent: function(row) { + var firstInputId = row.get('inputs.content.0.id'), + firstOutputId = row.get('outputs.content.0.id'); return { - showConfigs: row.get('inputs.content.length') == 1 && row.get('inputs.content.0.configs.length') > 0, - inputId: row.get('inputs.content.0.id'), + linkToAdditionals: row.get('inputs.content.length') > 1 || + row.get('outputs.content.length') > 1 || + (firstInputId != undefined && firstOutputId != undefined), + inputId: firstInputId, + outputId: firstOutputId, vertexId: row.get('id') }; } http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/scripts/controllers/vertex-additionals-controller.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/scripts/controllers/vertex-additionals-controller.js b/tez-ui/src/main/webapp/app/scripts/controllers/vertex-additionals-controller.js new file mode 100644 index 0000000..61c2616 --- /dev/null +++ b/tez-ui/src/main/webapp/app/scripts/controllers/vertex-additionals-controller.js @@ -0,0 +1,108 @@ +/** + * 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.VertexAdditionalsController = Em.ObjectController.extend({ + needs: 'vertex', + + controllerName: 'VertexAdditionalsController', + + loadEntities: function() { + var inputs = this.get('inputs.content'), + outputs = this.get('outputs.content'); + + this.set('inputContent', inputs); + this.set('inputsAvailable', inputs.length > 0); + + this.set('outputContent', outputs); + this.set('outputsAvailable', outputs.length > 0); + + this.set('loading', false); + }, + + inputColumns: function() { + return App.Helpers.misc.createColumnsFromConfigs([ + { + id: 'inputId', + headerCellName: 'Name', + contentPath: 'inputName', + }, + { + id: 'inputClass', + headerCellName: 'Class', + contentPath: 'inputClass', + }, + { + id: 'inputInitializer', + headerCellName: 'Initializer', + contentPath: 'inputInitializer', + }, + { + id: 'configurations', + headerCellName: 'Configurations', + tableCellViewClass: Em.Table.TableCell.extend({ + template: Em.Handlebars.compile( + "{{#if view.cellContent.count}}\ + {{#link-to 'input.configs' view.cellContent.id class='ember-table-content'}}View Configurations{{/link-to}}\ + {{else}}\ + <span class='ember-table-content'>Not Available</span>\ + {{/if}}") + }), + getCellContent: function(row) { + return { + count: row.get('configs.content.length'), + id: row.get('id') + }; + } + } + ]); + }.property(), + + outputColumns: function() { + return App.Helpers.misc.createColumnsFromConfigs([ + { + id: 'outputId', + headerCellName: 'Name', + contentPath: 'outputName', + }, + { + id: 'outputClass', + headerCellName: 'Class', + contentPath: 'outputClass', + }, + { + id: 'configurations', + headerCellName: 'Configurations', + tableCellViewClass: Em.Table.TableCell.extend({ + template: Em.Handlebars.compile( + "{{#if view.cellContent.count}}\ + {{#link-to 'output.configs' view.cellContent.id class='ember-table-content'}}View Configurations{{/link-to}}\ + {{else}}\ + <span class='ember-table-content'>Not Available</span>\ + {{/if}}") + }), + getCellContent: function(row) { + return { + count: row.get('configs.content.length'), + id: row.get('id') + }; + } + } + ]); + }.property(), + +}); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/scripts/controllers/vertex_controller.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/scripts/controllers/vertex_controller.js b/tez-ui/src/main/webapp/app/scripts/controllers/vertex_controller.js index 7e05eba..1c20b3e 100644 --- a/tez-ui/src/main/webapp/app/scripts/controllers/vertex_controller.js +++ b/tez-ui/src/main/webapp/app/scripts/controllers/vertex_controller.js @@ -33,6 +33,6 @@ App.VertexController = Em.ObjectController.extend(App.Helpers.DisplayHelper, { Ember.Object.create({title: 'Task Attempts', linkTo: 'vertex.taskAttempts'}), Ember.Object.create({title: 'Counters', linkTo: 'vertex.counters'}), Ember.Object.create({title: 'Swimlane', linkTo: 'vertex.swimlane'}), - Ember.Object.create({title: 'Inputs', linkTo: 'vertex.inputs'}), + Ember.Object.create({title: 'Sources & Sinks', linkTo: 'vertex.additionals'}), ], }); http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/scripts/default-configs.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/scripts/default-configs.js b/tez-ui/src/main/webapp/app/scripts/default-configs.js index 48da014..eba6a7e 100644 --- a/tez-ui/src/main/webapp/app/scripts/default-configs.js +++ b/tez-ui/src/main/webapp/app/scripts/default-configs.js @@ -43,57 +43,270 @@ $.extend(true, App.Configs, { applicationHistory: 'ws/v1/applicationhistory' }, + tables: { + entity: { + dag: [ + // DAG Counters + { + counterName :"NUM_FAILED_TASKS", + counterGroupName :"org.apache.tez.common.counters.DAGCounter", + }, + { + counterName :"NUM_KILLED_TASKS", + counterGroupName :"org.apache.tez.common.counters.DAGCounter", + }, + { + counterName :"NUM_SUCCEEDED_TASKS", + counterGroupName :"org.apache.tez.common.counters.DAGCounter", + }, + { + counterName :"TOTAL_LAUNCHED_TASKS", + counterGroupName :"org.apache.tez.common.counters.DAGCounter", + }, + { + counterName :"OTHER_LOCAL_TASKS", + counterGroupName :"org.apache.tez.common.counters.DAGCounter", + }, + { + counterName :"DATA_LOCAL_TASKS", + counterGroupName :"org.apache.tez.common.counters.DAGCounter", + }, + { + counterName :"RACK_LOCAL_TASKS", + counterGroupName :"org.apache.tez.common.counters.DAGCounter", + }, + { + counterName :"SLOTS_MILLIS_TASKS", + counterGroupName :"org.apache.tez.common.counters.DAGCounter", + }, + { + counterName :"FALLOW_SLOTS_MILLIS_TASKS", + counterGroupName :"org.apache.tez.common.counters.DAGCounter", + }, + { + counterName :"TOTAL_LAUNCHED_UBERTASKS", + counterGroupName :"org.apache.tez.common.counters.DAGCounter", + }, + { + counterName :"NUM_UBER_SUBTASKS", + counterGroupName :"org.apache.tez.common.counters.DAGCounter", + }, + { + counterName :"NUM_FAILED_UBERTASKS", + counterGroupName :"org.apache.tez.common.counters.DAGCounter", + }, + + { + counterName: "REDUCE_OUTPUT_RECORDS", + counterGroupName: "REDUCE_OUTPUT_RECORDS", + }, + { + counterName: "REDUCE_SKIPPED_GROUPS", + counterGroupName: "REDUCE_SKIPPED_GROUPS", + }, + { + counterName: "REDUCE_SKIPPED_RECORDS", + counterGroupName: "REDUCE_SKIPPED_RECORDS", + }, + { + counterName: "COMBINE_OUTPUT_RECORDS", + counterGroupName: "COMBINE_OUTPUT_RECORDS", + }, + { + counterName: "SKIPPED_RECORDS", + counterGroupName: "SKIPPED_RECORDS", + }, + { + counterName: "INPUT_GROUPS", + counterGroupName: "INPUT_GROUPS", + } + ] + } + }, + defaultCounters: [ // File System Counters { - counterId: 'FILE_BYTES_READ', - groupId: 'org.apache.tez.common.counters.FileSystemCounter', - headerText: 'File Bytes Read' + counterName: 'FILE_BYTES_READ', + counterGroupName: 'org.apache.tez.common.counters.FileSystemCounter', }, { - counterId: 'FILE_BYTES_WRITTEN', - groupId: 'org.apache.tez.common.counters.FileSystemCounter', - headerText: 'File Bytes Written' + counterName: 'FILE_BYTES_WRITTEN', + counterGroupName: 'org.apache.tez.common.counters.FileSystemCounter', }, { - counterId: 'FILE_READ_OPS', - groupId: 'org.apache.tez.common.counters.FileSystemCounter', - headerText: 'File Read Ops' + counterName: 'FILE_READ_OPS', + counterGroupName: 'org.apache.tez.common.counters.FileSystemCounter', }, { - counterId: 'FILE_LARGE_READ_OPS', - groupId: 'org.apache.tez.common.counters.FileSystemCounter', - headerText: 'File Large Read Ops' + counterName: 'FILE_LARGE_READ_OPS', + counterGroupName: 'org.apache.tez.common.counters.FileSystemCounter', }, { - counterId: 'FILE_WRITE_OPS', - groupId: 'org.apache.tez.common.counters.FileSystemCounter', - headerText: 'File Write Ops' + counterName: 'FILE_WRITE_OPS', + counterGroupName: 'org.apache.tez.common.counters.FileSystemCounter', }, { - counterId: 'HDFS_BYTES_READ', - groupId: 'org.apache.tez.common.counters.FileSystemCounter', - headerText: 'HDFS Bytes Read' + counterName: 'HDFS_BYTES_READ', + counterGroupName: 'org.apache.tez.common.counters.FileSystemCounter', }, { - counterId: 'HDFS_BYTES_WRITTEN', - groupId: 'org.apache.tez.common.counters.FileSystemCounter', - headerText: 'HDFS Bytes Written' + counterName: 'HDFS_BYTES_WRITTEN', + counterGroupName: 'org.apache.tez.common.counters.FileSystemCounter', }, { - counterId: 'HDFS_READ_OPS', - groupId: 'org.apache.tez.common.counters.FileSystemCounter', - headerText: 'HDFS Read Ops' + counterName: 'HDFS_READ_OPS', + counterGroupName: 'org.apache.tez.common.counters.FileSystemCounter', }, { - counterId: 'HDFS_LARGE_READ_OPS', - groupId: 'org.apache.tez.common.counters.FileSystemCounter', - headerText: 'HDFS Large Read Ops' + counterName: 'HDFS_LARGE_READ_OPS', + counterGroupName: 'org.apache.tez.common.counters.FileSystemCounter', }, { - counterId: 'HDFS_WRITE_OPS', - groupId: 'org.apache.tez.common.counters.FileSystemCounter', - headerText: 'HDFS Write Ops' - } + counterName: 'HDFS_WRITE_OPS', + counterGroupName: 'org.apache.tez.common.counters.FileSystemCounter', + }, + + // Task Counters + { + counterName: "NUM_SPECULATIONS", + counterGroupName: "org.apache.tez.common.counters.TaskCounter", + }, + { + counterName: "REDUCE_INPUT_GROUPS", + counterGroupName: "org.apache.tez.common.counters.TaskCounter", + }, + { + counterName: "REDUCE_INPUT_RECORDS", + counterGroupName: "org.apache.tez.common.counters.TaskCounter", + }, + { + counterName: "SPLIT_RAW_BYTES", + counterGroupName: "org.apache.tez.common.counters.TaskCounter", + }, + { + counterName: "COMBINE_INPUT_RECORDS", + counterGroupName: "org.apache.tez.common.counters.TaskCounter", + }, + { + counterName: "SPILLED_RECORDS", + counterGroupName: "org.apache.tez.common.counters.TaskCounter", + }, + { + counterName: "NUM_SHUFFLED_INPUTS", + counterGroupName: "org.apache.tez.common.counters.TaskCounter", + }, + { + counterName: "NUM_SKIPPED_INPUTS", + counterGroupName: "org.apache.tez.common.counters.TaskCounter", + }, + { + counterName: "NUM_FAILED_SHUFFLE_INPUTS", + counterGroupName: "org.apache.tez.common.counters.TaskCounter", + }, + { + counterName: "MERGED_MAP_OUTPUTS", + counterGroupName: "org.apache.tez.common.counters.TaskCounter", + }, + { + counterName: "GC_TIME_MILLIS", + counterGroupName: "org.apache.tez.common.counters.TaskCounter", + }, + { + counterName: "CPU_MILLISECONDS", + counterGroupName: "org.apache.tez.common.counters.TaskCounter", + }, + { + counterName: "PHYSICAL_MEMORY_BYTES", + counterGroupName: "org.apache.tez.common.counters.TaskCounter", + }, + { + counterName: "VIRTUAL_MEMORY_BYTES", + counterGroupName: "org.apache.tez.common.counters.TaskCounter", + }, + { + counterName: "COMMITTED_HEAP_BYTES", + counterGroupName: "org.apache.tez.common.counters.TaskCounter", + }, + { + counterName: "INPUT_RECORDS_PROCESSED", + counterGroupName: "org.apache.tez.common.counters.TaskCounter", + }, + { + counterName: "OUTPUT_RECORDS", + counterGroupName: "org.apache.tez.common.counters.TaskCounter", + }, + { + counterName: "OUTPUT_LARGE_RECORDS", + counterGroupName: "org.apache.tez.common.counters.TaskCounter", + }, + { + counterName: "OUTPUT_BYTES", + counterGroupName: "org.apache.tez.common.counters.TaskCounter", + }, + { + counterName: "OUTPUT_BYTES_WITH_OVERHEAD", + counterGroupName: "org.apache.tez.common.counters.TaskCounter", + }, + { + counterName: "OUTPUT_BYTES_PHYSICAL", + counterGroupName: "org.apache.tez.common.counters.TaskCounter", + }, + { + counterName: "ADDITIONAL_SPILLS_BYTES_WRITTEN", + counterGroupName: "org.apache.tez.common.counters.TaskCounter", + }, + { + counterName: "ADDITIONAL_SPILLS_BYTES_READ", + counterGroupName: "org.apache.tez.common.counters.TaskCounter", + }, + { + counterName: "ADDITIONAL_SPILL_COUNT", + counterGroupName: "org.apache.tez.common.counters.TaskCounter", + }, + { + counterName: "SHUFFLE_BYTES", + counterGroupName: "org.apache.tez.common.counters.TaskCounter", + }, + { + counterName: "SHUFFLE_BYTES_DECOMPRESSED", + counterGroupName: "org.apache.tez.common.counters.TaskCounter", + }, + { + counterName: "SHUFFLE_BYTES_TO_MEM", + counterGroupName: "org.apache.tez.common.counters.TaskCounter", + }, + { + counterName: "SHUFFLE_BYTES_TO_DISK", + counterGroupName: "org.apache.tez.common.counters.TaskCounter", + }, + { + counterName: "SHUFFLE_BYTES_DISK_DIRECT", + counterGroupName: "org.apache.tez.common.counters.TaskCounter", + }, + { + counterName: "NUM_MEM_TO_DISK_MERGES", + counterGroupName: "org.apache.tez.common.counters.TaskCounter", + }, + { + counterName: "NUM_DISK_TO_DISK_MERGES", + counterGroupName: "org.apache.tez.common.counters.TaskCounter", + }, + { + counterName: "SHUFFLE_PHASE_TIME", + counterGroupName: "org.apache.tez.common.counters.TaskCounter", + }, + { + counterName: "MERGE_PHASE_TIME", + counterGroupName: "org.apache.tez.common.counters.TaskCounter", + }, + { + counterName: "FIRST_EVENT_RECEIVED", + counterGroupName: "org.apache.tez.common.counters.TaskCounter", + }, + { + counterName: "LAST_EVENT_RECEIVED", + counterGroupName: "org.apache.tez.common.counters.TaskCounter", + }, ] }); http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/scripts/helpers/dialogs.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/scripts/helpers/dialogs.js b/tez-ui/src/main/webapp/app/scripts/helpers/dialogs.js index 253c8ab..4acd082 100644 --- a/tez-ui/src/main/webapp/app/scripts/helpers/dialogs.js +++ b/tez-ui/src/main/webapp/app/scripts/helpers/dialogs.js @@ -41,7 +41,7 @@ App.Dialogs = Em.Namespace.create({ var id = getProperty(item, 'id'), displayText = getProperty(item, 'displayText'); - listHTML += '<li><input id=%@ type="checkbox" %@ /> %@</li>'.fmt( + listHTML += '<li class="no-wrap"><input id=%@ type="checkbox" %@ /> %@</li>'.fmt( id, selectedItems[id] ? 'checked' : '', displayText http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/scripts/helpers/misc.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/scripts/helpers/misc.js b/tez-ui/src/main/webapp/app/scripts/helpers/misc.js index 07de80a..69f0037 100644 --- a/tez-ui/src/main/webapp/app/scripts/helpers/misc.js +++ b/tez-ui/src/main/webapp/app/scripts/helpers/misc.js @@ -81,8 +81,9 @@ App.Helpers.misc = { */ normalizeCounterConfigs: function (counterConfigs) { return counterConfigs.map(function (configuration) { - configuration.headerCellName = configuration.headerCellName || configuration.counterId; - configuration.id = '%@/%@'.fmt(configuration.groupId, configuration.counterId), + configuration.headerCellName = configuration.counterName || configuration.counterId; + configuration.id = '%@/%@'.fmt(configuration.counterGroupName || configuration.groupId, + configuration.counterName || configuration.counterId), configuration.getCellContent = App.Helpers.misc.getCounterCellContent; return configuration; }); @@ -153,6 +154,20 @@ App.Helpers.misc = { }; }, + merge: function objectMerge(obj1, obj2) { + $.each(obj2, function (key, val) { + if(Array.isArray(obj1[key]) && Array.isArray(val)) { + $.merge(obj1[key], val); + } + else if($.isPlainObject(obj1[key]) && $.isPlainObject(val)) { + objectMerge(obj1[key], val); + } + else { + obj1[key] = val; + } + }); + }, + dagStatusUIOptions: [ { label: 'All', id: null }, { label: 'Submitted', id: 'SUBMITTED' }, http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/scripts/models/TimelineRestAdapter.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/scripts/models/TimelineRestAdapter.js b/tez-ui/src/main/webapp/app/scripts/models/TimelineRestAdapter.js index d5d5858..6794e7d 100644 --- a/tez-ui/src/main/webapp/app/scripts/models/TimelineRestAdapter.js +++ b/tez-ui/src/main/webapp/app/scripts/models/TimelineRestAdapter.js @@ -75,7 +75,7 @@ App.TimelineSerializer = DS.RESTSerializer.extend({ var c = { id: cg.id + '/' + counter.counterName, name: counter.counterName, - displayName: counter.counterDisplayName, + displayName: counter.counterName, value: counter.counterValue, parentID: cg.id }; @@ -281,6 +281,7 @@ var timelineJsonToVertexMap = { processorClassName: 'processorClassName', counterGroups: 'counterGroups', inputs: 'inputs', + outputs: 'outputs', startTime: 'otherinfo.startTime', endTime: 'otherinfo.endTime', @@ -312,8 +313,10 @@ App.VertexSerializer = App.TimelineSerializer.extend({ var normalizedCounterGroupData = this.normalizeCounterGroupsHelper('vertex', vertex.entity, vertex), processorClassName = Ember.get(vertex, 'otherinfo.processorClassName'), - vertexInputs = [], - inputIds = []; + inputs = [], + inputIds = [], + outputs = [], + outputIds = []; vertex.processorClassName = processorClassName.substr(processorClassName.lastIndexOf('.') + 1), vertex.counterGroups = normalizedCounterGroupData.counterGroupsIDs; @@ -324,15 +327,25 @@ App.VertexSerializer = App.TimelineSerializer.extend({ vertex.inputs.forEach(function (input, index) { input.entity = vertex.entity + '-input' + index; inputIds.push(input.entity); - vertexInputs.push(input); + inputs.push(input); }); vertex.inputs = inputIds; } + if(vertex.outputs) { + vertex.outputs.forEach(function (output, index) { + output.entity = vertex.entity + '-output' + index; + outputIds.push(output.entity); + outputs.push(output); + }); + vertex.outputs = outputIds; + } + return { vertex: vertex, counterGroups: normalizedCounterGroupData.counterGroups, - vertexInputs: vertexInputs, + inputs: inputs, + outputs: outputs, counters: normalizedCounterGroupData.counters }; }, @@ -342,7 +355,8 @@ App.VertexSerializer = App.TimelineSerializer.extend({ var normalizedPayload = { vertices: [], counterGroups: [], - vertexInputs: [], + inputs: [], + outputs: [], counters: [] }; rawPayload.vertices.forEach(function(vertex){ @@ -350,7 +364,8 @@ App.VertexSerializer = App.TimelineSerializer.extend({ normalizedPayload.vertices.push(n.vertex); [].push.apply(normalizedPayload.counterGroups, n.counterGroups); [].push.apply(normalizedPayload.counters, n.counters); - [].push.apply(normalizedPayload.vertexInputs, n.vertexInputs); + [].push.apply(normalizedPayload.inputs, n.inputs); + [].push.apply(normalizedPayload.outputs, n.outputs); }, this); // delete so that we dont hang on to the json data. @@ -367,7 +382,7 @@ App.VertexSerializer = App.TimelineSerializer.extend({ }, }); -App.VertexInputSerializer = App.TimelineSerializer.extend({ +App.InputSerializer = App.TimelineSerializer.extend({ _map: { id: 'entity', inputName: 'name', @@ -405,6 +420,43 @@ App.VertexInputSerializer = App.TimelineSerializer.extend({ } }); +App.OutputSerializer = App.TimelineSerializer.extend({ + _map: { + id: 'entity', + outputName: 'name', + outputClass: 'class', + configs: 'configs' + }, + _normalizeData: function(data) { + var userPayload = JSON.parse(data.userPayloadAsText || null), + store = this.get('store'), + configs, + configKey, + configIndex = 0, + id; + + data.configs = []; + + if(userPayload) { + configs = userPayload.config || userPayload.dist; + for(configKey in configs) { + id = data.entity + configIndex++; + data.configs.push(id); + store.push('KVDatum', { + id: id, + key: configKey, + value: configs[configKey] + }); + } + } + + return data; + }, + normalize: function(type, hash, prop) { + return Em.JsonMapper.map(this._normalizeData(hash), this._map); + } +}); + var timelineJsonToAppDetailMap = { id: 'appId', attemptId: 'currentAppAttemptId', http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/scripts/models/dag.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/scripts/models/dag.js b/tez-ui/src/main/webapp/app/scripts/models/dag.js index e677478..c729712 100644 --- a/tez-ui/src/main/webapp/app/scripts/models/dag.js +++ b/tez-ui/src/main/webapp/app/scripts/models/dag.js @@ -221,7 +221,8 @@ App.Vertex = DS.Model.extend({ recordWriteCount: DS.attr('number'), - inputs: DS.hasMany('vertexInput'), + inputs: DS.hasMany('input'), + outputs: DS.hasMany('output'), totalReadBytes: function () { return this.get('fileReadBytes') + this.get('hdfsReadBytes'); @@ -244,7 +245,7 @@ App.Vertex = DS.Model.extend({ }.property('duration') }); -App.VertexInput = DS.Model.extend({ +App.Input = DS.Model.extend({ entity: DS.attr('string'), inputName: DS.attr('string'), @@ -254,6 +255,15 @@ App.VertexInput = DS.Model.extend({ configs: DS.hasMany('kVData', { async: false }) }); +App.Output = DS.Model.extend({ + entity: DS.attr('string'), + + outputName: DS.attr('string'), + outputClass: DS.attr('string'), + + configs: DS.hasMany('kVData', { async: false }) +}); + App.AppDetail = DS.Model.extend({ attemptId: DS.attr('string'), http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/scripts/router.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/scripts/router.js b/tez-ui/src/main/webapp/app/scripts/router.js index f33bcca..ddc8365 100644 --- a/tez-ui/src/main/webapp/app/scripts/router.js +++ b/tez-ui/src/main/webapp/app/scripts/router.js @@ -33,8 +33,11 @@ App.Router.map(function() { this.resource('vertex', {path: '/vertex/:vertex_id'}, function(){ this.route('tasks'); - this.route('inputs'); - this.resource('vertexInput', {path: '/input/:input_id'}, function(){ + this.route('additionals'); + this.resource('input', {path: '/input/:input_id'}, function(){ + this.route('configs'); + }); + this.resource('output', {path: '/output/:input_id'}, function(){ this.route('configs'); }); this.route('taskAttempts'); @@ -48,9 +51,11 @@ App.Router.map(function() { this.route('attempts'); this.route('counters'); }); + this.resource('taskAttempt', {path: '/task_attempt/:task_attempt_id'}, function() { this.route('counters'); }); + this.resource('error', {path: '/error'}); }); @@ -138,6 +143,10 @@ App.DagRoute = Em.Route.extend({ setupController: setupControllerFactory('Dag: %@ (%@)', 'name', 'id') }); +App.DagViewRoute = Em.Route.extend({ + setupController: setupControllerFactory() +}); + App.DagSwimlaneRoute = Em.Route.extend({ renderTemplate: renderSwimlanes, model: function(params) { @@ -177,25 +186,25 @@ App.VertexRoute = Em.Route.extend({ setupController: setupControllerFactory('Vertex: %@ (%@)', 'name', 'id') }); -App.VertexInputsRoute = Em.Route.extend({ +App.VertexAdditionalsRoute = Em.Route.extend({ setupController: function(controller, model) { this._super(controller, model); controller.loadEntities(); } }); -App.VertexInputConfigsRoute = Em.Route.extend({ - renderTemplate: renderConfigs, - setupController: function(controller, model) { - this._super(controller, model) - controller.set('needToShowInputDetails', true); - } +App.InputRoute = Em.Route.extend({ + model: function (params) { + var model = this.modelFor('vertex'); + return model.get('inputs').findBy('id', params.input_id); + }, + setupController: setupControllerFactory() }); -App.VertexInputRoute = Em.Route.extend({ +App.OutputRoute = Em.Route.extend({ model: function (params) { var model = this.modelFor('vertex'); - return model.get('inputs').findBy('id', params.input_id); + return model.get('outputs').findBy('id', params.input_id); }, setupController: setupControllerFactory() }); http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/styles/colors.less ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/styles/colors.less b/tez-ui/src/main/webapp/app/styles/colors.less new file mode 100644 index 0000000..b8e3b6e --- /dev/null +++ b/tez-ui/src/main/webapp/app/styles/colors.less @@ -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. + */ + +// Colors +@logo-orange: #D27A22; +@bg-lite: #f5f5f5; +@bg-liter: #f5f5f5; +@border-lite: #e5e5e5; +@bg-red-light: #FFE6E6; + +@white: #fff; + +@text-color: #666666; +@text-red: red; + +@top-nav-bg-color-from: #d5d5d5; +@top-nav-bg-color-to: #f0f0f0; + +@success-color: limegreen; +@error-color: crimson; +@warning-color: orange; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/styles/main.less ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/styles/main.less b/tez-ui/src/main/webapp/app/styles/main.less index 0f95485..57fa437 100644 --- a/tez-ui/src/main/webapp/app/styles/main.less +++ b/tez-ui/src/main/webapp/app/styles/main.less @@ -16,29 +16,14 @@ * limitations under the License. */ - -// Colors -@logo-orange: #D27A22; -@bg-lite: #f5f5f5; -@border-lite: #e5e5e5; -@bg-red-light: #FFE6E6; - -@white: #fff; - -@text-color: #666666; -@text-red: red; - -@top-nav-bg-color-from: #d5d5d5; -@top-nav-bg-color-to: #f0f0f0; - -@success-color: limegreen; -@error-color: crimson; -@warning-color: orange; - // Imports @import "../bower_components/font-awesome/less/font-awesome"; @import "../bower_components/bootstrap/less/bootstrap"; //UI theme +// Colors +@import "app/styles/colors"; +@import "app/styles/shared"; + // Base style body, html, body > .ember-view { height: 100%; @@ -205,11 +190,6 @@ body, html, body > .ember-view { } } -.fa-icon(@name) { - @content: "fa-var-@{name}"; - &:before {content: @@content} -} - /* misc helpers */ .inline-block { display: inline-block; @@ -441,4 +421,4 @@ div.indent { .align-close-button { margin-left: -1px; margin-top: -1px; -} \ No newline at end of file +} http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/styles/shared.less ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/styles/shared.less b/tez-ui/src/main/webapp/app/styles/shared.less new file mode 100644 index 0000000..341bb10 --- /dev/null +++ b/tez-ui/src/main/webapp/app/styles/shared.less @@ -0,0 +1,42 @@ +/** + * 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} +} + +.no-select { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + + cursor: default; +} + +.no-display { + display: none !important; +} + +.no-pointer { + pointer-events: none; +} + +.no-wrap { + white-space: nowrap; +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/templates/common/configs.hbs ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/templates/common/configs.hbs b/tez-ui/src/main/webapp/app/templates/common/configs.hbs index 8abf055..000a645 100644 --- a/tez-ui/src/main/webapp/app/templates/common/configs.hbs +++ b/tez-ui/src/main/webapp/app/templates/common/configs.hbs @@ -16,31 +16,4 @@ * limitations under the License. }} -{{#if needToShowInputDetails}} - <div class='align-left margin-small-horizontal' style="margin-bottom:10px;"> - <table class='detail-list'> - <thead> - <tr> - <th>Input Details</th> - </tr> - </thead> - <tbody> - <tr> - <td>Name</td> - <td>{{inputName}}</td> - </tr> - <tr> - <td>Class</td> - <td>{{inputClass}}</td> - </tr> - <tr> - <td>Initializer</td> - <td>{{inputInitializer}}</td> - </tr> - </tbody> - </table> - </div> -{{/if}} -<div class='table-container'> - {{kv-table-component data=configs}} -</div> +{{partial 'partials/configs'}} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/templates/input/configs.hbs ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/templates/input/configs.hbs b/tez-ui/src/main/webapp/app/templates/input/configs.hbs new file mode 100644 index 0000000..83c6ed9 --- /dev/null +++ b/tez-ui/src/main/webapp/app/templates/input/configs.hbs @@ -0,0 +1,42 @@ +{{! +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +}} + +<div class='margin-small-horizontal' style="margin-bottom:10px;"> + <table class='detail-list'> + <thead> + <tr> + <th>Source Details</th> + </tr> + </thead> + <tbody> + <tr> + <td>Name</td> + <td>{{inputName}}</td> + </tr> + <tr> + <td>Class</td> + <td>{{inputClass}}</td> + </tr> + <tr> + <td>Initializer</td> + <td>{{inputInitializer}}</td> + </tr> + </tbody> + </table> +</div> +{{partial 'partials/configs'}} http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/templates/output/configs.hbs ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/templates/output/configs.hbs b/tez-ui/src/main/webapp/app/templates/output/configs.hbs new file mode 100644 index 0000000..3c5dd59 --- /dev/null +++ b/tez-ui/src/main/webapp/app/templates/output/configs.hbs @@ -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. +}} + +<div class='margin-small-horizontal' style="margin-bottom:10px;"> + <table class='detail-list'> + <thead> + <tr> + <th>Sink Details</th> + </tr> + </thead> + <tbody> + <tr> + <td>Name</td> + <td>{{outputName}}</td> + </tr> + <tr> + <td>Class</td> + <td>{{outputClass}}</td> + </tr> + </tbody> + </table> +</div> +{{partial 'partials/configs'}} + http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/templates/partials/configs.hbs ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/templates/partials/configs.hbs b/tez-ui/src/main/webapp/app/templates/partials/configs.hbs new file mode 100644 index 0000000..a639352 --- /dev/null +++ b/tez-ui/src/main/webapp/app/templates/partials/configs.hbs @@ -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. +}} + +{{#if configs}} + <div class='table-container'> + {{kv-table-component data=configs}} + </div> +{{else}} + <div class='margin-small-horizontal'> + <h4>No configurations available!</h4> + </div> +{{/if}} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/templates/vertex/additionals.hbs ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/templates/vertex/additionals.hbs b/tez-ui/src/main/webapp/app/templates/vertex/additionals.hbs new file mode 100644 index 0000000..bb85eb3 --- /dev/null +++ b/tez-ui/src/main/webapp/app/templates/vertex/additionals.hbs @@ -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. +}} + +{{#unless loading}} + <h3>Sources</h3> + {{#if inputsAvailable}} + {{extended-table-component + hasFooter=false + columnsBinding="inputColumns" + contentBinding="inputContent" + forceFillColumns=true + }} + {{else}} + <h4>Not available!</h4> + {{/if}} + + <h3>Sinks</h3> + {{#if outputsAvailable}} + {{extended-table-component + hasFooter=false + columnsBinding="outputColumns" + contentBinding="outputContent" + forceFillColumns=true + }} + {{else}} + <h4>Not available!</h4> + {{/if}} +{{else}} + {{partial 'partials/loading-spinner'}} +{{/unless}} http://git-wip-us.apache.org/repos/asf/tez/blob/3a45508b/tez-ui/src/main/webapp/app/templates/vertex/inputs.hbs ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/templates/vertex/inputs.hbs b/tez-ui/src/main/webapp/app/templates/vertex/inputs.hbs deleted file mode 100644 index 972951d..0000000 --- a/tez-ui/src/main/webapp/app/templates/vertex/inputs.hbs +++ /dev/null @@ -1,36 +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. -}} - -{{#unless loading}} - {{#if inputsAvailable}} - <div class='margin-small align-children-right'> - {{page-nav-component - hasPrev=hasPrev - hasNext=hasNext - navNext='navigateNext' - navPrev='navigatePrev' - navFirst='navigateFirst' - }} - </div> - {{partial 'partials/table'}} - {{else}} - <h1>Inputs are not available!</h1> - {{/if}} -{{else}} - {{partial 'utils/loading-spinner'}} -{{/unless}}
